diff --git a/.axiom/semantic_index/index.json b/.axiom/semantic_index/index.json
index c2d8f1b2..94f7e45b 100644
--- a/.axiom/semantic_index/index.json
+++ b/.axiom/semantic_index/index.json
@@ -1,9 +1,9 @@
{
- "generated_at": "2026-05-26T06:29:57.952225530Z",
+ "generated_at": "2026-05-26T07:44:28.125947395Z",
"root_path": "/home/busya/dev/ss-tools",
- "contract_count": 3461,
+ "contract_count": 3195,
"edge_count": 2140,
- "file_count": 691,
+ "file_count": 690,
"contracts": [
{
"contract_id": "SrcRoot",
@@ -3810,14 +3810,14 @@
{
"source_id": "TestMigrationRoutes",
"relation_type": "BINDS_TO",
- "target_id": "EXT:path:backend.src.api.routes.migration",
- "target_ref": "[EXT:path:backend.src.api.routes.migration]"
+ "target_id": "MigrationApi",
+ "target_ref": "[MigrationApi]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TestMigrationRoutes [TYPE Module] [C:3] [SEMANTICS test, migration, api, route, handler]\n#\n# @BRIEF Unit tests for migration API route handlers.\n# @LAYER API\n# @RELATION BINDS_TO -> [EXT:path:backend.src.api.routes.migration]\n#\nfrom datetime import UTC, datetime\nfrom pathlib import Path\nimport pytest\nimport sys\nfrom unittest.mock import AsyncMock, MagicMock, patch\n\n# Add backend directory to sys.path\nbackend_dir = str(Path(__file__).parent.parent.parent.parent.resolve())\nif backend_dir not in sys.path:\n sys.path.insert(0, backend_dir)\nimport os\n\n# Force SQLite in-memory for all database connections BEFORE importing any application code\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"DATABASE_URL\"] = \"sqlite:///:memory:\"\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"TASKS_DATABASE_URL\"] = \"sqlite:///:memory:\"\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"AUTH_DATABASE_URL\"] = \"sqlite:///:memory:\"\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"ENVIRONMENT\"] = \"testing\"\nfrom fastapi import HTTPException\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom src.models.mapping import Base, ResourceMapping, ResourceType\n\n# Patch the get_db dependency if `src.api.routes.migration` imports it\npatch(\"src.core.database.get_db\").start()\n# --- Fixtures ---\n@pytest.fixture\ndef db_session():\n \"\"\"In-memory SQLite session for testing.\"\"\"\n from sqlalchemy.pool import StaticPool\n engine = create_engine(\n \"sqlite:///:memory:\",\n connect_args={\"check_same_thread\": False},\n poolclass=StaticPool,\n )\n Base.metadata.create_all(engine)\n Session = sessionmaker(bind=engine)\n session = Session()\n yield session\n session.close()\n# #region _make_config_manager [TYPE Function]\n# @RELATION BINDS_TO -> TestMigrationRoutes\ndef _make_config_manager(cron=\"0 2 * * *\"):\n \"\"\"Creates a mock config manager with a realistic AppConfig-like object.\"\"\"\n settings = MagicMock()\n settings.migration_sync_cron = cron\n config = MagicMock()\n config.settings = settings\n cm = MagicMock()\n cm.get_config.return_value = config\n cm.save_config = MagicMock()\n return cm\n# --- get_migration_settings tests ---\n# #endregion _make_config_manager\n@pytest.mark.asyncio\nasync def test_get_migration_settings_returns_default_cron():\n \"\"\"Verify the settings endpoint returns the stored cron string.\"\"\"\n from src.api.routes.migration import get_migration_settings\n cm = _make_config_manager(cron=\"0 3 * * *\")\n # Call the handler directly, bypassing Depends\n result = await get_migration_settings(config_manager=cm, _=None)\n assert result == {\"cron\": \"0 3 * * *\"}\n cm.get_config.assert_called_once()\n@pytest.mark.asyncio\nasync def test_get_migration_settings_returns_fallback_when_no_cron():\n \"\"\"When migration_sync_cron uses the default, should return '0 2 * * *'.\"\"\"\n from src.api.routes.migration import get_migration_settings\n # Use the default cron value (simulating a fresh config)\n cm = _make_config_manager()\n result = await get_migration_settings(config_manager=cm, _=None)\n assert result == {\"cron\": \"0 2 * * *\"}\n# --- update_migration_settings tests ---\n@pytest.mark.asyncio\nasync def test_update_migration_settings_saves_cron():\n \"\"\"Verify that a valid cron update saves to config.\"\"\"\n from src.api.routes.migration import update_migration_settings\n cm = _make_config_manager()\n result = await update_migration_settings(\n payload={\"cron\": \"0 4 * * *\"}, config_manager=cm, _=None\n )\n assert result[\"cron\"] == \"0 4 * * *\"\n assert result[\"status\"] == \"updated\"\n cm.save_config.assert_called_once()\n@pytest.mark.asyncio\nasync def test_update_migration_settings_rejects_missing_cron():\n \"\"\"Verify 400 error when 'cron' key is missing from payload.\"\"\"\n from src.api.routes.migration import update_migration_settings\n cm = _make_config_manager()\n with pytest.raises(HTTPException) as exc_info:\n await update_migration_settings(\n payload={\"interval\": \"daily\"}, config_manager=cm, _=None\n )\n assert exc_info.value.status_code == 400\n assert \"cron\" in exc_info.value.detail.lower()\n# --- get_resource_mappings tests ---\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_returns_formatted_list(db_session):\n \"\"\"Verify mappings are returned as formatted dicts with correct keys.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n # Populate test data\n m1 = ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"uuid-1\",\n remote_integer_id=\"42\",\n resource_name=\"Sales Chart\",\n last_synced_at=datetime(2026, 1, 15, 12, 0, 0, tzinfo=UTC),\n )\n db_session.add(m1)\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=None,\n env_id=None,\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert len(result[\"items\"]) == 1\n assert result[\"items\"][0][\"environment_id\"] == \"prod\"\n assert result[\"items\"][0][\"resource_type\"] == \"chart\"\n assert result[\"items\"][0][\"uuid\"] == \"uuid-1\"\n assert result[\"items\"][0][\"remote_id\"] == \"42\"\n assert result[\"items\"][0][\"resource_name\"] == \"Sales Chart\"\n assert result[\"items\"][0][\"last_synced_at\"] is not None\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_respects_pagination(db_session):\n \"\"\"Verify skip and limit parameters work correctly.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n for i in range(5):\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.DATASET,\n uuid=f\"uuid-{i}\",\n remote_integer_id=str(i),\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=2,\n limit=2,\n search=None,\n env_id=None,\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 5\n assert len(result[\"items\"]) == 2\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_search_by_name(db_session):\n \"\"\"Verify search filters by resource_name.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"u1\",\n remote_integer_id=\"1\",\n resource_name=\"Sales Chart\",\n )\n )\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"u2\",\n remote_integer_id=\"2\",\n resource_name=\"Revenue Dashboard\",\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=\"sales\",\n env_id=None,\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert result[\"items\"][0][\"resource_name\"] == \"Sales Chart\"\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_filter_by_env(db_session):\n \"\"\"Verify env_id filter returns only matching environment.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n db_session.add(\n ResourceMapping(\n environment_id=\"ss1\",\n resource_type=ResourceType.CHART,\n uuid=\"u1\",\n remote_integer_id=\"1\",\n resource_name=\"Chart A\",\n )\n )\n db_session.add(\n ResourceMapping(\n environment_id=\"ss2\",\n resource_type=ResourceType.CHART,\n uuid=\"u2\",\n remote_integer_id=\"2\",\n resource_name=\"Chart B\",\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=None,\n env_id=\"ss2\",\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert result[\"items\"][0][\"environment_id\"] == \"ss2\"\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_filter_by_type(db_session):\n \"\"\"Verify resource_type filter returns only matching type.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"u1\",\n remote_integer_id=\"1\",\n resource_name=\"My Chart\",\n )\n )\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.DATASET,\n uuid=\"u2\",\n remote_integer_id=\"2\",\n resource_name=\"My Dataset\",\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=None,\n env_id=None,\n resource_type=\"dataset\",\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert result[\"items\"][0][\"resource_type\"] == \"dataset\"\n# --- trigger_sync_now tests ---\n@pytest.fixture\n# #region _mock_env [TYPE Function]\n# @RELATION BINDS_TO -> TestMigrationRoutes\ndef _mock_env():\n \"\"\"Creates a mock config environment object.\"\"\"\n env = MagicMock()\n env.id = \"test-env-1\"\n env.name = \"Test Env\"\n env.url = \"http://superset.test\"\n env.username = \"admin\"\n env.password = \"admin\"\n env.verify_ssl = False\n env.timeout = 30\n return env\n# #endregion _mock_env\n# #region _make_sync_config_manager [TYPE Function]\n# @RELATION BINDS_TO -> TestMigrationRoutes\ndef _make_sync_config_manager(environments):\n \"\"\"Creates a mock config manager with environments list.\"\"\"\n settings = MagicMock()\n settings.migration_sync_cron = \"0 2 * * *\"\n config = MagicMock()\n config.settings = settings\n config.environments = environments\n cm = MagicMock()\n cm.get_config.return_value = config\n cm.get_environments.return_value = environments\n return cm\n# #endregion _make_sync_config_manager\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_creates_env_row_and_syncs(db_session, _mock_env):\n \"\"\"Verify that trigger_sync_now creates an Environment row in DB before syncing,\n preventing FK constraint violations on resource_mappings inserts.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n from src.models.mapping import Environment as EnvironmentModel\n cm = _make_sync_config_manager([_mock_env])\n with (\n patch(\"src.api.routes.migration.SupersetClient\") as MockClient,\n patch(\"src.api.routes.migration.IdMappingService\") as MockService,\n ):\n mock_client_instance = MagicMock()\n MockClient.return_value = mock_client_instance\n mock_service_instance = MagicMock()\n MockService.return_value = mock_service_instance\n result = await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n # Environment row must exist in DB\n env_row = db_session.query(EnvironmentModel).filter_by(id=\"test-env-1\").first()\n assert env_row is not None\n assert env_row.name == \"Test Env\"\n assert env_row.url == \"http://superset.test\"\n # Sync must have been called\n mock_service_instance.sync_environment.assert_called_once_with(\n \"test-env-1\", mock_client_instance\n )\n assert result[\"synced_count\"] == 1\n assert result[\"failed_count\"] == 0\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_rejects_empty_environments(db_session):\n \"\"\"Verify 400 error when no environments are configured.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n cm = _make_sync_config_manager([])\n with pytest.raises(HTTPException) as exc_info:\n await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n assert exc_info.value.status_code == 400\n assert \"No environments\" in exc_info.value.detail\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_handles_partial_failure(db_session, _mock_env):\n \"\"\"Verify that if sync_environment raises for one env, it's captured in failed list.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n env2 = MagicMock()\n env2.id = \"test-env-2\"\n env2.name = \"Failing Env\"\n env2.url = \"http://fail.test\"\n env2.username = \"admin\"\n env2.password = \"admin\"\n env2.verify_ssl = False\n env2.timeout = 30\n cm = _make_sync_config_manager([_mock_env, env2])\n with (\n patch(\"src.api.routes.migration.SupersetClient\") as MockClient,\n patch(\"src.api.routes.migration.IdMappingService\") as MockService,\n ):\n mock_service_instance = MagicMock()\n mock_service_instance.sync_environment.side_effect = [\n None,\n RuntimeError(\"Connection refused\"),\n ]\n MockService.return_value = mock_service_instance\n MockClient.return_value = MagicMock()\n result = await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n assert result[\"synced_count\"] == 1\n assert result[\"failed_count\"] == 1\n assert result[\"details\"][\"failed\"][0][\"env_id\"] == \"test-env-2\"\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_idempotent_env_upsert(db_session, _mock_env):\n \"\"\"Verify that calling sync twice doesn't duplicate the Environment row.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n from src.models.mapping import Environment as EnvironmentModel\n cm = _make_sync_config_manager([_mock_env])\n with (\n patch(\"src.api.routes.migration.SupersetClient\"),\n patch(\"src.api.routes.migration.IdMappingService\"),\n ):\n await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n env_count = db_session.query(EnvironmentModel).filter_by(id=\"test-env-1\").count()\n assert env_count == 1\n# --- get_dashboards tests ---\n@pytest.mark.asyncio\nasync def test_get_dashboards_success(_mock_env):\n from src.api.routes.migration import get_dashboards\n cm = _make_sync_config_manager([_mock_env])\n with patch(\"src.api.routes.migration.SupersetClient\") as MockClient:\n mock_client = MagicMock()\n mock_client.get_dashboards_summary.return_value = [{\"id\": 1, \"title\": \"Test\"}]\n MockClient.return_value = mock_client\n result = await get_dashboards(env_id=\"test-env-1\", config_manager=cm, _=None)\n assert len(result) == 1\n assert result[0][\"id\"] == 1\n@pytest.mark.asyncio\nasync def test_get_dashboards_invalid_env_raises_404(_mock_env):\n from src.api.routes.migration import get_dashboards\n cm = _make_sync_config_manager([_mock_env])\n with pytest.raises(HTTPException) as exc:\n await get_dashboards(env_id=\"wrong-env\", config_manager=cm, _=None)\n assert exc.value.status_code == 404\n# --- execute_migration tests ---\n@pytest.mark.asyncio\nasync def test_execute_migration_success(_mock_env):\n from src.api.routes.migration import execute_migration\n from src.models.dashboard import DashboardSelection\n cm = _make_sync_config_manager([_mock_env, _mock_env]) # Need both source/target\n tm = MagicMock()\n tm.create_task = AsyncMock(return_value=MagicMock(id=\"task-123\"))\n selection = DashboardSelection(\n source_env_id=\"test-env-1\", target_env_id=\"test-env-1\", selected_ids=[1, 2]\n )\n result = await execute_migration(\n selection=selection, config_manager=cm, task_manager=tm, _=None\n )\n assert result[\"task_id\"] == \"task-123\"\n tm.create_task.assert_called_once()\n@pytest.mark.asyncio\nasync def test_execute_migration_invalid_env_raises_400(_mock_env):\n from src.api.routes.migration import execute_migration\n from src.models.dashboard import DashboardSelection\n cm = _make_sync_config_manager([_mock_env])\n selection = DashboardSelection(\n source_env_id=\"test-env-1\", target_env_id=\"non-existent\", selected_ids=[1]\n )\n with pytest.raises(HTTPException) as exc:\n await execute_migration(\n selection=selection, config_manager=cm, task_manager=MagicMock(), _=None\n )\n assert exc.value.status_code == 400\n@pytest.mark.asyncio\nasync def test_dry_run_migration_returns_diff_and_risk(db_session):\n # @TEST_EDGE missing_target_datasource -> validates high risk item generation\n # @TEST_EDGE breaking_reference -> validates high risk on missing dataset link\n from src.api.routes.migration import dry_run_migration\n from src.models.dashboard import DashboardSelection\n env_source = MagicMock()\n env_source.id = \"src\"\n env_source.name = \"Source\"\n env_source.url = \"http://source\"\n env_source.username = \"admin\"\n env_source.password = \"admin\"\n env_source.verify_ssl = False\n env_source.timeout = 30\n env_target = MagicMock()\n env_target.id = \"tgt\"\n env_target.name = \"Target\"\n env_target.url = \"http://target\"\n env_target.username = \"admin\"\n env_target.password = \"admin\"\n env_target.verify_ssl = False\n env_target.timeout = 30\n cm = _make_sync_config_manager([env_source, env_target])\n selection = DashboardSelection(\n selected_ids=[42],\n source_env_id=\"src\",\n target_env_id=\"tgt\",\n replace_db_config=False,\n fix_cross_filters=True,\n )\n with (\n patch(\"src.api.routes.migration.SupersetClient\") as MockClient,\n patch(\"src.api.routes.migration.MigrationDryRunService\") as MockService,\n ):\n source_client = MagicMock()\n target_client = MagicMock()\n MockClient.side_effect = [source_client, target_client]\n service_instance = MagicMock()\n service_payload = {\n \"generated_at\": \"2026-02-27T00:00:00+00:00\",\n \"selection\": selection.model_dump(),\n \"selected_dashboard_titles\": [\"Sales\"],\n \"diff\": {\n \"dashboards\": {\n \"create\": [],\n \"update\": [{\"uuid\": \"dash-1\"}],\n \"delete\": [],\n },\n \"charts\": {\"create\": [{\"uuid\": \"chart-1\"}], \"update\": [], \"delete\": []},\n \"datasets\": {\n \"create\": [{\"uuid\": \"dataset-1\"}],\n \"update\": [],\n \"delete\": [],\n },\n },\n \"summary\": {\n \"dashboards\": {\"create\": 0, \"update\": 1, \"delete\": 0},\n \"charts\": {\"create\": 1, \"update\": 0, \"delete\": 0},\n \"datasets\": {\"create\": 1, \"update\": 0, \"delete\": 0},\n \"selected_dashboards\": 1,\n },\n \"risk\": {\n \"score\": 75,\n \"level\": \"high\",\n \"items\": [\n {\"code\": \"missing_datasource\"},\n {\"code\": \"breaking_reference\"},\n ],\n },\n }\n service_instance.run.return_value = service_payload\n MockService.return_value = service_instance\n result = await dry_run_migration(\n selection=selection, config_manager=cm, db=db_session, _=None\n )\n assert result[\"summary\"][\"dashboards\"][\"update\"] == 1\n assert result[\"summary\"][\"charts\"][\"create\"] == 1\n assert result[\"summary\"][\"datasets\"][\"create\"] == 1\n assert result[\"risk\"][\"score\"] > 0\n assert any(item[\"code\"] == \"missing_datasource\" for item in result[\"risk\"][\"items\"])\n assert any(item[\"code\"] == \"breaking_reference\" for item in result[\"risk\"][\"items\"])\n@pytest.mark.asyncio\nasync def test_dry_run_migration_rejects_same_environment(db_session):\n from src.api.routes.migration import dry_run_migration\n from src.models.dashboard import DashboardSelection\n env = MagicMock()\n env.id = \"same\"\n env.name = \"Same\"\n env.url = \"http://same\"\n env.username = \"admin\"\n env.password = \"admin\"\n env.verify_ssl = False\n env.timeout = 30\n cm = _make_sync_config_manager([env])\n selection = DashboardSelection(\n selected_ids=[1], source_env_id=\"same\", target_env_id=\"same\"\n )\n with pytest.raises(HTTPException) as exc:\n await dry_run_migration(\n selection=selection, config_manager=cm, db=db_session, _=None\n )\n assert exc.value.status_code == 400\n# #endregion TestMigrationRoutes\n"
+ "body": "# #region TestMigrationRoutes [TYPE Module] [C:3] [SEMANTICS test, migration, api, route, handler]\n#\n# @BRIEF Unit tests for migration API route handlers.\n# @LAYER API\n# @RELATION BINDS_TO -> [MigrationApi]\n#\nfrom datetime import UTC, datetime\nfrom pathlib import Path\nimport pytest\nimport sys\nfrom unittest.mock import AsyncMock, MagicMock, patch\n\n# Add backend directory to sys.path\nbackend_dir = str(Path(__file__).parent.parent.parent.parent.resolve())\nif backend_dir not in sys.path:\n sys.path.insert(0, backend_dir)\nimport os\n\n# Force SQLite in-memory for all database connections BEFORE importing any application code\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"DATABASE_URL\"] = \"sqlite:///:memory:\"\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"TASKS_DATABASE_URL\"] = \"sqlite:///:memory:\"\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"AUTH_DATABASE_URL\"] = \"sqlite:///:memory:\"\n# @SIDE_EFFECT_WARNING: os.environ mutation at module import time — no teardown. This bleeds into all subsequently collected tests. Migrate to pytest.fixture(autouse=True) with monkeypatch.setenv.\nos.environ[\"ENVIRONMENT\"] = \"testing\"\nfrom fastapi import HTTPException\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom src.models.mapping import Base, ResourceMapping, ResourceType\n\n# Patch the get_db dependency if `src.api.routes.migration` imports it\npatch(\"src.core.database.get_db\").start()\n# --- Fixtures ---\n@pytest.fixture\ndef db_session():\n \"\"\"In-memory SQLite session for testing.\"\"\"\n from sqlalchemy.pool import StaticPool\n engine = create_engine(\n \"sqlite:///:memory:\",\n connect_args={\"check_same_thread\": False},\n poolclass=StaticPool,\n )\n Base.metadata.create_all(engine)\n Session = sessionmaker(bind=engine)\n session = Session()\n yield session\n session.close()\n# #region _make_config_manager [TYPE Function]\n# @RELATION BINDS_TO -> TestMigrationRoutes\ndef _make_config_manager(cron=\"0 2 * * *\"):\n \"\"\"Creates a mock config manager with a realistic AppConfig-like object.\"\"\"\n settings = MagicMock()\n settings.migration_sync_cron = cron\n config = MagicMock()\n config.settings = settings\n cm = MagicMock()\n cm.get_config.return_value = config\n cm.save_config = MagicMock()\n return cm\n# --- get_migration_settings tests ---\n# #endregion _make_config_manager\n@pytest.mark.asyncio\nasync def test_get_migration_settings_returns_default_cron():\n \"\"\"Verify the settings endpoint returns the stored cron string.\"\"\"\n from src.api.routes.migration import get_migration_settings\n cm = _make_config_manager(cron=\"0 3 * * *\")\n # Call the handler directly, bypassing Depends\n result = await get_migration_settings(config_manager=cm, _=None)\n assert result == {\"cron\": \"0 3 * * *\"}\n cm.get_config.assert_called_once()\n@pytest.mark.asyncio\nasync def test_get_migration_settings_returns_fallback_when_no_cron():\n \"\"\"When migration_sync_cron uses the default, should return '0 2 * * *'.\"\"\"\n from src.api.routes.migration import get_migration_settings\n # Use the default cron value (simulating a fresh config)\n cm = _make_config_manager()\n result = await get_migration_settings(config_manager=cm, _=None)\n assert result == {\"cron\": \"0 2 * * *\"}\n# --- update_migration_settings tests ---\n@pytest.mark.asyncio\nasync def test_update_migration_settings_saves_cron():\n \"\"\"Verify that a valid cron update saves to config.\"\"\"\n from src.api.routes.migration import update_migration_settings\n cm = _make_config_manager()\n result = await update_migration_settings(\n payload={\"cron\": \"0 4 * * *\"}, config_manager=cm, _=None\n )\n assert result[\"cron\"] == \"0 4 * * *\"\n assert result[\"status\"] == \"updated\"\n cm.save_config.assert_called_once()\n@pytest.mark.asyncio\nasync def test_update_migration_settings_rejects_missing_cron():\n \"\"\"Verify 400 error when 'cron' key is missing from payload.\"\"\"\n from src.api.routes.migration import update_migration_settings\n cm = _make_config_manager()\n with pytest.raises(HTTPException) as exc_info:\n await update_migration_settings(\n payload={\"interval\": \"daily\"}, config_manager=cm, _=None\n )\n assert exc_info.value.status_code == 400\n assert \"cron\" in exc_info.value.detail.lower()\n# --- get_resource_mappings tests ---\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_returns_formatted_list(db_session):\n \"\"\"Verify mappings are returned as formatted dicts with correct keys.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n # Populate test data\n m1 = ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"uuid-1\",\n remote_integer_id=\"42\",\n resource_name=\"Sales Chart\",\n last_synced_at=datetime(2026, 1, 15, 12, 0, 0, tzinfo=UTC),\n )\n db_session.add(m1)\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=None,\n env_id=None,\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert len(result[\"items\"]) == 1\n assert result[\"items\"][0][\"environment_id\"] == \"prod\"\n assert result[\"items\"][0][\"resource_type\"] == \"chart\"\n assert result[\"items\"][0][\"uuid\"] == \"uuid-1\"\n assert result[\"items\"][0][\"remote_id\"] == \"42\"\n assert result[\"items\"][0][\"resource_name\"] == \"Sales Chart\"\n assert result[\"items\"][0][\"last_synced_at\"] is not None\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_respects_pagination(db_session):\n \"\"\"Verify skip and limit parameters work correctly.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n for i in range(5):\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.DATASET,\n uuid=f\"uuid-{i}\",\n remote_integer_id=str(i),\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=2,\n limit=2,\n search=None,\n env_id=None,\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 5\n assert len(result[\"items\"]) == 2\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_search_by_name(db_session):\n \"\"\"Verify search filters by resource_name.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"u1\",\n remote_integer_id=\"1\",\n resource_name=\"Sales Chart\",\n )\n )\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"u2\",\n remote_integer_id=\"2\",\n resource_name=\"Revenue Dashboard\",\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=\"sales\",\n env_id=None,\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert result[\"items\"][0][\"resource_name\"] == \"Sales Chart\"\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_filter_by_env(db_session):\n \"\"\"Verify env_id filter returns only matching environment.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n db_session.add(\n ResourceMapping(\n environment_id=\"ss1\",\n resource_type=ResourceType.CHART,\n uuid=\"u1\",\n remote_integer_id=\"1\",\n resource_name=\"Chart A\",\n )\n )\n db_session.add(\n ResourceMapping(\n environment_id=\"ss2\",\n resource_type=ResourceType.CHART,\n uuid=\"u2\",\n remote_integer_id=\"2\",\n resource_name=\"Chart B\",\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=None,\n env_id=\"ss2\",\n resource_type=None,\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert result[\"items\"][0][\"environment_id\"] == \"ss2\"\n@pytest.mark.asyncio\nasync def test_get_resource_mappings_filter_by_type(db_session):\n \"\"\"Verify resource_type filter returns only matching type.\"\"\"\n from src.api.routes.migration import get_resource_mappings\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.CHART,\n uuid=\"u1\",\n remote_integer_id=\"1\",\n resource_name=\"My Chart\",\n )\n )\n db_session.add(\n ResourceMapping(\n environment_id=\"prod\",\n resource_type=ResourceType.DATASET,\n uuid=\"u2\",\n remote_integer_id=\"2\",\n resource_name=\"My Dataset\",\n )\n )\n db_session.commit()\n result = await get_resource_mappings(\n skip=0,\n limit=50,\n search=None,\n env_id=None,\n resource_type=\"dataset\",\n db=db_session,\n _=None,\n )\n assert result[\"total\"] == 1\n assert result[\"items\"][0][\"resource_type\"] == \"dataset\"\n# --- trigger_sync_now tests ---\n@pytest.fixture\n# #region _mock_env [TYPE Function]\n# @RELATION BINDS_TO -> TestMigrationRoutes\ndef _mock_env():\n \"\"\"Creates a mock config environment object.\"\"\"\n env = MagicMock()\n env.id = \"test-env-1\"\n env.name = \"Test Env\"\n env.url = \"http://superset.test\"\n env.username = \"admin\"\n env.password = \"admin\"\n env.verify_ssl = False\n env.timeout = 30\n return env\n# #endregion _mock_env\n# #region _make_sync_config_manager [TYPE Function]\n# @RELATION BINDS_TO -> TestMigrationRoutes\ndef _make_sync_config_manager(environments):\n \"\"\"Creates a mock config manager with environments list.\"\"\"\n settings = MagicMock()\n settings.migration_sync_cron = \"0 2 * * *\"\n config = MagicMock()\n config.settings = settings\n config.environments = environments\n cm = MagicMock()\n cm.get_config.return_value = config\n cm.get_environments.return_value = environments\n return cm\n# #endregion _make_sync_config_manager\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_creates_env_row_and_syncs(db_session, _mock_env):\n \"\"\"Verify that trigger_sync_now creates an Environment row in DB before syncing,\n preventing FK constraint violations on resource_mappings inserts.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n from src.models.mapping import Environment as EnvironmentModel\n cm = _make_sync_config_manager([_mock_env])\n with (\n patch(\"src.api.routes.migration.SupersetClient\") as MockClient,\n patch(\"src.api.routes.migration.IdMappingService\") as MockService,\n ):\n mock_client_instance = MagicMock()\n MockClient.return_value = mock_client_instance\n mock_service_instance = MagicMock()\n MockService.return_value = mock_service_instance\n result = await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n # Environment row must exist in DB\n env_row = db_session.query(EnvironmentModel).filter_by(id=\"test-env-1\").first()\n assert env_row is not None\n assert env_row.name == \"Test Env\"\n assert env_row.url == \"http://superset.test\"\n # Sync must have been called\n mock_service_instance.sync_environment.assert_called_once_with(\n \"test-env-1\", mock_client_instance\n )\n assert result[\"synced_count\"] == 1\n assert result[\"failed_count\"] == 0\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_rejects_empty_environments(db_session):\n \"\"\"Verify 400 error when no environments are configured.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n cm = _make_sync_config_manager([])\n with pytest.raises(HTTPException) as exc_info:\n await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n assert exc_info.value.status_code == 400\n assert \"No environments\" in exc_info.value.detail\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_handles_partial_failure(db_session, _mock_env):\n \"\"\"Verify that if sync_environment raises for one env, it's captured in failed list.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n env2 = MagicMock()\n env2.id = \"test-env-2\"\n env2.name = \"Failing Env\"\n env2.url = \"http://fail.test\"\n env2.username = \"admin\"\n env2.password = \"admin\"\n env2.verify_ssl = False\n env2.timeout = 30\n cm = _make_sync_config_manager([_mock_env, env2])\n with (\n patch(\"src.api.routes.migration.SupersetClient\") as MockClient,\n patch(\"src.api.routes.migration.IdMappingService\") as MockService,\n ):\n mock_service_instance = MagicMock()\n mock_service_instance.sync_environment.side_effect = [\n None,\n RuntimeError(\"Connection refused\"),\n ]\n MockService.return_value = mock_service_instance\n MockClient.return_value = MagicMock()\n result = await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n assert result[\"synced_count\"] == 1\n assert result[\"failed_count\"] == 1\n assert result[\"details\"][\"failed\"][0][\"env_id\"] == \"test-env-2\"\n@pytest.mark.asyncio\nasync def test_trigger_sync_now_idempotent_env_upsert(db_session, _mock_env):\n \"\"\"Verify that calling sync twice doesn't duplicate the Environment row.\"\"\"\n from src.api.routes.migration import trigger_sync_now\n from src.models.mapping import Environment as EnvironmentModel\n cm = _make_sync_config_manager([_mock_env])\n with (\n patch(\"src.api.routes.migration.SupersetClient\"),\n patch(\"src.api.routes.migration.IdMappingService\"),\n ):\n await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n await trigger_sync_now(config_manager=cm, db=db_session, _=None)\n env_count = db_session.query(EnvironmentModel).filter_by(id=\"test-env-1\").count()\n assert env_count == 1\n# --- get_dashboards tests ---\n@pytest.mark.asyncio\nasync def test_get_dashboards_success(_mock_env):\n from src.api.routes.migration import get_dashboards\n cm = _make_sync_config_manager([_mock_env])\n with patch(\"src.api.routes.migration.SupersetClient\") as MockClient:\n mock_client = MagicMock()\n mock_client.get_dashboards_summary.return_value = [{\"id\": 1, \"title\": \"Test\"}]\n MockClient.return_value = mock_client\n result = await get_dashboards(env_id=\"test-env-1\", config_manager=cm, _=None)\n assert len(result) == 1\n assert result[0][\"id\"] == 1\n@pytest.mark.asyncio\nasync def test_get_dashboards_invalid_env_raises_404(_mock_env):\n from src.api.routes.migration import get_dashboards\n cm = _make_sync_config_manager([_mock_env])\n with pytest.raises(HTTPException) as exc:\n await get_dashboards(env_id=\"wrong-env\", config_manager=cm, _=None)\n assert exc.value.status_code == 404\n# --- execute_migration tests ---\n@pytest.mark.asyncio\nasync def test_execute_migration_success(_mock_env):\n from src.api.routes.migration import execute_migration\n from src.models.dashboard import DashboardSelection\n cm = _make_sync_config_manager([_mock_env, _mock_env]) # Need both source/target\n tm = MagicMock()\n tm.create_task = AsyncMock(return_value=MagicMock(id=\"task-123\"))\n selection = DashboardSelection(\n source_env_id=\"test-env-1\", target_env_id=\"test-env-1\", selected_ids=[1, 2]\n )\n result = await execute_migration(\n selection=selection, config_manager=cm, task_manager=tm, _=None\n )\n assert result[\"task_id\"] == \"task-123\"\n tm.create_task.assert_called_once()\n@pytest.mark.asyncio\nasync def test_execute_migration_invalid_env_raises_400(_mock_env):\n from src.api.routes.migration import execute_migration\n from src.models.dashboard import DashboardSelection\n cm = _make_sync_config_manager([_mock_env])\n selection = DashboardSelection(\n source_env_id=\"test-env-1\", target_env_id=\"non-existent\", selected_ids=[1]\n )\n with pytest.raises(HTTPException) as exc:\n await execute_migration(\n selection=selection, config_manager=cm, task_manager=MagicMock(), _=None\n )\n assert exc.value.status_code == 400\n@pytest.mark.asyncio\nasync def test_dry_run_migration_returns_diff_and_risk(db_session):\n # @TEST_EDGE missing_target_datasource -> validates high risk item generation\n # @TEST_EDGE breaking_reference -> validates high risk on missing dataset link\n from src.api.routes.migration import dry_run_migration\n from src.models.dashboard import DashboardSelection\n env_source = MagicMock()\n env_source.id = \"src\"\n env_source.name = \"Source\"\n env_source.url = \"http://source\"\n env_source.username = \"admin\"\n env_source.password = \"admin\"\n env_source.verify_ssl = False\n env_source.timeout = 30\n env_target = MagicMock()\n env_target.id = \"tgt\"\n env_target.name = \"Target\"\n env_target.url = \"http://target\"\n env_target.username = \"admin\"\n env_target.password = \"admin\"\n env_target.verify_ssl = False\n env_target.timeout = 30\n cm = _make_sync_config_manager([env_source, env_target])\n selection = DashboardSelection(\n selected_ids=[42],\n source_env_id=\"src\",\n target_env_id=\"tgt\",\n replace_db_config=False,\n fix_cross_filters=True,\n )\n with (\n patch(\"src.api.routes.migration.SupersetClient\") as MockClient,\n patch(\"src.api.routes.migration.MigrationDryRunService\") as MockService,\n ):\n source_client = MagicMock()\n target_client = MagicMock()\n MockClient.side_effect = [source_client, target_client]\n service_instance = MagicMock()\n service_payload = {\n \"generated_at\": \"2026-02-27T00:00:00+00:00\",\n \"selection\": selection.model_dump(),\n \"selected_dashboard_titles\": [\"Sales\"],\n \"diff\": {\n \"dashboards\": {\n \"create\": [],\n \"update\": [{\"uuid\": \"dash-1\"}],\n \"delete\": [],\n },\n \"charts\": {\"create\": [{\"uuid\": \"chart-1\"}], \"update\": [], \"delete\": []},\n \"datasets\": {\n \"create\": [{\"uuid\": \"dataset-1\"}],\n \"update\": [],\n \"delete\": [],\n },\n },\n \"summary\": {\n \"dashboards\": {\"create\": 0, \"update\": 1, \"delete\": 0},\n \"charts\": {\"create\": 1, \"update\": 0, \"delete\": 0},\n \"datasets\": {\"create\": 1, \"update\": 0, \"delete\": 0},\n \"selected_dashboards\": 1,\n },\n \"risk\": {\n \"score\": 75,\n \"level\": \"high\",\n \"items\": [\n {\"code\": \"missing_datasource\"},\n {\"code\": \"breaking_reference\"},\n ],\n },\n }\n service_instance.run.return_value = service_payload\n MockService.return_value = service_instance\n result = await dry_run_migration(\n selection=selection, config_manager=cm, db=db_session, _=None\n )\n assert result[\"summary\"][\"dashboards\"][\"update\"] == 1\n assert result[\"summary\"][\"charts\"][\"create\"] == 1\n assert result[\"summary\"][\"datasets\"][\"create\"] == 1\n assert result[\"risk\"][\"score\"] > 0\n assert any(item[\"code\"] == \"missing_datasource\" for item in result[\"risk\"][\"items\"])\n assert any(item[\"code\"] == \"breaking_reference\" for item in result[\"risk\"][\"items\"])\n@pytest.mark.asyncio\nasync def test_dry_run_migration_rejects_same_environment(db_session):\n from src.api.routes.migration import dry_run_migration\n from src.models.dashboard import DashboardSelection\n env = MagicMock()\n env.id = \"same\"\n env.name = \"Same\"\n env.url = \"http://same\"\n env.username = \"admin\"\n env.password = \"admin\"\n env.verify_ssl = False\n env.timeout = 30\n cm = _make_sync_config_manager([env])\n selection = DashboardSelection(\n selected_ids=[1], source_env_id=\"same\", target_env_id=\"same\"\n )\n with pytest.raises(HTTPException) as exc:\n await dry_run_migration(\n selection=selection, config_manager=cm, db=db_session, _=None\n )\n assert exc.value.status_code == 400\n# #endregion TestMigrationRoutes\n"
},
{
"contract_id": "_mock_env",
@@ -4968,14 +4968,14 @@
{
"source_id": "AdminApiKeyRoutes",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:code:has_permission(\"admin:settings\", \"WRITE\")",
- "target_ref": "[EXT:code:has_permission(\"admin:settings\", \"WRITE\")]"
+ "target_id": "EXT:code:has_permission_admin_settings_WRITE",
+ "target_ref": "[EXT:code:has_permission_admin_settings_WRITE]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region AdminApiKeyRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, admin, api_key, crud]\n# @BRIEF Admin API endpoints for API key management — list, generate (one-time reveal), and revoke.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [APIKeyModel]\n# @RELATION DEPENDS_ON -> [APIKeyUtilities]\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"admin:settings\", \"WRITE\")]\n# @INVARIANT GET /api/admin/api-keys NEVER returns key_hash or raw_key.\n# @INVARIANT POST /api/admin/api-keys returns raw_key ONCE — never stored, never retrievable again.\n# @INVARIANT DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.\n\nfrom datetime import datetime\n\nfrom fastapi import APIRouter, Depends, HTTPException, status\nfrom pydantic import BaseModel, Field\nfrom sqlalchemy.orm import Session\n\nfrom ...core.auth.api_key import generate_api_key\nfrom ...core.database import get_db\nfrom ...dependencies import has_permission\nfrom ...models.api_key import APIKey\n\n# #region router [TYPE Variable]\n# @BRIEF APIRouter for admin API key management routes.\nrouter = APIRouter(prefix=\"/api/admin/api-keys\", tags=[\"admin\", \"api-keys\"])\n# #endregion router\n\n\n# ── Pydantic schemas ──────────────────────────────────────────\n\n# #region ApiKeyCreateRequest [C:1] [TYPE Class]\nclass ApiKeyCreateRequest(BaseModel):\n name: str = Field(..., min_length=1, max_length=255)\n environment_id: str | None = None\n permissions: list[str] = Field(..., min_length=1)\n expires_at: datetime | None = None\n# #endregion ApiKeyCreateRequest\n\n\n# #region ApiKeyCreateResponse [C:1] [TYPE Class]\nclass ApiKeyCreateResponse(BaseModel):\n id: str\n raw_key: str\n prefix: str\n name: str\n environment_id: str | None\n permissions: list[str]\n active: bool\n created_at: datetime\n expires_at: datetime | None\n# #endregion ApiKeyCreateResponse\n\n\n# #region ApiKeyListItem [C:1] [TYPE Class]\nclass ApiKeyListItem(BaseModel):\n id: str\n name: str\n prefix: str\n environment_id: str | None\n permissions: list[str]\n active: bool\n created_at: datetime\n expires_at: datetime | None\n last_used_at: datetime | None\n\n model_config = {\"from_attributes\": True}\n# #endregion ApiKeyListItem\n\n\n# #region ApiKeyRevokeResponse [C:1] [TYPE Class]\nclass ApiKeyRevokeResponse(BaseModel):\n id: str\n status: str\n# #endregion ApiKeyRevokeResponse\n\n\n# ── Routes ────────────────────────────────────────────────────\n\n# #region list_api_keys [C:2] [TYPE Function]\n# @BRIEF List all API keys — NEVER returns key_hash or raw_key.\n# @PRE Requires admin:settings WRITE permission.\n# @POST Returns list of ApiKeyListItem without sensitive fields.\n@router.get(\"/\", response_model=list[ApiKeyListItem])\nasync def list_api_keys(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n keys = db.query(APIKey).order_by(APIKey.created_at.desc()).all()\n return [\n ApiKeyListItem(\n id=k.id,\n name=k.name,\n prefix=k.prefix,\n environment_id=k.environment_id,\n permissions=list(k.permissions or []),\n active=k.active,\n created_at=k.created_at,\n expires_at=k.expires_at,\n last_used_at=k.last_used_at,\n )\n for k in keys\n ]\n# #endregion list_api_keys\n\n\n# #region create_api_key [C:3] [TYPE Function]\n# @BRIEF Generate a new API key — returns raw key ONCE, never stored or retrievable again.\n# @PRE Requires admin:settings WRITE permission. name is required, at least one permission.\n# @POST Creates APIKey row with SHA-256 hash. Returns raw key in response.\n# @SIDE_EFFECT Generates cryptographically random key, stores hash in DB.\n# @RELATION DEPENDS_ON -> [generate_api_key]\n@router.post(\"/\", response_model=ApiKeyCreateResponse, status_code=status.HTTP_201_CREATED)\nasync def create_api_key(\n request: ApiKeyCreateRequest,\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n # Validate\n if not request.name.strip():\n raise HTTPException(status_code=400, detail=\"Name is required\")\n if not request.permissions:\n raise HTTPException(status_code=400, detail=\"At least one permission is required\")\n\n # Generate key\n raw_key, prefix, key_hash = generate_api_key()\n\n # Store hash only\n api_key = APIKey(\n key_hash=key_hash,\n prefix=prefix,\n name=request.name.strip(),\n environment_id=request.environment_id,\n permissions=request.permissions,\n active=True,\n expires_at=request.expires_at,\n )\n db.add(api_key)\n db.commit()\n db.refresh(api_key)\n\n return ApiKeyCreateResponse(\n id=api_key.id,\n raw_key=raw_key,\n prefix=api_key.prefix,\n name=api_key.name,\n environment_id=api_key.environment_id,\n permissions=list(api_key.permissions or []),\n active=api_key.active,\n created_at=api_key.created_at,\n expires_at=api_key.expires_at,\n )\n# #endregion create_api_key\n\n\n# #region revoke_api_key [C:2] [TYPE Function]\n# @BRIEF Revoke an API key by setting active=False. Preserves row for audit.\n# @PRE Requires admin:settings WRITE permission.\n# @POST Sets active=False on the key. Returns 404 if already revoked or not found.\n@router.delete(\"/{key_id}\", response_model=ApiKeyRevokeResponse)\nasync def revoke_api_key(\n key_id: str,\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n api_key = db.query(APIKey).filter(APIKey.id == key_id).first()\n if not api_key:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"API key not found\",\n )\n if not api_key.active:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"API key is already revoked\",\n )\n\n api_key.active = False\n db.commit()\n\n return ApiKeyRevokeResponse(\n id=api_key.id,\n status=\"revoked\",\n )\n# #endregion revoke_api_key\n\n# #endregion AdminApiKeyRoutes\n"
+ "body": "# #region AdminApiKeyRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, admin, api_key, crud]\n# @BRIEF Admin API endpoints for API key management — list, generate (one-time reveal), and revoke.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [APIKeyModel]\n# @RELATION DEPENDS_ON -> [APIKeyUtilities]\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_admin_settings_WRITE]\n# @INVARIANT GET /api/admin/api-keys NEVER returns key_hash or raw_key.\n# @INVARIANT POST /api/admin/api-keys returns raw_key ONCE — never stored, never retrievable again.\n# @INVARIANT DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.\n\nfrom datetime import datetime\n\nfrom fastapi import APIRouter, Depends, HTTPException, status\nfrom pydantic import BaseModel, Field\nfrom sqlalchemy.orm import Session\n\nfrom ...core.auth.api_key import generate_api_key\nfrom ...core.database import get_db\nfrom ...dependencies import has_permission\nfrom ...models.api_key import APIKey\n\n# #region router [TYPE Variable]\n# @BRIEF APIRouter for admin API key management routes.\nrouter = APIRouter(prefix=\"/api/admin/api-keys\", tags=[\"admin\", \"api-keys\"])\n# #endregion router\n\n\n# ── Pydantic schemas ──────────────────────────────────────────\n\n# #region ApiKeyCreateRequest [C:1] [TYPE Class]\nclass ApiKeyCreateRequest(BaseModel):\n name: str = Field(..., min_length=1, max_length=255)\n environment_id: str | None = None\n permissions: list[str] = Field(..., min_length=1)\n expires_at: datetime | None = None\n# #endregion ApiKeyCreateRequest\n\n\n# #region ApiKeyCreateResponse [C:1] [TYPE Class]\nclass ApiKeyCreateResponse(BaseModel):\n id: str\n raw_key: str\n prefix: str\n name: str\n environment_id: str | None\n permissions: list[str]\n active: bool\n created_at: datetime\n expires_at: datetime | None\n# #endregion ApiKeyCreateResponse\n\n\n# #region ApiKeyListItem [C:1] [TYPE Class]\nclass ApiKeyListItem(BaseModel):\n id: str\n name: str\n prefix: str\n environment_id: str | None\n permissions: list[str]\n active: bool\n created_at: datetime\n expires_at: datetime | None\n last_used_at: datetime | None\n\n model_config = {\"from_attributes\": True}\n# #endregion ApiKeyListItem\n\n\n# #region ApiKeyRevokeResponse [C:1] [TYPE Class]\nclass ApiKeyRevokeResponse(BaseModel):\n id: str\n status: str\n# #endregion ApiKeyRevokeResponse\n\n\n# ── Routes ────────────────────────────────────────────────────\n\n# #region list_api_keys [C:2] [TYPE Function]\n# @BRIEF List all API keys — NEVER returns key_hash or raw_key.\n# @PRE Requires admin:settings WRITE permission.\n# @POST Returns list of ApiKeyListItem without sensitive fields.\n@router.get(\"/\", response_model=list[ApiKeyListItem])\nasync def list_api_keys(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n keys = db.query(APIKey).order_by(APIKey.created_at.desc()).all()\n return [\n ApiKeyListItem(\n id=k.id,\n name=k.name,\n prefix=k.prefix,\n environment_id=k.environment_id,\n permissions=list(k.permissions or []),\n active=k.active,\n created_at=k.created_at,\n expires_at=k.expires_at,\n last_used_at=k.last_used_at,\n )\n for k in keys\n ]\n# #endregion list_api_keys\n\n\n# #region create_api_key [C:3] [TYPE Function]\n# @BRIEF Generate a new API key — returns raw key ONCE, never stored or retrievable again.\n# @PRE Requires admin:settings WRITE permission. name is required, at least one permission.\n# @POST Creates APIKey row with SHA-256 hash. Returns raw key in response.\n# @SIDE_EFFECT Generates cryptographically random key, stores hash in DB.\n# @RELATION DEPENDS_ON -> [generate_api_key]\n@router.post(\"/\", response_model=ApiKeyCreateResponse, status_code=status.HTTP_201_CREATED)\nasync def create_api_key(\n request: ApiKeyCreateRequest,\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n # Validate\n if not request.name.strip():\n raise HTTPException(status_code=400, detail=\"Name is required\")\n if not request.permissions:\n raise HTTPException(status_code=400, detail=\"At least one permission is required\")\n\n # Generate key\n raw_key, prefix, key_hash = generate_api_key()\n\n # Store hash only\n api_key = APIKey(\n key_hash=key_hash,\n prefix=prefix,\n name=request.name.strip(),\n environment_id=request.environment_id,\n permissions=request.permissions,\n active=True,\n expires_at=request.expires_at,\n )\n db.add(api_key)\n db.commit()\n db.refresh(api_key)\n\n return ApiKeyCreateResponse(\n id=api_key.id,\n raw_key=raw_key,\n prefix=api_key.prefix,\n name=api_key.name,\n environment_id=api_key.environment_id,\n permissions=list(api_key.permissions or []),\n active=api_key.active,\n created_at=api_key.created_at,\n expires_at=api_key.expires_at,\n )\n# #endregion create_api_key\n\n\n# #region revoke_api_key [C:2] [TYPE Function]\n# @BRIEF Revoke an API key by setting active=False. Preserves row for audit.\n# @PRE Requires admin:settings WRITE permission.\n# @POST Sets active=False on the key. Returns 404 if already revoked or not found.\n@router.delete(\"/{key_id}\", response_model=ApiKeyRevokeResponse)\nasync def revoke_api_key(\n key_id: str,\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n api_key = db.query(APIKey).filter(APIKey.id == key_id).first()\n if not api_key:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"API key not found\",\n )\n if not api_key.active:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"API key is already revoked\",\n )\n\n api_key.active = False\n db.commit()\n\n return ApiKeyRevokeResponse(\n id=api_key.id,\n status=\"revoked\",\n )\n# #endregion revoke_api_key\n\n# #endregion AdminApiKeyRoutes\n"
},
{
"contract_id": "ApiKeyCreateRequest",
@@ -5711,7 +5711,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region AssistantHistory [C:2] [TYPE Module] [SEMANTICS assistant, history, audit, persistence, conversation]\n# @BRIEF Conversation history, audit trail, and confirmation persistence helpers for the assistant API.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [AssistantSchemas]\n# @INVARIANT Failed persistence attempts always rollback before returning.\n\nfrom __future__ import annotations\n\nfrom datetime import datetime, timedelta\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom src.core.logger import logger\nfrom src.models.assistant import (\n AssistantAuditRecord,\n AssistantConfirmationRecord,\n AssistantMessageRecord,\n)\n\nfrom ._schemas import (\n ASSISTANT_ARCHIVE_AFTER_DAYS,\n ASSISTANT_AUDIT,\n ASSISTANT_MESSAGE_TTL_DAYS,\n CONVERSATIONS,\n ConfirmationRecord,\n)\n\nlogger = logger\n\n\n# #region _append_history [C:2] [TYPE Function]\n# @BRIEF Append conversation message to in-memory history buffer.\n# @DATA_CONTRACT Input[user_id,conversation_id,role,text,state?,task_id?,confirmation_id?] -> Output[None]\n# @RELATION BINDS_TO -> [EXT:internal:CONVERSATIONS]\n# @SIDE_EFFECT Mutates in-memory CONVERSATIONS store for user conversation history.\n# @PRE user_id and conversation_id identify target conversation bucket.\n# @POST Message entry is appended to CONVERSATIONS key list.\n# @INVARIANT every appended entry includes generated message_id and created_at timestamp.\ndef _append_history(\n user_id: str,\n conversation_id: str,\n role: str,\n text: str,\n state: str | None = None,\n task_id: str | None = None,\n confirmation_id: str | None = None,\n):\n key = (user_id, conversation_id)\n if key not in CONVERSATIONS:\n CONVERSATIONS[key] = []\n CONVERSATIONS[key].append(\n {\n \"message_id\": str(uuid.uuid4()),\n \"conversation_id\": conversation_id,\n \"role\": role,\n \"text\": text,\n \"state\": state,\n \"task_id\": task_id,\n \"confirmation_id\": confirmation_id,\n \"created_at\": datetime.utcnow(),\n }\n )\n\n\n# #endregion _append_history\n\n\n# #region _persist_message [C:2] [TYPE Function]\n# @BRIEF Persist assistant/user message record to database.\n# @DATA_CONTRACT Input[Session,user_id,conversation_id,role,text,state?,task_id?,confirmation_id?,metadata?] -> Output[None]\n# @RELATION DEPENDS_ON -> [AssistantMessageRecord]\n# @SIDE_EFFECT Writes AssistantMessageRecord rows and commits or rollbacks the DB session.\n# @PRE db session is writable and message payload is serializable.\n# @POST Message row is committed or persistence failure is logged.\n# @INVARIANT failed persistence attempts always rollback before returning.\ndef _persist_message(\n db: Session,\n user_id: str,\n conversation_id: str,\n role: str,\n text: str,\n state: str | None = None,\n task_id: str | None = None,\n confirmation_id: str | None = None,\n metadata: dict[str, Any] | None = None,\n):\n try:\n row = AssistantMessageRecord(\n id=str(uuid.uuid4()),\n user_id=user_id,\n conversation_id=conversation_id,\n role=role,\n text=text,\n state=state,\n task_id=task_id,\n confirmation_id=confirmation_id,\n payload=metadata,\n )\n db.add(row)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.message][persist_failed] {exc}\")\n\n\n# #endregion _persist_message\n\n\n# #region _audit [C:2] [TYPE Function]\n# @BRIEF Append in-memory audit record for assistant decision trace.\n# @DATA_CONTRACT Input[user_id,payload:Dict[str,Any]] -> Output[None]\n# @RELATION BINDS_TO -> [EXT:internal:ASSISTANT_AUDIT]\n# @SIDE_EFFECT Mutates in-memory ASSISTANT_AUDIT store and emits structured log event.\n# @PRE payload describes decision/outcome fields.\n# @POST ASSISTANT_AUDIT list for user contains new timestamped entry.\n# @INVARIANT persisted in-memory audit entry always contains created_at in ISO format.\ndef _audit(user_id: str, payload: dict[str, Any]):\n if user_id not in ASSISTANT_AUDIT:\n ASSISTANT_AUDIT[user_id] = []\n ASSISTANT_AUDIT[user_id].append(\n {**payload, \"created_at\": datetime.utcnow().isoformat()}\n )\n logger.info(f\"[assistant.audit] {payload}\")\n\n\n# #endregion _audit\n\n\n# #region _persist_audit [C:2] [TYPE Function]\n# @BRIEF Persist structured assistant audit payload in database.\n# @PRE db session is writable and payload is JSON-serializable.\n# @POST Audit row is committed or failure is logged with rollback.\ndef _persist_audit(\n db: Session, user_id: str, payload: dict[str, Any], conversation_id: str | None\n):\n try:\n row = AssistantAuditRecord(\n id=str(uuid.uuid4()),\n user_id=user_id,\n conversation_id=conversation_id,\n decision=payload.get(\"decision\"),\n task_id=payload.get(\"task_id\"),\n message=payload.get(\"message\"),\n payload=payload,\n )\n db.add(row)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.audit][persist_failed] {exc}\")\n\n\n# #endregion _persist_audit\n\n\n# #region _persist_confirmation [C:2] [TYPE Function]\n# @BRIEF Persist confirmation token record to database.\n# @PRE record contains id/user/intent/dispatch/expiry fields.\n# @POST Confirmation row exists in persistent storage.\ndef _persist_confirmation(db: Session, record: ConfirmationRecord):\n try:\n row = AssistantConfirmationRecord(\n id=record.id,\n user_id=record.user_id,\n conversation_id=record.conversation_id,\n state=record.state,\n intent=record.intent,\n dispatch=record.dispatch,\n expires_at=record.expires_at,\n created_at=record.created_at,\n consumed_at=None,\n )\n db.merge(row)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.confirmation][persist_failed] {exc}\")\n\n\n# #endregion _persist_confirmation\n\n\n# #region _update_confirmation_state [C:2] [TYPE Function]\n# @BRIEF Update persistent confirmation token lifecycle state.\n# @PRE confirmation_id references existing row.\n# @POST State and consumed_at fields are updated when applicable.\ndef _update_confirmation_state(db: Session, confirmation_id: str, state: str):\n try:\n row = (\n db.query(AssistantConfirmationRecord)\n .filter(AssistantConfirmationRecord.id == confirmation_id)\n .first()\n )\n if not row:\n return\n row.state = state\n if state in {\"consumed\", \"expired\", \"cancelled\"}:\n row.consumed_at = datetime.utcnow()\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.confirmation][update_failed] {exc}\")\n\n\n# #endregion _update_confirmation_state\n\n\n# #region _load_confirmation_from_db [C:2] [TYPE Function]\n# @BRIEF Load confirmation token from database into in-memory model.\n# @PRE confirmation_id may or may not exist in storage.\n# @POST Returns ConfirmationRecord when found, otherwise None.\ndef _load_confirmation_from_db(\n db: Session, confirmation_id: str\n) -> ConfirmationRecord | None:\n row = (\n db.query(AssistantConfirmationRecord)\n .filter(AssistantConfirmationRecord.id == confirmation_id)\n .first()\n )\n if not row:\n return None\n return ConfirmationRecord(\n id=row.id,\n user_id=row.user_id,\n conversation_id=row.conversation_id,\n intent=row.intent or {},\n dispatch=row.dispatch or {},\n expires_at=row.expires_at,\n state=row.state,\n created_at=row.created_at,\n )\n\n\n# #endregion _load_confirmation_from_db\n\n\n# #region _ensure_conversation [C:2] [TYPE Function]\n# @BRIEF Resolve active conversation id in memory or create a new one.\n# @PRE user_id identifies current actor.\n# @POST Returns stable conversation id and updates USER_ACTIVE_CONVERSATION.\ndef _ensure_conversation(user_id: str, conversation_id: str | None) -> str:\n if conversation_id:\n from ._schemas import USER_ACTIVE_CONVERSATION\n USER_ACTIVE_CONVERSATION[user_id] = conversation_id\n return conversation_id\n\n from ._schemas import USER_ACTIVE_CONVERSATION\n active = USER_ACTIVE_CONVERSATION.get(user_id)\n if active:\n return active\n\n new_id = str(uuid.uuid4())\n USER_ACTIVE_CONVERSATION[user_id] = new_id\n return new_id\n\n\n# #endregion _ensure_conversation\n\n\n# #region _resolve_or_create_conversation [C:2] [TYPE Function]\n# @BRIEF Resolve active conversation using explicit id, memory cache, or persisted history.\n# @PRE user_id and db session are available.\n# @POST Returns conversation id and updates USER_ACTIVE_CONVERSATION cache.\ndef _resolve_or_create_conversation(\n user_id: str, conversation_id: str | None, db: Session\n) -> str:\n from ._schemas import USER_ACTIVE_CONVERSATION\n\n if conversation_id:\n USER_ACTIVE_CONVERSATION[user_id] = conversation_id\n return conversation_id\n\n active = USER_ACTIVE_CONVERSATION.get(user_id)\n if active:\n return active\n\n from sqlalchemy import desc\n\n last_message = (\n db.query(AssistantMessageRecord)\n .filter(AssistantMessageRecord.user_id == user_id)\n .order_by(desc(AssistantMessageRecord.created_at))\n .first()\n )\n if last_message:\n USER_ACTIVE_CONVERSATION[user_id] = last_message.conversation_id\n return last_message.conversation_id\n\n new_id = str(uuid.uuid4())\n USER_ACTIVE_CONVERSATION[user_id] = new_id\n return new_id\n\n\n# #endregion _resolve_or_create_conversation\n\n\n# #region _cleanup_history_ttl [C:2] [TYPE Function]\n# @BRIEF Enforce assistant message retention window by deleting expired rows and in-memory records.\n# @PRE db session is available and user_id references current actor scope.\n# @POST Messages older than ASSISTANT_MESSAGE_TTL_DAYS are removed from persistence and memory mirrors.\ndef _cleanup_history_ttl(db: Session, user_id: str):\n cutoff = datetime.utcnow() - timedelta(days=ASSISTANT_MESSAGE_TTL_DAYS)\n try:\n query = db.query(AssistantMessageRecord).filter(\n AssistantMessageRecord.user_id == user_id,\n AssistantMessageRecord.created_at < cutoff,\n )\n if hasattr(query, \"delete\"):\n query.delete(synchronize_session=False)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(\n f\"[assistant.history][ttl_cleanup_failed] user={user_id} error={exc}\"\n )\n\n stale_keys: list[tuple[str, str]] = []\n for key, items in CONVERSATIONS.items():\n if key[0] != user_id:\n continue\n kept = []\n for item in items:\n created_at = item.get(\"created_at\")\n if isinstance(created_at, datetime) and created_at < cutoff:\n continue\n kept.append(item)\n if kept:\n CONVERSATIONS[key] = kept\n else:\n stale_keys.append(key)\n for key in stale_keys:\n CONVERSATIONS.pop(key, None)\n\n\n# #endregion _cleanup_history_ttl\n\n\n# #region _is_conversation_archived [C:2] [TYPE Function]\n# @BRIEF Determine archived state for a conversation based on last update timestamp.\n# @PRE updated_at can be null for empty conversations.\n# @POST Returns True when conversation inactivity exceeds archive threshold.\ndef _is_conversation_archived(updated_at: datetime | None) -> bool:\n if not updated_at:\n return False\n cutoff = datetime.utcnow() - timedelta(days=ASSISTANT_ARCHIVE_AFTER_DAYS)\n return updated_at < cutoff\n\n\n# #endregion _is_conversation_archived\n\n\n# #region _coerce_query_bool [C:2] [TYPE Function]\n# @BRIEF Normalize bool-like query values for compatibility in direct handler invocations/tests.\n# @PRE value may be bool, string, or FastAPI Query metadata object.\n# @POST Returns deterministic boolean flag.\ndef _coerce_query_bool(value: Any) -> bool:\n if isinstance(value, bool):\n return value\n if isinstance(value, str):\n return value.strip().lower() in {\"1\", \"true\", \"yes\", \"on\"}\n return False\n\n\n# #endregion _coerce_query_bool\n\n\n# #endregion AssistantHistory\n"
+ "body": "# #region AssistantHistory [C:2] [TYPE Module] [SEMANTICS assistant, history, audit, persistence, conversation]\n# @BRIEF Conversation history, audit trail, and confirmation persistence helpers for the assistant API.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [AssistantSchemas]\n# @INVARIANT Failed persistence attempts always rollback before returning.\n\nfrom __future__ import annotations\n\nfrom datetime import datetime, timedelta\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom src.core.logger import logger\nfrom src.models.assistant import (\n AssistantAuditRecord,\n AssistantConfirmationRecord,\n AssistantMessageRecord,\n)\n\nfrom ._schemas import (\n ASSISTANT_ARCHIVE_AFTER_DAYS,\n ASSISTANT_AUDIT,\n ASSISTANT_MESSAGE_TTL_DAYS,\n CONVERSATIONS,\n ConfirmationRecord,\n)\n\nlogger = logger\n\n\n# #region _append_history [C:2] [TYPE Function]\n# @BRIEF Append conversation message to in-memory history buffer.\n# @DATA_CONTRACT Input[user_id,conversation_id,role,text,state?,task_id?,confirmation_id?] -> Output[None]\n# @RELATION BINDS_TO -> [CONVERSATIONS]\n# @SIDE_EFFECT Mutates in-memory CONVERSATIONS store for user conversation history.\n# @PRE user_id and conversation_id identify target conversation bucket.\n# @POST Message entry is appended to CONVERSATIONS key list.\n# @INVARIANT every appended entry includes generated message_id and created_at timestamp.\ndef _append_history(\n user_id: str,\n conversation_id: str,\n role: str,\n text: str,\n state: str | None = None,\n task_id: str | None = None,\n confirmation_id: str | None = None,\n):\n key = (user_id, conversation_id)\n if key not in CONVERSATIONS:\n CONVERSATIONS[key] = []\n CONVERSATIONS[key].append(\n {\n \"message_id\": str(uuid.uuid4()),\n \"conversation_id\": conversation_id,\n \"role\": role,\n \"text\": text,\n \"state\": state,\n \"task_id\": task_id,\n \"confirmation_id\": confirmation_id,\n \"created_at\": datetime.utcnow(),\n }\n )\n\n\n# #endregion _append_history\n\n\n# #region _persist_message [C:2] [TYPE Function]\n# @BRIEF Persist assistant/user message record to database.\n# @DATA_CONTRACT Input[Session,user_id,conversation_id,role,text,state?,task_id?,confirmation_id?,metadata?] -> Output[None]\n# @RELATION DEPENDS_ON -> [AssistantMessageRecord]\n# @SIDE_EFFECT Writes AssistantMessageRecord rows and commits or rollbacks the DB session.\n# @PRE db session is writable and message payload is serializable.\n# @POST Message row is committed or persistence failure is logged.\n# @INVARIANT failed persistence attempts always rollback before returning.\ndef _persist_message(\n db: Session,\n user_id: str,\n conversation_id: str,\n role: str,\n text: str,\n state: str | None = None,\n task_id: str | None = None,\n confirmation_id: str | None = None,\n metadata: dict[str, Any] | None = None,\n):\n try:\n row = AssistantMessageRecord(\n id=str(uuid.uuid4()),\n user_id=user_id,\n conversation_id=conversation_id,\n role=role,\n text=text,\n state=state,\n task_id=task_id,\n confirmation_id=confirmation_id,\n payload=metadata,\n )\n db.add(row)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.message][persist_failed] {exc}\")\n\n\n# #endregion _persist_message\n\n\n# #region _audit [C:2] [TYPE Function]\n# @BRIEF Append in-memory audit record for assistant decision trace.\n# @DATA_CONTRACT Input[user_id,payload:Dict[str,Any]] -> Output[None]\n# @RELATION BINDS_TO -> [ASSISTANT_AUDIT]\n# @SIDE_EFFECT Mutates in-memory ASSISTANT_AUDIT store and emits structured log event.\n# @PRE payload describes decision/outcome fields.\n# @POST ASSISTANT_AUDIT list for user contains new timestamped entry.\n# @INVARIANT persisted in-memory audit entry always contains created_at in ISO format.\ndef _audit(user_id: str, payload: dict[str, Any]):\n if user_id not in ASSISTANT_AUDIT:\n ASSISTANT_AUDIT[user_id] = []\n ASSISTANT_AUDIT[user_id].append(\n {**payload, \"created_at\": datetime.utcnow().isoformat()}\n )\n logger.info(f\"[assistant.audit] {payload}\")\n\n\n# #endregion _audit\n\n\n# #region _persist_audit [C:2] [TYPE Function]\n# @BRIEF Persist structured assistant audit payload in database.\n# @PRE db session is writable and payload is JSON-serializable.\n# @POST Audit row is committed or failure is logged with rollback.\ndef _persist_audit(\n db: Session, user_id: str, payload: dict[str, Any], conversation_id: str | None\n):\n try:\n row = AssistantAuditRecord(\n id=str(uuid.uuid4()),\n user_id=user_id,\n conversation_id=conversation_id,\n decision=payload.get(\"decision\"),\n task_id=payload.get(\"task_id\"),\n message=payload.get(\"message\"),\n payload=payload,\n )\n db.add(row)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.audit][persist_failed] {exc}\")\n\n\n# #endregion _persist_audit\n\n\n# #region _persist_confirmation [C:2] [TYPE Function]\n# @BRIEF Persist confirmation token record to database.\n# @PRE record contains id/user/intent/dispatch/expiry fields.\n# @POST Confirmation row exists in persistent storage.\ndef _persist_confirmation(db: Session, record: ConfirmationRecord):\n try:\n row = AssistantConfirmationRecord(\n id=record.id,\n user_id=record.user_id,\n conversation_id=record.conversation_id,\n state=record.state,\n intent=record.intent,\n dispatch=record.dispatch,\n expires_at=record.expires_at,\n created_at=record.created_at,\n consumed_at=None,\n )\n db.merge(row)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.confirmation][persist_failed] {exc}\")\n\n\n# #endregion _persist_confirmation\n\n\n# #region _update_confirmation_state [C:2] [TYPE Function]\n# @BRIEF Update persistent confirmation token lifecycle state.\n# @PRE confirmation_id references existing row.\n# @POST State and consumed_at fields are updated when applicable.\ndef _update_confirmation_state(db: Session, confirmation_id: str, state: str):\n try:\n row = (\n db.query(AssistantConfirmationRecord)\n .filter(AssistantConfirmationRecord.id == confirmation_id)\n .first()\n )\n if not row:\n return\n row.state = state\n if state in {\"consumed\", \"expired\", \"cancelled\"}:\n row.consumed_at = datetime.utcnow()\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(f\"[assistant.confirmation][update_failed] {exc}\")\n\n\n# #endregion _update_confirmation_state\n\n\n# #region _load_confirmation_from_db [C:2] [TYPE Function]\n# @BRIEF Load confirmation token from database into in-memory model.\n# @PRE confirmation_id may or may not exist in storage.\n# @POST Returns ConfirmationRecord when found, otherwise None.\ndef _load_confirmation_from_db(\n db: Session, confirmation_id: str\n) -> ConfirmationRecord | None:\n row = (\n db.query(AssistantConfirmationRecord)\n .filter(AssistantConfirmationRecord.id == confirmation_id)\n .first()\n )\n if not row:\n return None\n return ConfirmationRecord(\n id=row.id,\n user_id=row.user_id,\n conversation_id=row.conversation_id,\n intent=row.intent or {},\n dispatch=row.dispatch or {},\n expires_at=row.expires_at,\n state=row.state,\n created_at=row.created_at,\n )\n\n\n# #endregion _load_confirmation_from_db\n\n\n# #region _ensure_conversation [C:2] [TYPE Function]\n# @BRIEF Resolve active conversation id in memory or create a new one.\n# @PRE user_id identifies current actor.\n# @POST Returns stable conversation id and updates USER_ACTIVE_CONVERSATION.\ndef _ensure_conversation(user_id: str, conversation_id: str | None) -> str:\n if conversation_id:\n from ._schemas import USER_ACTIVE_CONVERSATION\n USER_ACTIVE_CONVERSATION[user_id] = conversation_id\n return conversation_id\n\n from ._schemas import USER_ACTIVE_CONVERSATION\n active = USER_ACTIVE_CONVERSATION.get(user_id)\n if active:\n return active\n\n new_id = str(uuid.uuid4())\n USER_ACTIVE_CONVERSATION[user_id] = new_id\n return new_id\n\n\n# #endregion _ensure_conversation\n\n\n# #region _resolve_or_create_conversation [C:2] [TYPE Function]\n# @BRIEF Resolve active conversation using explicit id, memory cache, or persisted history.\n# @PRE user_id and db session are available.\n# @POST Returns conversation id and updates USER_ACTIVE_CONVERSATION cache.\ndef _resolve_or_create_conversation(\n user_id: str, conversation_id: str | None, db: Session\n) -> str:\n from ._schemas import USER_ACTIVE_CONVERSATION\n\n if conversation_id:\n USER_ACTIVE_CONVERSATION[user_id] = conversation_id\n return conversation_id\n\n active = USER_ACTIVE_CONVERSATION.get(user_id)\n if active:\n return active\n\n from sqlalchemy import desc\n\n last_message = (\n db.query(AssistantMessageRecord)\n .filter(AssistantMessageRecord.user_id == user_id)\n .order_by(desc(AssistantMessageRecord.created_at))\n .first()\n )\n if last_message:\n USER_ACTIVE_CONVERSATION[user_id] = last_message.conversation_id\n return last_message.conversation_id\n\n new_id = str(uuid.uuid4())\n USER_ACTIVE_CONVERSATION[user_id] = new_id\n return new_id\n\n\n# #endregion _resolve_or_create_conversation\n\n\n# #region _cleanup_history_ttl [C:2] [TYPE Function]\n# @BRIEF Enforce assistant message retention window by deleting expired rows and in-memory records.\n# @PRE db session is available and user_id references current actor scope.\n# @POST Messages older than ASSISTANT_MESSAGE_TTL_DAYS are removed from persistence and memory mirrors.\ndef _cleanup_history_ttl(db: Session, user_id: str):\n cutoff = datetime.utcnow() - timedelta(days=ASSISTANT_MESSAGE_TTL_DAYS)\n try:\n query = db.query(AssistantMessageRecord).filter(\n AssistantMessageRecord.user_id == user_id,\n AssistantMessageRecord.created_at < cutoff,\n )\n if hasattr(query, \"delete\"):\n query.delete(synchronize_session=False)\n db.commit()\n except Exception as exc:\n db.rollback()\n logger.warning(\n f\"[assistant.history][ttl_cleanup_failed] user={user_id} error={exc}\"\n )\n\n stale_keys: list[tuple[str, str]] = []\n for key, items in CONVERSATIONS.items():\n if key[0] != user_id:\n continue\n kept = []\n for item in items:\n created_at = item.get(\"created_at\")\n if isinstance(created_at, datetime) and created_at < cutoff:\n continue\n kept.append(item)\n if kept:\n CONVERSATIONS[key] = kept\n else:\n stale_keys.append(key)\n for key in stale_keys:\n CONVERSATIONS.pop(key, None)\n\n\n# #endregion _cleanup_history_ttl\n\n\n# #region _is_conversation_archived [C:2] [TYPE Function]\n# @BRIEF Determine archived state for a conversation based on last update timestamp.\n# @PRE updated_at can be null for empty conversations.\n# @POST Returns True when conversation inactivity exceeds archive threshold.\ndef _is_conversation_archived(updated_at: datetime | None) -> bool:\n if not updated_at:\n return False\n cutoff = datetime.utcnow() - timedelta(days=ASSISTANT_ARCHIVE_AFTER_DAYS)\n return updated_at < cutoff\n\n\n# #endregion _is_conversation_archived\n\n\n# #region _coerce_query_bool [C:2] [TYPE Function]\n# @BRIEF Normalize bool-like query values for compatibility in direct handler invocations/tests.\n# @PRE value may be bool, string, or FastAPI Query metadata object.\n# @POST Returns deterministic boolean flag.\ndef _coerce_query_bool(value: Any) -> bool:\n if isinstance(value, bool):\n return value\n if isinstance(value, str):\n return value.strip().lower() in {\"1\", \"true\", \"yes\", \"on\"}\n return False\n\n\n# #endregion _coerce_query_bool\n\n\n# #endregion AssistantHistory\n"
},
{
"contract_id": "_append_history",
@@ -5734,14 +5734,14 @@
{
"source_id": "_append_history",
"relation_type": "BINDS_TO",
- "target_id": "EXT:internal:CONVERSATIONS",
- "target_ref": "[EXT:internal:CONVERSATIONS]"
+ "target_id": "CONVERSATIONS",
+ "target_ref": "[CONVERSATIONS]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region _append_history [C:2] [TYPE Function]\n# @BRIEF Append conversation message to in-memory history buffer.\n# @DATA_CONTRACT Input[user_id,conversation_id,role,text,state?,task_id?,confirmation_id?] -> Output[None]\n# @RELATION BINDS_TO -> [EXT:internal:CONVERSATIONS]\n# @SIDE_EFFECT Mutates in-memory CONVERSATIONS store for user conversation history.\n# @PRE user_id and conversation_id identify target conversation bucket.\n# @POST Message entry is appended to CONVERSATIONS key list.\n# @INVARIANT every appended entry includes generated message_id and created_at timestamp.\ndef _append_history(\n user_id: str,\n conversation_id: str,\n role: str,\n text: str,\n state: str | None = None,\n task_id: str | None = None,\n confirmation_id: str | None = None,\n):\n key = (user_id, conversation_id)\n if key not in CONVERSATIONS:\n CONVERSATIONS[key] = []\n CONVERSATIONS[key].append(\n {\n \"message_id\": str(uuid.uuid4()),\n \"conversation_id\": conversation_id,\n \"role\": role,\n \"text\": text,\n \"state\": state,\n \"task_id\": task_id,\n \"confirmation_id\": confirmation_id,\n \"created_at\": datetime.utcnow(),\n }\n )\n\n\n# #endregion _append_history\n"
+ "body": "# #region _append_history [C:2] [TYPE Function]\n# @BRIEF Append conversation message to in-memory history buffer.\n# @DATA_CONTRACT Input[user_id,conversation_id,role,text,state?,task_id?,confirmation_id?] -> Output[None]\n# @RELATION BINDS_TO -> [CONVERSATIONS]\n# @SIDE_EFFECT Mutates in-memory CONVERSATIONS store for user conversation history.\n# @PRE user_id and conversation_id identify target conversation bucket.\n# @POST Message entry is appended to CONVERSATIONS key list.\n# @INVARIANT every appended entry includes generated message_id and created_at timestamp.\ndef _append_history(\n user_id: str,\n conversation_id: str,\n role: str,\n text: str,\n state: str | None = None,\n task_id: str | None = None,\n confirmation_id: str | None = None,\n):\n key = (user_id, conversation_id)\n if key not in CONVERSATIONS:\n CONVERSATIONS[key] = []\n CONVERSATIONS[key].append(\n {\n \"message_id\": str(uuid.uuid4()),\n \"conversation_id\": conversation_id,\n \"role\": role,\n \"text\": text,\n \"state\": state,\n \"task_id\": task_id,\n \"confirmation_id\": confirmation_id,\n \"created_at\": datetime.utcnow(),\n }\n )\n\n\n# #endregion _append_history\n"
},
{
"contract_id": "_persist_message",
@@ -5794,14 +5794,14 @@
{
"source_id": "_audit",
"relation_type": "BINDS_TO",
- "target_id": "EXT:internal:ASSISTANT_AUDIT",
- "target_ref": "[EXT:internal:ASSISTANT_AUDIT]"
+ "target_id": "ASSISTANT_AUDIT",
+ "target_ref": "[ASSISTANT_AUDIT]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region _audit [C:2] [TYPE Function]\n# @BRIEF Append in-memory audit record for assistant decision trace.\n# @DATA_CONTRACT Input[user_id,payload:Dict[str,Any]] -> Output[None]\n# @RELATION BINDS_TO -> [EXT:internal:ASSISTANT_AUDIT]\n# @SIDE_EFFECT Mutates in-memory ASSISTANT_AUDIT store and emits structured log event.\n# @PRE payload describes decision/outcome fields.\n# @POST ASSISTANT_AUDIT list for user contains new timestamped entry.\n# @INVARIANT persisted in-memory audit entry always contains created_at in ISO format.\ndef _audit(user_id: str, payload: dict[str, Any]):\n if user_id not in ASSISTANT_AUDIT:\n ASSISTANT_AUDIT[user_id] = []\n ASSISTANT_AUDIT[user_id].append(\n {**payload, \"created_at\": datetime.utcnow().isoformat()}\n )\n logger.info(f\"[assistant.audit] {payload}\")\n\n\n# #endregion _audit\n"
+ "body": "# #region _audit [C:2] [TYPE Function]\n# @BRIEF Append in-memory audit record for assistant decision trace.\n# @DATA_CONTRACT Input[user_id,payload:Dict[str,Any]] -> Output[None]\n# @RELATION BINDS_TO -> [ASSISTANT_AUDIT]\n# @SIDE_EFFECT Mutates in-memory ASSISTANT_AUDIT store and emits structured log event.\n# @PRE payload describes decision/outcome fields.\n# @POST ASSISTANT_AUDIT list for user contains new timestamped entry.\n# @INVARIANT persisted in-memory audit entry always contains created_at in ISO format.\ndef _audit(user_id: str, payload: dict[str, Any]):\n if user_id not in ASSISTANT_AUDIT:\n ASSISTANT_AUDIT[user_id] = []\n ASSISTANT_AUDIT[user_id].append(\n {**payload, \"created_at\": datetime.utcnow().isoformat()}\n )\n logger.info(f\"[assistant.audit] {payload}\")\n\n\n# #endregion _audit\n"
},
{
"contract_id": "_persist_audit",
@@ -6591,7 +6591,7 @@
"contract_type": "Module",
"file_path": "backend/src/api/routes/assistant/_schemas.py",
"start_line": 1,
- "end_line": 143,
+ "end_line": 150,
"tier": "TIER_1",
"complexity": 2,
"metadata": {
@@ -6618,7 +6618,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region AssistantSchemas [C:2] [TYPE Module] [SEMANTICS assistant, pydantic, schema, store, permission]\n# @BRIEF Pydantic models, in-memory stores, and permission mappings for the assistant API.\n# @LAYER API\n# @RELATION CALLED_BY -> [AssistantHistory]\n# @RELATION CALLED_BY -> [AssistantHistory]\n# @INVARIANT In-memory stores are module-level singletons shared across the assistant package.\n# @RATIONALE In-memory stores documented with NOTE about restart loss. ASSISTANT_ARCHIVE_AFTER_DAYS and ASSISTANT_MESSAGE_TTL_DAYS kept as module-level constants with TODO for config migration — Pydantic schemas module should not depend on ConfigManager for architectural purity.\n\nfrom __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom pydantic import BaseModel, Field\n\n\n# #region AssistantMessageRequest [C:1] [TYPE Class]\n# @BRIEF Input payload for assistant message endpoint.\n# @DATA_CONTRACT Input[conversation_id?:str, message:str(1..4000)] -> Output[AssistantMessageRequest]\n# @RELATION CALLED_BY -> [send_message]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE message length is within accepted bounds.\n# @POST Request object provides message text and optional conversation binding.\n# @INVARIANT message is always non-empty and no longer than 4000 characters.\nclass AssistantMessageRequest(BaseModel):\n conversation_id: str | None = None\n message: str = Field(..., min_length=1, max_length=4000)\n dataset_review_session_id: str | None = None\n\n\n# #endregion AssistantMessageRequest\n\n\n# #region AssistantAction [C:1] [TYPE Class]\n# @BRIEF UI action descriptor returned with assistant responses.\n# @DATA_CONTRACT Input[type:str, label:str, target?:str] -> Output[AssistantAction]\n# @RELATION CALLED_BY -> [AssistantMessageResponse]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE type and label are provided by orchestration logic.\n# @POST Action can be rendered as button on frontend.\n# @INVARIANT type and label are required for every UI action.\nclass AssistantAction(BaseModel):\n type: str\n label: str\n target: str | None = None\n\n\n# #endregion AssistantAction\n\n\n# #region AssistantMessageResponse [C:1] [TYPE Class]\n# @BRIEF Output payload contract for assistant interaction endpoints.\n# @DATA_CONTRACT Input[conversation_id,response_id,state,text,intent?,confirmation_id?,task_id?,actions[],created_at] -> Output[AssistantMessageResponse]\n# @RELATION CALLED_BY -> [send_message]\n# @RELATION CALLED_BY -> [confirm_operation]\n# @RELATION CALLED_BY -> [cancel_operation]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE Response includes deterministic state and text.\n# @POST Payload may include task_id/confirmation_id/actions for UI follow-up.\n# @INVARIANT created_at and state are always present in endpoint responses.\nclass AssistantMessageResponse(BaseModel):\n conversation_id: str\n response_id: str\n state: str\n text: str\n intent: dict[str, Any] | None = None\n confirmation_id: str | None = None\n task_id: str | None = None\n actions: list[AssistantAction] = Field(default_factory=list)\n created_at: datetime\n\n\n# #endregion AssistantMessageResponse\n\n\n# #region ConfirmationRecord [C:1] [TYPE Class]\n# @BRIEF In-memory confirmation token model for risky operation dispatch.\n# @DATA_CONTRACT Input[id,user_id,conversation_id,intent,dispatch,expires_at,state?,created_at] -> Output[ConfirmationRecord]\n# @RELATION CALLED_BY -> [send_message]\n# @RELATION CALLED_BY -> [confirm_operation]\n# @RELATION CALLED_BY -> [cancel_operation]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE intent/dispatch/user_id are populated at confirmation request time.\n# @POST Record tracks lifecycle state and expiry timestamp.\n# @INVARIANT state defaults to \"pending\" and expires_at bounds confirmation validity.\nclass ConfirmationRecord(BaseModel):\n id: str\n user_id: str\n conversation_id: str\n intent: dict[str, Any]\n dispatch: dict[str, Any]\n expires_at: datetime\n state: str = \"pending\"\n created_at: datetime\n\n\n# #endregion ConfirmationRecord\n\n\n# --- In-memory stores ---\n\nCONVERSATIONS: dict[tuple[str, str], list[dict[str, Any]]] = {}\nUSER_ACTIVE_CONVERSATION: dict[str, str] = {}\nCONFIRMATIONS: dict[str, ConfirmationRecord] = {}\nASSISTANT_AUDIT: dict[str, list[dict[str, Any]]] = {}\nASSISTANT_ARCHIVE_AFTER_DAYS = 14\nASSISTANT_MESSAGE_TTL_DAYS = 90\n\n# Operations that are read-only and do not require confirmation.\n_SAFE_OPS = {\n \"show_capabilities\",\n \"get_task_status\",\n \"get_health_summary\",\n \"dataset_review_answer_context\",\n}\n\n_DATASET_REVIEW_OPS = {\n \"dataset_review_approve_mappings\",\n \"dataset_review_set_field_semantics\",\n \"dataset_review_generate_sql_preview\",\n}\n\nINTENT_PERMISSION_CHECKS: dict[str, list[tuple[str, str]]] = {\n \"get_task_status\": [(\"tasks\", \"READ\")],\n \"create_branch\": [(\"plugin:git\", \"EXECUTE\")],\n \"commit_changes\": [(\"plugin:git\", \"EXECUTE\")],\n \"deploy_dashboard\": [(\"plugin:git\", \"EXECUTE\")],\n \"execute_migration\": [\n (\"plugin:migration\", \"EXECUTE\"),\n (\"plugin:superset-migration\", \"EXECUTE\"),\n ],\n \"run_backup\": [(\"plugin:superset-backup\", \"EXECUTE\"), (\"plugin:backup\", \"EXECUTE\")],\n \"run_llm_validation\": [(\"plugin:llm_dashboard_validation\", \"EXECUTE\")],\n \"run_llm_documentation\": [(\"plugin:llm_documentation\", \"EXECUTE\")],\n \"get_health_summary\": [(\"plugin:migration\", \"READ\")],\n \"dataset_review_answer_context\": [(\"dataset:session\", \"READ\")],\n \"dataset_review_approve_mappings\": [(\"dataset:session\", \"MANAGE\")],\n \"dataset_review_set_field_semantics\": [(\"dataset:session\", \"MANAGE\")],\n \"dataset_review_generate_sql_preview\": [(\"dataset:session\", \"MANAGE\")],\n}\n\n\n# #endregion AssistantSchemas\n"
+ "body": "# #region AssistantSchemas [C:2] [TYPE Module] [SEMANTICS assistant, pydantic, schema, store, permission]\n# @BRIEF Pydantic models, in-memory stores, and permission mappings for the assistant API.\n# @LAYER API\n# @RELATION CALLED_BY -> [AssistantHistory]\n# @RELATION CALLED_BY -> [AssistantHistory]\n# @INVARIANT In-memory stores are module-level singletons shared across the assistant package.\n# @RATIONALE In-memory stores documented with NOTE about restart loss. ASSISTANT_ARCHIVE_AFTER_DAYS and ASSISTANT_MESSAGE_TTL_DAYS kept as module-level constants with TODO for config migration — Pydantic schemas module should not depend on ConfigManager for architectural purity.\n\nfrom __future__ import annotations\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom pydantic import BaseModel, Field\n\n\n# #region AssistantMessageRequest [C:1] [TYPE Class]\n# @BRIEF Input payload for assistant message endpoint.\n# @DATA_CONTRACT Input[conversation_id?:str, message:str(1..4000)] -> Output[AssistantMessageRequest]\n# @RELATION CALLED_BY -> [send_message]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE message length is within accepted bounds.\n# @POST Request object provides message text and optional conversation binding.\n# @INVARIANT message is always non-empty and no longer than 4000 characters.\nclass AssistantMessageRequest(BaseModel):\n conversation_id: str | None = None\n message: str = Field(..., min_length=1, max_length=4000)\n dataset_review_session_id: str | None = None\n\n\n# #endregion AssistantMessageRequest\n\n\n# #region AssistantAction [C:1] [TYPE Class]\n# @BRIEF UI action descriptor returned with assistant responses.\n# @DATA_CONTRACT Input[type:str, label:str, target?:str] -> Output[AssistantAction]\n# @RELATION CALLED_BY -> [AssistantMessageResponse]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE type and label are provided by orchestration logic.\n# @POST Action can be rendered as button on frontend.\n# @INVARIANT type and label are required for every UI action.\nclass AssistantAction(BaseModel):\n type: str\n label: str\n target: str | None = None\n\n\n# #endregion AssistantAction\n\n\n# #region AssistantMessageResponse [C:1] [TYPE Class]\n# @BRIEF Output payload contract for assistant interaction endpoints.\n# @DATA_CONTRACT Input[conversation_id,response_id,state,text,intent?,confirmation_id?,task_id?,actions[],created_at] -> Output[AssistantMessageResponse]\n# @RELATION CALLED_BY -> [send_message]\n# @RELATION CALLED_BY -> [confirm_operation]\n# @RELATION CALLED_BY -> [cancel_operation]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE Response includes deterministic state and text.\n# @POST Payload may include task_id/confirmation_id/actions for UI follow-up.\n# @INVARIANT created_at and state are always present in endpoint responses.\nclass AssistantMessageResponse(BaseModel):\n conversation_id: str\n response_id: str\n state: str\n text: str\n intent: dict[str, Any] | None = None\n confirmation_id: str | None = None\n task_id: str | None = None\n actions: list[AssistantAction] = Field(default_factory=list)\n created_at: datetime\n\n\n# #endregion AssistantMessageResponse\n\n\n# #region ConfirmationRecord [C:1] [TYPE Class]\n# @BRIEF In-memory confirmation token model for risky operation dispatch.\n# @DATA_CONTRACT Input[id,user_id,conversation_id,intent,dispatch,expires_at,state?,created_at] -> Output[ConfirmationRecord]\n# @RELATION CALLED_BY -> [send_message]\n# @RELATION CALLED_BY -> [confirm_operation]\n# @RELATION CALLED_BY -> [cancel_operation]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE intent/dispatch/user_id are populated at confirmation request time.\n# @POST Record tracks lifecycle state and expiry timestamp.\n# @INVARIANT state defaults to \"pending\" and expires_at bounds confirmation validity.\nclass ConfirmationRecord(BaseModel):\n id: str\n user_id: str\n conversation_id: str\n intent: dict[str, Any]\n dispatch: dict[str, Any]\n expires_at: datetime\n state: str = \"pending\"\n created_at: datetime\n\n\n# #endregion ConfirmationRecord\n\n\n# --- In-memory stores ---\n\n# #region CONVERSATIONS [C:1] [TYPE Constant]\n# @BRIEF In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}\n# #endregion CONVERSATIONS\nCONVERSATIONS: dict[tuple[str, str], list[dict[str, Any]]] = {}\n\n# #region ASSISTANT_AUDIT [C:1] [TYPE Constant]\n# @BRIEF In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.\n# #endregion ASSISTANT_AUDIT\nUSER_ACTIVE_CONVERSATION: dict[str, str] = {}\nCONFIRMATIONS: dict[str, ConfirmationRecord] = {}\nASSISTANT_AUDIT: dict[str, list[dict[str, Any]]] = {}\nASSISTANT_ARCHIVE_AFTER_DAYS = 14\nASSISTANT_MESSAGE_TTL_DAYS = 90\n\n# Operations that are read-only and do not require confirmation.\n_SAFE_OPS = {\n \"show_capabilities\",\n \"get_task_status\",\n \"get_health_summary\",\n \"dataset_review_answer_context\",\n}\n\n_DATASET_REVIEW_OPS = {\n \"dataset_review_approve_mappings\",\n \"dataset_review_set_field_semantics\",\n \"dataset_review_generate_sql_preview\",\n}\n\nINTENT_PERMISSION_CHECKS: dict[str, list[tuple[str, str]]] = {\n \"get_task_status\": [(\"tasks\", \"READ\")],\n \"create_branch\": [(\"plugin:git\", \"EXECUTE\")],\n \"commit_changes\": [(\"plugin:git\", \"EXECUTE\")],\n \"deploy_dashboard\": [(\"plugin:git\", \"EXECUTE\")],\n \"execute_migration\": [\n (\"plugin:migration\", \"EXECUTE\"),\n (\"plugin:superset-migration\", \"EXECUTE\"),\n ],\n \"run_backup\": [(\"plugin:superset-backup\", \"EXECUTE\"), (\"plugin:backup\", \"EXECUTE\")],\n \"run_llm_validation\": [(\"plugin:llm_dashboard_validation\", \"EXECUTE\")],\n \"run_llm_documentation\": [(\"plugin:llm_documentation\", \"EXECUTE\")],\n \"get_health_summary\": [(\"plugin:migration\", \"READ\")],\n \"dataset_review_answer_context\": [(\"dataset:session\", \"READ\")],\n \"dataset_review_approve_mappings\": [(\"dataset:session\", \"MANAGE\")],\n \"dataset_review_set_field_semantics\": [(\"dataset:session\", \"MANAGE\")],\n \"dataset_review_generate_sql_preview\": [(\"dataset:session\", \"MANAGE\")],\n}\n\n\n# #endregion AssistantSchemas\n"
},
{
"contract_id": "AssistantMessageRequest",
@@ -6764,6 +6764,42 @@
"tier_source": "AutoCalculated",
"body": "# #region ConfirmationRecord [C:1] [TYPE Class]\n# @BRIEF In-memory confirmation token model for risky operation dispatch.\n# @DATA_CONTRACT Input[id,user_id,conversation_id,intent,dispatch,expires_at,state?,created_at] -> Output[ConfirmationRecord]\n# @RELATION CALLED_BY -> [send_message]\n# @RELATION CALLED_BY -> [confirm_operation]\n# @RELATION CALLED_BY -> [cancel_operation]\n# @SIDE_EFFECT None (schema declaration only).\n# @PRE intent/dispatch/user_id are populated at confirmation request time.\n# @POST Record tracks lifecycle state and expiry timestamp.\n# @INVARIANT state defaults to \"pending\" and expires_at bounds confirmation validity.\nclass ConfirmationRecord(BaseModel):\n id: str\n user_id: str\n conversation_id: str\n intent: dict[str, Any]\n dispatch: dict[str, Any]\n expires_at: datetime\n state: str = \"pending\"\n created_at: datetime\n\n\n# #endregion ConfirmationRecord\n"
},
+ {
+ "contract_id": "CONVERSATIONS",
+ "contract_type": "Constant",
+ "file_path": "backend/src/api/routes/assistant/_schemas.py",
+ "start_line": 102,
+ "end_line": 104,
+ "tier": "TIER_1",
+ "complexity": 1,
+ "metadata": {
+ "BRIEF": "In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}",
+ "COMPLEXITY": 1
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "# #region CONVERSATIONS [C:1] [TYPE Constant]\n# @BRIEF In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}\n# #endregion CONVERSATIONS\n"
+ },
+ {
+ "contract_id": "ASSISTANT_AUDIT",
+ "contract_type": "Constant",
+ "file_path": "backend/src/api/routes/assistant/_schemas.py",
+ "start_line": 107,
+ "end_line": 109,
+ "tier": "TIER_1",
+ "complexity": 1,
+ "metadata": {
+ "BRIEF": "In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.",
+ "COMPLEXITY": 1
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "# #region ASSISTANT_AUDIT [C:1] [TYPE Constant]\n# @BRIEF In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.\n# #endregion ASSISTANT_AUDIT\n"
+ },
{
"contract_id": "CleanReleaseApi",
"contract_type": "Module",
@@ -7397,8 +7433,8 @@
{
"source_id": "DashboardActionRoutes",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:frontend:DashboardRouter]",
- "target_ref": "[[EXT:frontend:DashboardRouter]]"
+ "target_id": "EXT:frontend:DashboardRouter]",
+ "target_ref": "[EXT:frontend:DashboardRouter]]"
},
{
"source_id": "DashboardActionRoutes",
@@ -7410,7 +7446,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DashboardActionRoutes [C:2] [TYPE Module] [SEMANTICS fastapi, dashboard, api, backup]\n# @BRIEF Dashboard action route handlers — migrate, backup.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [[EXT:frontend:DashboardRouter]]\n# @RELATION DEPENDS_ON -> [DashboardSchemas]\n\nfrom fastapi import Depends, HTTPException\n\nfrom src.core.logger import belief_scope, logger\nfrom src.dependencies import (\n get_config_manager,\n get_task_manager,\n has_permission,\n)\n\nfrom ._router import router\nfrom ._schemas import (\n BackupRequest,\n MigrateRequest,\n TaskResponse,\n)\n\n\n# #region migrate_dashboards [C:2] [TYPE Function]\n# @BRIEF Trigger bulk migration of dashboards from source to target environment\n# @PRE User has permission plugin:migration:execute\n# @PRE source_env_id and target_env_id are valid environment IDs\n# @PRE dashboard_ids is a non-empty list\n# @POST Returns task_id for tracking migration progress\n# @POST Task is created and queued for execution\n# @RELATION DISPATCHES -> [EXT:method:MigrationPlugin:execute]\n# @RELATION CALLS -> [TaskManager]\n@router.post(\"/migrate\", response_model=TaskResponse)\nasync def migrate_dashboards(\n request: MigrateRequest,\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n _=Depends(has_permission(\"plugin:migration\", \"EXECUTE\")),\n):\n with belief_scope(\n \"migrate_dashboards\",\n f\"source={request.source_env_id}, target={request.target_env_id}, count={len(request.dashboard_ids)}\",\n ):\n if not request.dashboard_ids:\n logger.error(\n \"[migrate_dashboards][Coherence:Failed] No dashboard IDs provided\"\n )\n raise HTTPException(\n status_code=400, detail=\"At least one dashboard ID must be provided\"\n )\n\n environments = config_manager.get_environments()\n source_env = next(\n (e for e in environments if e.id == request.source_env_id), None\n )\n target_env = next(\n (e for e in environments if e.id == request.target_env_id), None\n )\n\n if not source_env:\n logger.error(\n f\"[migrate_dashboards][Coherence:Failed] Source environment not found: {request.source_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Source environment not found\")\n if not target_env:\n logger.error(\n f\"[migrate_dashboards][Coherence:Failed] Target environment not found: {request.target_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Target environment not found\")\n\n try:\n task_params = {\n \"source_env_id\": request.source_env_id,\n \"target_env_id\": request.target_env_id,\n \"selected_ids\": request.dashboard_ids,\n \"replace_db_config\": request.replace_db_config,\n \"db_mappings\": request.db_mappings or {},\n }\n\n task_obj = await task_manager.create_task(\n plugin_id=\"superset-migration\", params=task_params\n )\n\n logger.info(\n f\"[migrate_dashboards][Coherence:OK] Migration task created: {task_obj.id} for {len(request.dashboard_ids)} dashboards\"\n )\n\n return TaskResponse(task_id=str(task_obj.id))\n\n except Exception as e:\n logger.error(\n f\"[migrate_dashboards][Coherence:Failed] Failed to create migration task: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to create migration task: {e!s}\"\n )\n\n\n# #endregion migrate_dashboards\n\n\n# #region backup_dashboards [C:2] [TYPE Function]\n# @BRIEF Trigger bulk backup of dashboards with optional cron schedule\n# @PRE User has permission plugin:backup:execute\n# @PRE env_id is a valid environment ID\n# @PRE dashboard_ids is a non-empty list\n# @POST Returns task_id for tracking backup progress\n# @POST Task is created and queued for execution\n# @POST If schedule is provided, a scheduled task is created\n# @RELATION DISPATCHES -> [EXT:method:BackupPlugin:execute]\n# @RELATION CALLS -> [TaskManager]\n@router.post(\"/backup\", response_model=TaskResponse)\nasync def backup_dashboards(\n request: BackupRequest,\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n _=Depends(has_permission(\"plugin:backup\", \"EXECUTE\")),\n):\n with belief_scope(\n \"backup_dashboards\",\n f\"env={request.env_id}, count={len(request.dashboard_ids)}, schedule={request.schedule}\",\n ):\n if not request.dashboard_ids:\n logger.error(\n \"[backup_dashboards][Coherence:Failed] No dashboard IDs provided\"\n )\n raise HTTPException(\n status_code=400, detail=\"At least one dashboard ID must be provided\"\n )\n\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == request.env_id), None)\n\n if not env:\n logger.error(\n f\"[backup_dashboards][Coherence:Failed] Environment not found: {request.env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n try:\n task_params = {\n \"env\": request.env_id,\n \"dashboards\": request.dashboard_ids,\n \"schedule\": request.schedule,\n }\n\n task_obj = await task_manager.create_task(\n plugin_id=\"superset-backup\", params=task_params\n )\n\n logger.info(\n f\"[backup_dashboards][Coherence:OK] Backup task created: {task_obj.id} for {len(request.dashboard_ids)} dashboards\"\n )\n\n return TaskResponse(task_id=str(task_obj.id))\n\n except Exception as e:\n logger.error(\n f\"[backup_dashboards][Coherence:Failed] Failed to create backup task: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to create backup task: {e!s}\"\n )\n\n\n# #endregion backup_dashboards\n# #endregion DashboardActionRoutes\n"
+ "body": "# #region DashboardActionRoutes [C:2] [TYPE Module] [SEMANTICS fastapi, dashboard, api, backup]\n# @BRIEF Dashboard action route handlers — migrate, backup.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]\n# @RELATION DEPENDS_ON -> [DashboardSchemas]\n\nfrom fastapi import Depends, HTTPException\n\nfrom src.core.logger import belief_scope, logger\nfrom src.dependencies import (\n get_config_manager,\n get_task_manager,\n has_permission,\n)\n\nfrom ._router import router\nfrom ._schemas import (\n BackupRequest,\n MigrateRequest,\n TaskResponse,\n)\n\n\n# #region migrate_dashboards [C:2] [TYPE Function]\n# @BRIEF Trigger bulk migration of dashboards from source to target environment\n# @PRE User has permission plugin:migration:execute\n# @PRE source_env_id and target_env_id are valid environment IDs\n# @PRE dashboard_ids is a non-empty list\n# @POST Returns task_id for tracking migration progress\n# @POST Task is created and queued for execution\n# @RELATION DISPATCHES -> [EXT:method:MigrationPlugin:execute]\n# @RELATION CALLS -> [TaskManager]\n@router.post(\"/migrate\", response_model=TaskResponse)\nasync def migrate_dashboards(\n request: MigrateRequest,\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n _=Depends(has_permission(\"plugin:migration\", \"EXECUTE\")),\n):\n with belief_scope(\n \"migrate_dashboards\",\n f\"source={request.source_env_id}, target={request.target_env_id}, count={len(request.dashboard_ids)}\",\n ):\n if not request.dashboard_ids:\n logger.error(\n \"[migrate_dashboards][Coherence:Failed] No dashboard IDs provided\"\n )\n raise HTTPException(\n status_code=400, detail=\"At least one dashboard ID must be provided\"\n )\n\n environments = config_manager.get_environments()\n source_env = next(\n (e for e in environments if e.id == request.source_env_id), None\n )\n target_env = next(\n (e for e in environments if e.id == request.target_env_id), None\n )\n\n if not source_env:\n logger.error(\n f\"[migrate_dashboards][Coherence:Failed] Source environment not found: {request.source_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Source environment not found\")\n if not target_env:\n logger.error(\n f\"[migrate_dashboards][Coherence:Failed] Target environment not found: {request.target_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Target environment not found\")\n\n try:\n task_params = {\n \"source_env_id\": request.source_env_id,\n \"target_env_id\": request.target_env_id,\n \"selected_ids\": request.dashboard_ids,\n \"replace_db_config\": request.replace_db_config,\n \"db_mappings\": request.db_mappings or {},\n }\n\n task_obj = await task_manager.create_task(\n plugin_id=\"superset-migration\", params=task_params\n )\n\n logger.info(\n f\"[migrate_dashboards][Coherence:OK] Migration task created: {task_obj.id} for {len(request.dashboard_ids)} dashboards\"\n )\n\n return TaskResponse(task_id=str(task_obj.id))\n\n except Exception as e:\n logger.error(\n f\"[migrate_dashboards][Coherence:Failed] Failed to create migration task: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to create migration task: {e!s}\"\n )\n\n\n# #endregion migrate_dashboards\n\n\n# #region backup_dashboards [C:2] [TYPE Function]\n# @BRIEF Trigger bulk backup of dashboards with optional cron schedule\n# @PRE User has permission plugin:backup:execute\n# @PRE env_id is a valid environment ID\n# @PRE dashboard_ids is a non-empty list\n# @POST Returns task_id for tracking backup progress\n# @POST Task is created and queued for execution\n# @POST If schedule is provided, a scheduled task is created\n# @RELATION DISPATCHES -> [EXT:method:BackupPlugin:execute]\n# @RELATION CALLS -> [TaskManager]\n@router.post(\"/backup\", response_model=TaskResponse)\nasync def backup_dashboards(\n request: BackupRequest,\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n _=Depends(has_permission(\"plugin:backup\", \"EXECUTE\")),\n):\n with belief_scope(\n \"backup_dashboards\",\n f\"env={request.env_id}, count={len(request.dashboard_ids)}, schedule={request.schedule}\",\n ):\n if not request.dashboard_ids:\n logger.error(\n \"[backup_dashboards][Coherence:Failed] No dashboard IDs provided\"\n )\n raise HTTPException(\n status_code=400, detail=\"At least one dashboard ID must be provided\"\n )\n\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == request.env_id), None)\n\n if not env:\n logger.error(\n f\"[backup_dashboards][Coherence:Failed] Environment not found: {request.env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n try:\n task_params = {\n \"env\": request.env_id,\n \"dashboards\": request.dashboard_ids,\n \"schedule\": request.schedule,\n }\n\n task_obj = await task_manager.create_task(\n plugin_id=\"superset-backup\", params=task_params\n )\n\n logger.info(\n f\"[backup_dashboards][Coherence:OK] Backup task created: {task_obj.id} for {len(request.dashboard_ids)} dashboards\"\n )\n\n return TaskResponse(task_id=str(task_obj.id))\n\n except Exception as e:\n logger.error(\n f\"[backup_dashboards][Coherence:Failed] Failed to create backup task: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to create backup task: {e!s}\"\n )\n\n\n# #endregion backup_dashboards\n# #endregion DashboardActionRoutes\n"
},
{
"contract_id": "migrate_dashboards",
@@ -7495,8 +7531,8 @@
{
"source_id": "DashboardDetailRoutes",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:frontend:DashboardRouter]",
- "target_ref": "[[EXT:frontend:DashboardRouter]]"
+ "target_id": "EXT:frontend:DashboardRouter]",
+ "target_ref": "[EXT:frontend:DashboardRouter]]"
},
{
"source_id": "DashboardDetailRoutes",
@@ -7520,7 +7556,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DashboardDetailRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, dashboard, api, transform, search, task]\n# @BRIEF Dashboard detail, db-mappings, task history, thumbnail route handlers.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [[EXT:frontend:DashboardRouter]]\n# @RELATION DEPENDS_ON -> [DashboardSchemas]\n# @RELATION DEPENDS_ON -> [DashboardHelpers]\n# @RELATION DEPENDS_ON -> [DashboardProjection]\n\nimport re\nfrom typing import Any\nfrom urllib.parse import urlparse\n\nfrom fastapi import Depends, HTTPException, Query, Response\nfrom fastapi.responses import JSONResponse\n\nfrom src.core.async_superset_client import AsyncSupersetClient\nfrom src.core.logger import belief_scope, logger\nfrom src.core.superset_client import SupersetClient\nfrom src.core.utils.network import DashboardNotFoundError\nfrom src.dependencies import (\n get_config_manager,\n get_mapping_service,\n get_task_manager,\n has_permission,\n)\n\nfrom ._helpers import (\n _resolve_dashboard_id_from_ref,\n _resolve_dashboard_id_from_ref_async,\n)\nfrom ._projection import (\n _task_matches_dashboard,\n)\nfrom ._router import router\nfrom ._schemas import (\n DashboardDetailResponse,\n DashboardTaskHistoryItem,\n DashboardTaskHistoryResponse,\n DatabaseMapping,\n DatabaseMappingsResponse,\n)\n\n\n# #region get_database_mappings [C:2] [TYPE Function]\n# @BRIEF Get database mapping suggestions between source and target environments\n# @PRE User has permission plugin:migration:read\n# @PRE source_env_id and target_env_id are valid environment IDs\n# @POST Returns list of suggested database mappings with confidence scores\n# @RELATION CALLS -> [EXT:method:MappingService:get_suggestions]\n@router.get(\"/db-mappings\", response_model=DatabaseMappingsResponse)\nasync def get_database_mappings(\n source_env_id: str,\n target_env_id: str,\n config_manager=Depends(get_config_manager),\n mapping_service=Depends(get_mapping_service),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_database_mappings\", f\"source={source_env_id}, target={target_env_id}\"\n ):\n environments = config_manager.get_environments()\n source_env = next((e for e in environments if e.id == source_env_id), None)\n target_env = next((e for e in environments if e.id == target_env_id), None)\n\n if not source_env:\n logger.error(\n f\"[get_database_mappings][Coherence:Failed] Source environment not found: {source_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Source environment not found\")\n if not target_env:\n logger.error(\n f\"[get_database_mappings][Coherence:Failed] Target environment not found: {target_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Target environment not found\")\n\n try:\n suggestions = await mapping_service.get_suggestions(\n source_env_id, target_env_id\n )\n\n mappings = [\n DatabaseMapping(\n source_db=s.get(\"source_db\", \"\"),\n target_db=s.get(\"target_db\", \"\"),\n source_db_uuid=s.get(\"source_db_uuid\"),\n target_db_uuid=s.get(\"target_db_uuid\"),\n confidence=s.get(\"confidence\", 0.0),\n )\n for s in suggestions\n ]\n\n logger.info(\n f\"[get_database_mappings][Coherence:OK] Returning {len(mappings)} database mapping suggestions\"\n )\n\n return DatabaseMappingsResponse(mappings=mappings)\n\n except Exception as e:\n logger.error(\n f\"[get_database_mappings][Coherence:Failed] Failed to get database mappings: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to get database mappings: {e!s}\"\n )\n\n\n# #endregion get_database_mappings\n\n\n# #region get_dashboard_detail [C:2] [TYPE Function]\n# @BRIEF Fetch detailed dashboard info with related charts and datasets\n# @PRE env_id must be valid and dashboard ref (slug or id) must exist\n# @POST Returns dashboard detail payload for overview page\n# @RELATION CALLS -> [AsyncSupersetClient]\n@router.get(\"/{dashboard_ref}\", response_model=DashboardDetailResponse)\nasync def get_dashboard_detail(\n dashboard_ref: str,\n env_id: str,\n config_manager=Depends(get_config_manager),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboard_detail\", f\"dashboard_ref={dashboard_ref}, env_id={env_id}\"\n ):\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(\n f\"[get_dashboard_detail][Coherence:Failed] Environment not found: {env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n try:\n sync_client = SupersetClient(env)\n dashboard_id = _resolve_dashboard_id_from_ref(dashboard_ref, sync_client)\n detail = sync_client.get_dashboard_detail(dashboard_id)\n logger.info(\n f\"[get_dashboard_detail][Coherence:OK] Dashboard ref={dashboard_ref} resolved_id={dashboard_id}: {detail.get('chart_count', 0)} charts, {detail.get('dataset_count', 0)} datasets\"\n )\n return DashboardDetailResponse(**detail)\n except HTTPException:\n raise\n except Exception as e:\n logger.error(\n f\"[get_dashboard_detail][Coherence:Failed] Failed to fetch dashboard detail: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to fetch dashboard detail: {e!s}\"\n )\n\n\n# #endregion get_dashboard_detail\n\n\n# #region get_dashboard_tasks_history [C:2] [TYPE Function]\n# @BRIEF Returns history of backup and LLM validation tasks for a dashboard.\n# @PRE dashboard ref (slug or id) is valid.\n# @POST Response contains sorted task history (newest first).\n@router.get(\"/{dashboard_ref}/tasks\", response_model=DashboardTaskHistoryResponse)\nasync def get_dashboard_tasks_history(\n dashboard_ref: str,\n env_id: str | None = None,\n limit: int = Query(20, ge=1, le=100),\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n _=Depends(has_permission(\"tasks\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboard_tasks_history\",\n f\"dashboard_ref={dashboard_ref}, env_id={env_id}, limit={limit}\",\n ):\n dashboard_id: int | None = None\n client: AsyncSupersetClient | None = None\n try:\n if dashboard_ref.isdigit():\n dashboard_id = int(dashboard_ref)\n elif env_id:\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(\n f\"[get_dashboard_tasks_history][Coherence:Failed] Environment not found: {env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n client = AsyncSupersetClient(env)\n dashboard_id = await _resolve_dashboard_id_from_ref_async(\n dashboard_ref, client\n )\n else:\n logger.error(\n \"[get_dashboard_tasks_history][Coherence:Failed] Non-numeric dashboard ref requires env_id\"\n )\n raise HTTPException(\n status_code=400,\n detail=\"env_id is required when dashboard reference is a slug\",\n )\n\n matching_tasks = []\n for task in task_manager.get_all_tasks():\n if _task_matches_dashboard(task, dashboard_id, env_id):\n matching_tasks.append(task)\n\n def _sort_key(task_obj: Any) -> str:\n return str(getattr(task_obj, \"started_at\", \"\") or \"\") or str(\n getattr(task_obj, \"finished_at\", \"\") or \"\"\n )\n\n matching_tasks.sort(key=_sort_key, reverse=True)\n selected = matching_tasks[:limit]\n\n items = []\n for task in selected:\n result = getattr(task, \"result\", None)\n summary = None\n validation_status = None\n if isinstance(result, dict):\n raw_validation_status = result.get(\"status\")\n if raw_validation_status is not None:\n validation_status = str(raw_validation_status)\n summary = (\n result.get(\"summary\")\n or result.get(\"status\")\n or result.get(\"message\")\n )\n params = getattr(task, \"params\", {}) or {}\n items.append(\n DashboardTaskHistoryItem(\n id=str(getattr(task, \"id\", \"\")),\n plugin_id=str(getattr(task, \"plugin_id\", \"\")),\n status=str(getattr(task, \"status\", \"\")),\n validation_status=validation_status,\n started_at=getattr(task, \"started_at\", None).isoformat()\n if getattr(task, \"started_at\", None)\n else None,\n finished_at=getattr(task, \"finished_at\", None).isoformat()\n if getattr(task, \"finished_at\", None)\n else None,\n env_id=str(params.get(\"environment_id\") or params.get(\"env\"))\n if (params.get(\"environment_id\") or params.get(\"env\"))\n else None,\n summary=summary,\n )\n )\n\n logger.info(\n f\"[get_dashboard_tasks_history][Coherence:OK] Found {len(items)} tasks for dashboard_ref={dashboard_ref}, dashboard_id={dashboard_id}\"\n )\n return DashboardTaskHistoryResponse(dashboard_id=dashboard_id, items=items)\n finally:\n if client is not None:\n await client.aclose()\n\n\n# #endregion get_dashboard_tasks_history\n\n\n# #region get_dashboard_thumbnail [C:3] [TYPE Function]\n# @BRIEF Proxies Superset dashboard thumbnail with cache support.\n# @RELATION CALLS -> [AsyncSupersetClient]\n# @PRE env_id must exist.\n# @POST Returns image bytes or 202 when thumbnail is being prepared by Superset.\n@router.get(\"/{dashboard_ref}/thumbnail\")\nasync def get_dashboard_thumbnail(\n dashboard_ref: str,\n env_id: str,\n force: bool = Query(False),\n config_manager=Depends(get_config_manager),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboard_thumbnail\",\n f\"dashboard_ref={dashboard_ref}, env_id={env_id}, force={force}\",\n ):\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(\n f\"[get_dashboard_thumbnail][Coherence:Failed] Environment not found: {env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n try:\n client = SupersetClient(env)\n dashboard_id = _resolve_dashboard_id_from_ref(dashboard_ref, client)\n digest = None\n thumb_endpoint = None\n\n try:\n screenshot_payload = client.network.request(\n method=\"POST\",\n endpoint=f\"/dashboard/{dashboard_id}/cache_dashboard_screenshot/\",\n json={\"force\": force},\n )\n payload = (\n screenshot_payload.get(\"result\", screenshot_payload)\n if isinstance(screenshot_payload, dict)\n else {}\n )\n image_url = (\n payload.get(\"image_url\", \"\") if isinstance(payload, dict) else \"\"\n )\n if isinstance(image_url, str) and image_url:\n matched = re.search(\n r\"/dashboard/\\d+/(?:thumbnail|screenshot)/([^/]+)/?$\",\n image_url,\n )\n if matched:\n digest = matched.group(1)\n except DashboardNotFoundError:\n logger.warning(\n \"[get_dashboard_thumbnail][Fallback] cache_dashboard_screenshot endpoint unavailable, fallback to dashboard.thumbnail_url\"\n )\n\n if not digest:\n dashboard_payload = client.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}\",\n )\n dashboard_data = (\n dashboard_payload.get(\"result\", dashboard_payload)\n if isinstance(dashboard_payload, dict)\n else {}\n )\n thumbnail_url = (\n dashboard_data.get(\"thumbnail_url\", \"\")\n if isinstance(dashboard_data, dict)\n else \"\"\n )\n if isinstance(thumbnail_url, str) and thumbnail_url:\n parsed = urlparse(thumbnail_url)\n parsed_path = parsed.path or thumbnail_url\n if parsed_path.startswith(\"/api/v1/\"):\n parsed_path = parsed_path[len(\"/api/v1\") :]\n thumb_endpoint = parsed_path\n matched = re.search(\n r\"/dashboard/\\d+/(?:thumbnail|screenshot)/([^/]+)/?$\",\n parsed_path,\n )\n if matched:\n digest = matched.group(1)\n\n if not thumb_endpoint:\n thumb_endpoint = (\n f\"/dashboard/{dashboard_id}/thumbnail/{digest or 'latest'}/\"\n )\n\n thumb_response = client.network.request(\n method=\"GET\",\n endpoint=thumb_endpoint,\n raw_response=True,\n allow_redirects=True,\n )\n\n if thumb_response.status_code == 202:\n payload_202: dict[str, Any] = {}\n try:\n payload_202 = thumb_response.json()\n except Exception:\n payload_202 = {\"message\": \"Thumbnail is being generated\"}\n return JSONResponse(status_code=202, content=payload_202)\n\n content_type = thumb_response.headers.get(\"Content-Type\", \"image/png\")\n return Response(content=thumb_response.content, media_type=content_type)\n except DashboardNotFoundError as e:\n logger.error(\n f\"[get_dashboard_thumbnail][Coherence:Failed] Dashboard not found for thumbnail: {e}\"\n )\n raise HTTPException(status_code=404, detail=\"Dashboard thumbnail not found\")\n except HTTPException:\n raise\n except Exception as e:\n logger.error(\n f\"[get_dashboard_thumbnail][Coherence:Failed] Failed to fetch dashboard thumbnail: {e}\"\n )\n raise HTTPException(\n status_code=503,\n detail=f\"Failed to fetch dashboard thumbnail: {e!s}\",\n )\n\n\n# #endregion get_dashboard_thumbnail\n# #endregion DashboardDetailRoutes\n"
+ "body": "# #region DashboardDetailRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, dashboard, api, transform, search, task]\n# @BRIEF Dashboard detail, db-mappings, task history, thumbnail route handlers.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]\n# @RELATION DEPENDS_ON -> [DashboardSchemas]\n# @RELATION DEPENDS_ON -> [DashboardHelpers]\n# @RELATION DEPENDS_ON -> [DashboardProjection]\n\nimport re\nfrom typing import Any\nfrom urllib.parse import urlparse\n\nfrom fastapi import Depends, HTTPException, Query, Response\nfrom fastapi.responses import JSONResponse\n\nfrom src.core.async_superset_client import AsyncSupersetClient\nfrom src.core.logger import belief_scope, logger\nfrom src.core.superset_client import SupersetClient\nfrom src.core.utils.network import DashboardNotFoundError\nfrom src.dependencies import (\n get_config_manager,\n get_mapping_service,\n get_task_manager,\n has_permission,\n)\n\nfrom ._helpers import (\n _resolve_dashboard_id_from_ref,\n _resolve_dashboard_id_from_ref_async,\n)\nfrom ._projection import (\n _task_matches_dashboard,\n)\nfrom ._router import router\nfrom ._schemas import (\n DashboardDetailResponse,\n DashboardTaskHistoryItem,\n DashboardTaskHistoryResponse,\n DatabaseMapping,\n DatabaseMappingsResponse,\n)\n\n\n# #region get_database_mappings [C:2] [TYPE Function]\n# @BRIEF Get database mapping suggestions between source and target environments\n# @PRE User has permission plugin:migration:read\n# @PRE source_env_id and target_env_id are valid environment IDs\n# @POST Returns list of suggested database mappings with confidence scores\n# @RELATION CALLS -> [EXT:method:MappingService:get_suggestions]\n@router.get(\"/db-mappings\", response_model=DatabaseMappingsResponse)\nasync def get_database_mappings(\n source_env_id: str,\n target_env_id: str,\n config_manager=Depends(get_config_manager),\n mapping_service=Depends(get_mapping_service),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_database_mappings\", f\"source={source_env_id}, target={target_env_id}\"\n ):\n environments = config_manager.get_environments()\n source_env = next((e for e in environments if e.id == source_env_id), None)\n target_env = next((e for e in environments if e.id == target_env_id), None)\n\n if not source_env:\n logger.error(\n f\"[get_database_mappings][Coherence:Failed] Source environment not found: {source_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Source environment not found\")\n if not target_env:\n logger.error(\n f\"[get_database_mappings][Coherence:Failed] Target environment not found: {target_env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Target environment not found\")\n\n try:\n suggestions = await mapping_service.get_suggestions(\n source_env_id, target_env_id\n )\n\n mappings = [\n DatabaseMapping(\n source_db=s.get(\"source_db\", \"\"),\n target_db=s.get(\"target_db\", \"\"),\n source_db_uuid=s.get(\"source_db_uuid\"),\n target_db_uuid=s.get(\"target_db_uuid\"),\n confidence=s.get(\"confidence\", 0.0),\n )\n for s in suggestions\n ]\n\n logger.info(\n f\"[get_database_mappings][Coherence:OK] Returning {len(mappings)} database mapping suggestions\"\n )\n\n return DatabaseMappingsResponse(mappings=mappings)\n\n except Exception as e:\n logger.error(\n f\"[get_database_mappings][Coherence:Failed] Failed to get database mappings: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to get database mappings: {e!s}\"\n )\n\n\n# #endregion get_database_mappings\n\n\n# #region get_dashboard_detail [C:2] [TYPE Function]\n# @BRIEF Fetch detailed dashboard info with related charts and datasets\n# @PRE env_id must be valid and dashboard ref (slug or id) must exist\n# @POST Returns dashboard detail payload for overview page\n# @RELATION CALLS -> [AsyncSupersetClient]\n@router.get(\"/{dashboard_ref}\", response_model=DashboardDetailResponse)\nasync def get_dashboard_detail(\n dashboard_ref: str,\n env_id: str,\n config_manager=Depends(get_config_manager),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboard_detail\", f\"dashboard_ref={dashboard_ref}, env_id={env_id}\"\n ):\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(\n f\"[get_dashboard_detail][Coherence:Failed] Environment not found: {env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n try:\n sync_client = SupersetClient(env)\n dashboard_id = _resolve_dashboard_id_from_ref(dashboard_ref, sync_client)\n detail = sync_client.get_dashboard_detail(dashboard_id)\n logger.info(\n f\"[get_dashboard_detail][Coherence:OK] Dashboard ref={dashboard_ref} resolved_id={dashboard_id}: {detail.get('chart_count', 0)} charts, {detail.get('dataset_count', 0)} datasets\"\n )\n return DashboardDetailResponse(**detail)\n except HTTPException:\n raise\n except Exception as e:\n logger.error(\n f\"[get_dashboard_detail][Coherence:Failed] Failed to fetch dashboard detail: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to fetch dashboard detail: {e!s}\"\n )\n\n\n# #endregion get_dashboard_detail\n\n\n# #region get_dashboard_tasks_history [C:2] [TYPE Function]\n# @BRIEF Returns history of backup and LLM validation tasks for a dashboard.\n# @PRE dashboard ref (slug or id) is valid.\n# @POST Response contains sorted task history (newest first).\n@router.get(\"/{dashboard_ref}/tasks\", response_model=DashboardTaskHistoryResponse)\nasync def get_dashboard_tasks_history(\n dashboard_ref: str,\n env_id: str | None = None,\n limit: int = Query(20, ge=1, le=100),\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n _=Depends(has_permission(\"tasks\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboard_tasks_history\",\n f\"dashboard_ref={dashboard_ref}, env_id={env_id}, limit={limit}\",\n ):\n dashboard_id: int | None = None\n client: AsyncSupersetClient | None = None\n try:\n if dashboard_ref.isdigit():\n dashboard_id = int(dashboard_ref)\n elif env_id:\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(\n f\"[get_dashboard_tasks_history][Coherence:Failed] Environment not found: {env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n client = AsyncSupersetClient(env)\n dashboard_id = await _resolve_dashboard_id_from_ref_async(\n dashboard_ref, client\n )\n else:\n logger.error(\n \"[get_dashboard_tasks_history][Coherence:Failed] Non-numeric dashboard ref requires env_id\"\n )\n raise HTTPException(\n status_code=400,\n detail=\"env_id is required when dashboard reference is a slug\",\n )\n\n matching_tasks = []\n for task in task_manager.get_all_tasks():\n if _task_matches_dashboard(task, dashboard_id, env_id):\n matching_tasks.append(task)\n\n def _sort_key(task_obj: Any) -> str:\n return str(getattr(task_obj, \"started_at\", \"\") or \"\") or str(\n getattr(task_obj, \"finished_at\", \"\") or \"\"\n )\n\n matching_tasks.sort(key=_sort_key, reverse=True)\n selected = matching_tasks[:limit]\n\n items = []\n for task in selected:\n result = getattr(task, \"result\", None)\n summary = None\n validation_status = None\n if isinstance(result, dict):\n raw_validation_status = result.get(\"status\")\n if raw_validation_status is not None:\n validation_status = str(raw_validation_status)\n summary = (\n result.get(\"summary\")\n or result.get(\"status\")\n or result.get(\"message\")\n )\n params = getattr(task, \"params\", {}) or {}\n items.append(\n DashboardTaskHistoryItem(\n id=str(getattr(task, \"id\", \"\")),\n plugin_id=str(getattr(task, \"plugin_id\", \"\")),\n status=str(getattr(task, \"status\", \"\")),\n validation_status=validation_status,\n started_at=getattr(task, \"started_at\", None).isoformat()\n if getattr(task, \"started_at\", None)\n else None,\n finished_at=getattr(task, \"finished_at\", None).isoformat()\n if getattr(task, \"finished_at\", None)\n else None,\n env_id=str(params.get(\"environment_id\") or params.get(\"env\"))\n if (params.get(\"environment_id\") or params.get(\"env\"))\n else None,\n summary=summary,\n )\n )\n\n logger.info(\n f\"[get_dashboard_tasks_history][Coherence:OK] Found {len(items)} tasks for dashboard_ref={dashboard_ref}, dashboard_id={dashboard_id}\"\n )\n return DashboardTaskHistoryResponse(dashboard_id=dashboard_id, items=items)\n finally:\n if client is not None:\n await client.aclose()\n\n\n# #endregion get_dashboard_tasks_history\n\n\n# #region get_dashboard_thumbnail [C:3] [TYPE Function]\n# @BRIEF Proxies Superset dashboard thumbnail with cache support.\n# @RELATION CALLS -> [AsyncSupersetClient]\n# @PRE env_id must exist.\n# @POST Returns image bytes or 202 when thumbnail is being prepared by Superset.\n@router.get(\"/{dashboard_ref}/thumbnail\")\nasync def get_dashboard_thumbnail(\n dashboard_ref: str,\n env_id: str,\n force: bool = Query(False),\n config_manager=Depends(get_config_manager),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboard_thumbnail\",\n f\"dashboard_ref={dashboard_ref}, env_id={env_id}, force={force}\",\n ):\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(\n f\"[get_dashboard_thumbnail][Coherence:Failed] Environment not found: {env_id}\"\n )\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n try:\n client = SupersetClient(env)\n dashboard_id = _resolve_dashboard_id_from_ref(dashboard_ref, client)\n digest = None\n thumb_endpoint = None\n\n try:\n screenshot_payload = client.network.request(\n method=\"POST\",\n endpoint=f\"/dashboard/{dashboard_id}/cache_dashboard_screenshot/\",\n json={\"force\": force},\n )\n payload = (\n screenshot_payload.get(\"result\", screenshot_payload)\n if isinstance(screenshot_payload, dict)\n else {}\n )\n image_url = (\n payload.get(\"image_url\", \"\") if isinstance(payload, dict) else \"\"\n )\n if isinstance(image_url, str) and image_url:\n matched = re.search(\n r\"/dashboard/\\d+/(?:thumbnail|screenshot)/([^/]+)/?$\",\n image_url,\n )\n if matched:\n digest = matched.group(1)\n except DashboardNotFoundError:\n logger.warning(\n \"[get_dashboard_thumbnail][Fallback] cache_dashboard_screenshot endpoint unavailable, fallback to dashboard.thumbnail_url\"\n )\n\n if not digest:\n dashboard_payload = client.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}\",\n )\n dashboard_data = (\n dashboard_payload.get(\"result\", dashboard_payload)\n if isinstance(dashboard_payload, dict)\n else {}\n )\n thumbnail_url = (\n dashboard_data.get(\"thumbnail_url\", \"\")\n if isinstance(dashboard_data, dict)\n else \"\"\n )\n if isinstance(thumbnail_url, str) and thumbnail_url:\n parsed = urlparse(thumbnail_url)\n parsed_path = parsed.path or thumbnail_url\n if parsed_path.startswith(\"/api/v1/\"):\n parsed_path = parsed_path[len(\"/api/v1\") :]\n thumb_endpoint = parsed_path\n matched = re.search(\n r\"/dashboard/\\d+/(?:thumbnail|screenshot)/([^/]+)/?$\",\n parsed_path,\n )\n if matched:\n digest = matched.group(1)\n\n if not thumb_endpoint:\n thumb_endpoint = (\n f\"/dashboard/{dashboard_id}/thumbnail/{digest or 'latest'}/\"\n )\n\n thumb_response = client.network.request(\n method=\"GET\",\n endpoint=thumb_endpoint,\n raw_response=True,\n allow_redirects=True,\n )\n\n if thumb_response.status_code == 202:\n payload_202: dict[str, Any] = {}\n try:\n payload_202 = thumb_response.json()\n except Exception:\n payload_202 = {\"message\": \"Thumbnail is being generated\"}\n return JSONResponse(status_code=202, content=payload_202)\n\n content_type = thumb_response.headers.get(\"Content-Type\", \"image/png\")\n return Response(content=thumb_response.content, media_type=content_type)\n except DashboardNotFoundError as e:\n logger.error(\n f\"[get_dashboard_thumbnail][Coherence:Failed] Dashboard not found for thumbnail: {e}\"\n )\n raise HTTPException(status_code=404, detail=\"Dashboard thumbnail not found\")\n except HTTPException:\n raise\n except Exception as e:\n logger.error(\n f\"[get_dashboard_thumbnail][Coherence:Failed] Failed to fetch dashboard thumbnail: {e}\"\n )\n raise HTTPException(\n status_code=503,\n detail=f\"Failed to fetch dashboard thumbnail: {e!s}\",\n )\n\n\n# #endregion get_dashboard_thumbnail\n# #endregion DashboardDetailRoutes\n"
},
{
"contract_id": "get_database_mappings",
@@ -7792,8 +7828,8 @@
{
"source_id": "DashboardListingRoutes",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:frontend:DashboardRouter]",
- "target_ref": "[[EXT:frontend:DashboardRouter]]"
+ "target_id": "EXT:frontend:DashboardRouter]",
+ "target_ref": "[EXT:frontend:DashboardRouter]]"
},
{
"source_id": "DashboardListingRoutes",
@@ -7817,7 +7853,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DashboardListingRoutes [C:4] [TYPE Module] [SEMANTICS fastapi, dashboard, api, search]\n# @BRIEF Dashboard listing route handler for Dashboard Hub.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [[EXT:frontend:DashboardRouter]]\n# @RELATION DEPENDS_ON -> [DashboardSchemas]\n# @RELATION DEPENDS_ON -> [DashboardHelpers]\n# @RELATION DEPENDS_ON -> [DashboardProjection]\n\nfrom typing import Any, Literal\n\nfrom fastapi import Depends, HTTPException, Query\nfrom sqlalchemy.orm import Session\n\nfrom src.core.database import get_db\nfrom src.core.logger import belief_scope, logger\nfrom src.dependencies import (\n get_config_manager,\n get_current_user,\n get_resource_service,\n get_task_manager,\n has_permission,\n)\nfrom src.models.auth import User\nfrom src.services.profile_service import ProfileService\n\nfrom ._helpers import _dashboard_git_filter_value, _normalize_filter_values\nfrom ._projection import (\n _get_profile_filter_binding,\n _matches_dashboard_actor_aliases,\n _project_dashboard_response_items,\n _resolve_profile_actor_aliases,\n)\nfrom ._router import router\nfrom ._schemas import DashboardsResponse, EffectiveProfileFilter\n\n\n# #region get_dashboards [C:3] [TYPE Function]\n# @BRIEF Fetch list of dashboards from a specific environment with Git status and last task status\n# @PRE env_id must be a valid environment ID\n# @PRE page must be >= 1 if provided\n# @PRE page_size must be between 1 and 100 if provided\n# @POST Returns a list of dashboards with enhanced metadata and pagination info\n# @POST Response includes pagination metadata (page, page_size, total, total_pages)\n# @POST Response includes effective profile filter metadata for main dashboards page context\n# @RELATION CALLS -> [EXT:method:get_dashboards_with_status]\n@router.get(\"\", response_model=DashboardsResponse)\nasync def get_dashboards(\n env_id: str,\n search: str | None = None,\n page: int = 1,\n page_size: int = 10,\n page_context: Literal[\"dashboards_main\", \"other\"] = Query(\"dashboards_main\"),\n apply_profile_default: bool = Query(default=True),\n override_show_all: bool = Query(default=False),\n filter_title: list[str] | None = Query(default=None),\n filter_git_status: list[str] | None = Query(default=None),\n filter_llm_status: list[str] | None = Query(default=None),\n filter_changed_on: list[str] | None = Query(default=None),\n filter_actor: list[str] | None = Query(default=None),\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n resource_service=Depends(get_resource_service),\n current_user: User = Depends(get_current_user),\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboards\",\n f\"env_id={env_id}, search={search}, page={page}, page_size={page_size}, \"\n f\"page_context={page_context}, applyp={apply_profile_default}, overhide={override_show_all}\",\n ):\n if page < 1:\n logger.error(f\"[get_dashboards][Coherence:Failed] Invalid page: {page}\")\n raise HTTPException(status_code=400, detail=\"Page must be >= 1\")\n if page_size < 1 or page_size > 100:\n logger.error(f\"[get_dashboards][Coherence:Failed] Invalid page_size: {page_size}\")\n raise HTTPException(status_code=400, detail=\"Page size must be between 1 and 100\")\n\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(f\"[get_dashboards][Coherence:Failed] Environment not found: {env_id}\")\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n bound_username: str | None = None\n can_apply_profile_filter = False\n can_apply_slug_filter = False\n effective_profile_filter = EffectiveProfileFilter(\n applied=False,\n source_page=page_context,\n override_show_all=bool(override_show_all),\n username=None,\n match_logic=None,\n )\n profile_service: ProfileService | None = None\n\n try:\n profile_service_module = getattr(ProfileService, \"__module__\", \"\")\n is_mock_db = db.__class__.__module__.startswith(\"unittest.mock\")\n use_profile_service = (not is_mock_db) or profile_service_module.startswith(\n \"unittest.mock\"\n )\n if use_profile_service:\n profile_service = ProfileService(db=db, config_manager=config_manager)\n profile_preference = _get_profile_filter_binding(\n profile_service, current_user\n )\n normalized_username = (\n str(profile_preference.get(\"superset_username_normalized\") or \"\")\n .strip()\n .lower()\n )\n raw_username = (\n str(profile_preference.get(\"superset_username\") or \"\")\n .strip()\n .lower()\n )\n bound_username = normalized_username or raw_username or None\n\n can_apply_profile_filter = (\n page_context == \"dashboards_main\"\n and bool(apply_profile_default)\n and not bool(override_show_all)\n and bool(profile_preference.get(\"show_only_my_dashboards\", False))\n and bool(bound_username)\n )\n can_apply_slug_filter = (\n page_context == \"dashboards_main\"\n and bool(apply_profile_default)\n and not bool(override_show_all)\n and bool(profile_preference.get(\"show_only_slug_dashboards\", True))\n )\n\n profile_match_logic = None\n if can_apply_profile_filter and can_apply_slug_filter:\n profile_match_logic = \"owners_or_modified_by+slug_only\"\n elif can_apply_profile_filter:\n profile_match_logic = \"owners_or_modified_by\"\n elif can_apply_slug_filter:\n profile_match_logic = \"slug_only\"\n\n effective_profile_filter = EffectiveProfileFilter(\n applied=bool(can_apply_profile_filter or can_apply_slug_filter),\n source_page=page_context,\n override_show_all=bool(override_show_all),\n username=bound_username if can_apply_profile_filter else None,\n match_logic=profile_match_logic,\n )\n except Exception as profile_error:\n logger.explore(\n f\"Profile preference unavailable; continuing without profile-default filter: {profile_error}\",\n extra={\"src\": \"get_dashboards\"},\n )\n\n try:\n all_tasks = task_manager.get_all_tasks()\n title_filters = _normalize_filter_values(filter_title)\n git_filters = _normalize_filter_values(filter_git_status)\n llm_filters = _normalize_filter_values(filter_llm_status)\n changed_on_filters = _normalize_filter_values(filter_changed_on)\n actor_filters = _normalize_filter_values(filter_actor)\n has_column_filters = any(\n (\n title_filters,\n git_filters,\n llm_filters,\n changed_on_filters,\n actor_filters,\n )\n )\n needs_full_scan = (\n has_column_filters\n or bool(can_apply_profile_filter)\n or bool(can_apply_slug_filter)\n )\n\n if not needs_full_scan:\n try:\n page_payload = (\n await resource_service.get_dashboards_page_with_status(\n env,\n all_tasks,\n page=page,\n page_size=page_size,\n search=search,\n include_git_status=False,\n require_slug=bool(can_apply_slug_filter),\n )\n )\n paginated_dashboards = page_payload[\"dashboards\"]\n total = page_payload[\"total\"]\n total_pages = page_payload[\"total_pages\"]\n except Exception as page_error:\n logger.reason(\n f\"Page-based fetch failed; using compatibility fallback: {page_error}\",\n extra={\"src\": \"get_dashboards\"},\n )\n if can_apply_slug_filter:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=False,\n require_slug=True,\n )\n else:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=False,\n )\n\n if search:\n search_lower = search.lower()\n dashboards = [\n d\n for d in dashboards\n if search_lower in d.get(\"title\", \"\").lower()\n or search_lower in d.get(\"slug\", \"\").lower()\n ]\n\n total = len(dashboards)\n total_pages = (\n (total + page_size - 1) // page_size if total > 0 else 1\n )\n start_idx = (page - 1) * page_size\n end_idx = start_idx + page_size\n paginated_dashboards = dashboards[start_idx:end_idx]\n else:\n if can_apply_slug_filter:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=bool(git_filters),\n require_slug=True,\n )\n else:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=bool(git_filters),\n )\n\n if (\n can_apply_profile_filter\n and bound_username\n and profile_service is not None\n ):\n actor_aliases = _resolve_profile_actor_aliases(env, bound_username)\n if not actor_aliases:\n actor_aliases = [bound_username]\n logger.reason(\n \"Applying profile actor filter\",\n extra={\"src\": \"get_dashboards\", \"payload\": {\"env\": env_id, \"bound_username\": bound_username, \"actor_aliases\": actor_aliases, \"dashboards_before\": len(dashboards)}},\n )\n filtered_dashboards: list[dict[str, Any]] = []\n max_actor_samples = 15\n for index, dashboard in enumerate(dashboards):\n owners_value = dashboard.get(\"owners\")\n created_by_value = dashboard.get(\"created_by\")\n modified_by_value = dashboard.get(\"modified_by\")\n matches_actor = _matches_dashboard_actor_aliases(\n profile_service=profile_service,\n actor_aliases=actor_aliases,\n owners=owners_value,\n modified_by=modified_by_value,\n )\n if index < max_actor_samples:\n logger.reflect(\n \"Profile actor filter sample\",\n extra={\"src\": \"get_dashboards\", \"payload\": {\"env\": env_id, \"dashboard_id\": dashboard.get('id'), \"bound_username\": bound_username, \"actor_aliases\": actor_aliases, \"owners\": owners_value, \"created_by\": created_by_value, \"modified_by\": modified_by_value, \"matches\": matches_actor}},\n )\n if matches_actor:\n filtered_dashboards.append(dashboard)\n\n logger.reflect(\n \"Profile actor filter summary\",\n extra={\"src\": \"get_dashboards\", \"payload\": {\"env\": env_id, \"bound_username\": bound_username, \"dashboards_before\": len(dashboards), \"dashboards_after\": len(filtered_dashboards)}},\n )\n dashboards = filtered_dashboards\n\n if can_apply_slug_filter:\n dashboards = [\n dashboard\n for dashboard in dashboards\n if str(dashboard.get(\"slug\") or \"\").strip()\n ]\n\n if search:\n search_lower = search.lower()\n dashboards = [\n d\n for d in dashboards\n if search_lower in d.get(\"title\", \"\").lower()\n or search_lower in d.get(\"slug\", \"\").lower()\n ]\n\n def _matches_dashboard_filters(dashboard: dict[str, Any]) -> bool:\n title_value = str(dashboard.get(\"title\") or \"\").strip().lower()\n if title_filters and title_value not in title_filters:\n return False\n\n if git_filters:\n git_value = _dashboard_git_filter_value(dashboard)\n if git_value not in git_filters:\n return False\n\n llm_value = (\n str(\n (\n (dashboard.get(\"last_task\") or {}).get(\n \"validation_status\"\n )\n )\n or \"UNKNOWN\"\n )\n .strip()\n .lower()\n )\n if llm_filters and llm_value not in llm_filters:\n return False\n\n changed_on_raw = (\n str(dashboard.get(\"last_modified\") or \"\").strip().lower()\n )\n changed_on_prefix = (\n changed_on_raw[:10]\n if len(changed_on_raw) >= 10\n else changed_on_raw\n )\n if (\n changed_on_filters\n and changed_on_raw not in changed_on_filters\n and changed_on_prefix not in changed_on_filters\n ):\n return False\n\n owners = dashboard.get(\"owners\") or []\n if isinstance(owners, list):\n actor_value = \", \".join(\n str(item).strip() for item in owners if str(item).strip()\n ).lower()\n else:\n actor_value = str(owners).strip().lower()\n if not actor_value:\n actor_value = \"-\"\n if actor_filters and actor_value not in actor_filters:\n return False\n return True\n\n if has_column_filters:\n dashboards = [\n d for d in dashboards if _matches_dashboard_filters(d)\n ]\n\n total = len(dashboards)\n total_pages = (total + page_size - 1) // page_size if total > 0 else 1\n start_idx = (page - 1) * page_size\n end_idx = start_idx + page_size\n paginated_dashboards = dashboards[start_idx:end_idx]\n\n logger.info(\n f\"[get_dashboards][Coherence:OK] Returning {len(paginated_dashboards)} dashboards \"\n f\"(page {page}/{total_pages}, total: {total}, profile_filter_applied={effective_profile_filter.applied})\"\n )\n\n response_dashboards = _project_dashboard_response_items(\n paginated_dashboards\n )\n\n return DashboardsResponse(\n dashboards=response_dashboards,\n total=total,\n page=page,\n page_size=page_size,\n total_pages=total_pages,\n effective_profile_filter=effective_profile_filter,\n )\n\n except HTTPException:\n raise\n except Exception as e:\n logger.error(\n f\"[get_dashboards][Coherence:Failed] Failed to fetch dashboards: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to fetch dashboards: {e!s}\"\n )\n\n\n# #endregion get_dashboards\n# #endregion DashboardListingRoutes\n"
+ "body": "# #region DashboardListingRoutes [C:4] [TYPE Module] [SEMANTICS fastapi, dashboard, api, search]\n# @BRIEF Dashboard listing route handler for Dashboard Hub.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]\n# @RELATION DEPENDS_ON -> [DashboardSchemas]\n# @RELATION DEPENDS_ON -> [DashboardHelpers]\n# @RELATION DEPENDS_ON -> [DashboardProjection]\n\nfrom typing import Any, Literal\n\nfrom fastapi import Depends, HTTPException, Query\nfrom sqlalchemy.orm import Session\n\nfrom src.core.database import get_db\nfrom src.core.logger import belief_scope, logger\nfrom src.dependencies import (\n get_config_manager,\n get_current_user,\n get_resource_service,\n get_task_manager,\n has_permission,\n)\nfrom src.models.auth import User\nfrom src.services.profile_service import ProfileService\n\nfrom ._helpers import _dashboard_git_filter_value, _normalize_filter_values\nfrom ._projection import (\n _get_profile_filter_binding,\n _matches_dashboard_actor_aliases,\n _project_dashboard_response_items,\n _resolve_profile_actor_aliases,\n)\nfrom ._router import router\nfrom ._schemas import DashboardsResponse, EffectiveProfileFilter\n\n\n# #region get_dashboards [C:3] [TYPE Function]\n# @BRIEF Fetch list of dashboards from a specific environment with Git status and last task status\n# @PRE env_id must be a valid environment ID\n# @PRE page must be >= 1 if provided\n# @PRE page_size must be between 1 and 100 if provided\n# @POST Returns a list of dashboards with enhanced metadata and pagination info\n# @POST Response includes pagination metadata (page, page_size, total, total_pages)\n# @POST Response includes effective profile filter metadata for main dashboards page context\n# @RELATION CALLS -> [EXT:method:get_dashboards_with_status]\n@router.get(\"\", response_model=DashboardsResponse)\nasync def get_dashboards(\n env_id: str,\n search: str | None = None,\n page: int = 1,\n page_size: int = 10,\n page_context: Literal[\"dashboards_main\", \"other\"] = Query(\"dashboards_main\"),\n apply_profile_default: bool = Query(default=True),\n override_show_all: bool = Query(default=False),\n filter_title: list[str] | None = Query(default=None),\n filter_git_status: list[str] | None = Query(default=None),\n filter_llm_status: list[str] | None = Query(default=None),\n filter_changed_on: list[str] | None = Query(default=None),\n filter_actor: list[str] | None = Query(default=None),\n config_manager=Depends(get_config_manager),\n task_manager=Depends(get_task_manager),\n resource_service=Depends(get_resource_service),\n current_user: User = Depends(get_current_user),\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"plugin:migration\", \"READ\")),\n):\n with belief_scope(\n \"get_dashboards\",\n f\"env_id={env_id}, search={search}, page={page}, page_size={page_size}, \"\n f\"page_context={page_context}, applyp={apply_profile_default}, overhide={override_show_all}\",\n ):\n if page < 1:\n logger.error(f\"[get_dashboards][Coherence:Failed] Invalid page: {page}\")\n raise HTTPException(status_code=400, detail=\"Page must be >= 1\")\n if page_size < 1 or page_size > 100:\n logger.error(f\"[get_dashboards][Coherence:Failed] Invalid page_size: {page_size}\")\n raise HTTPException(status_code=400, detail=\"Page size must be between 1 and 100\")\n\n environments = config_manager.get_environments()\n env = next((e for e in environments if e.id == env_id), None)\n if not env:\n logger.error(f\"[get_dashboards][Coherence:Failed] Environment not found: {env_id}\")\n raise HTTPException(status_code=404, detail=\"Environment not found\")\n\n bound_username: str | None = None\n can_apply_profile_filter = False\n can_apply_slug_filter = False\n effective_profile_filter = EffectiveProfileFilter(\n applied=False,\n source_page=page_context,\n override_show_all=bool(override_show_all),\n username=None,\n match_logic=None,\n )\n profile_service: ProfileService | None = None\n\n try:\n profile_service_module = getattr(ProfileService, \"__module__\", \"\")\n is_mock_db = db.__class__.__module__.startswith(\"unittest.mock\")\n use_profile_service = (not is_mock_db) or profile_service_module.startswith(\n \"unittest.mock\"\n )\n if use_profile_service:\n profile_service = ProfileService(db=db, config_manager=config_manager)\n profile_preference = _get_profile_filter_binding(\n profile_service, current_user\n )\n normalized_username = (\n str(profile_preference.get(\"superset_username_normalized\") or \"\")\n .strip()\n .lower()\n )\n raw_username = (\n str(profile_preference.get(\"superset_username\") or \"\")\n .strip()\n .lower()\n )\n bound_username = normalized_username or raw_username or None\n\n can_apply_profile_filter = (\n page_context == \"dashboards_main\"\n and bool(apply_profile_default)\n and not bool(override_show_all)\n and bool(profile_preference.get(\"show_only_my_dashboards\", False))\n and bool(bound_username)\n )\n can_apply_slug_filter = (\n page_context == \"dashboards_main\"\n and bool(apply_profile_default)\n and not bool(override_show_all)\n and bool(profile_preference.get(\"show_only_slug_dashboards\", True))\n )\n\n profile_match_logic = None\n if can_apply_profile_filter and can_apply_slug_filter:\n profile_match_logic = \"owners_or_modified_by+slug_only\"\n elif can_apply_profile_filter:\n profile_match_logic = \"owners_or_modified_by\"\n elif can_apply_slug_filter:\n profile_match_logic = \"slug_only\"\n\n effective_profile_filter = EffectiveProfileFilter(\n applied=bool(can_apply_profile_filter or can_apply_slug_filter),\n source_page=page_context,\n override_show_all=bool(override_show_all),\n username=bound_username if can_apply_profile_filter else None,\n match_logic=profile_match_logic,\n )\n except Exception as profile_error:\n logger.explore(\n f\"Profile preference unavailable; continuing without profile-default filter: {profile_error}\",\n extra={\"src\": \"get_dashboards\"},\n )\n\n try:\n all_tasks = task_manager.get_all_tasks()\n title_filters = _normalize_filter_values(filter_title)\n git_filters = _normalize_filter_values(filter_git_status)\n llm_filters = _normalize_filter_values(filter_llm_status)\n changed_on_filters = _normalize_filter_values(filter_changed_on)\n actor_filters = _normalize_filter_values(filter_actor)\n has_column_filters = any(\n (\n title_filters,\n git_filters,\n llm_filters,\n changed_on_filters,\n actor_filters,\n )\n )\n needs_full_scan = (\n has_column_filters\n or bool(can_apply_profile_filter)\n or bool(can_apply_slug_filter)\n )\n\n if not needs_full_scan:\n try:\n page_payload = (\n await resource_service.get_dashboards_page_with_status(\n env,\n all_tasks,\n page=page,\n page_size=page_size,\n search=search,\n include_git_status=False,\n require_slug=bool(can_apply_slug_filter),\n )\n )\n paginated_dashboards = page_payload[\"dashboards\"]\n total = page_payload[\"total\"]\n total_pages = page_payload[\"total_pages\"]\n except Exception as page_error:\n logger.reason(\n f\"Page-based fetch failed; using compatibility fallback: {page_error}\",\n extra={\"src\": \"get_dashboards\"},\n )\n if can_apply_slug_filter:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=False,\n require_slug=True,\n )\n else:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=False,\n )\n\n if search:\n search_lower = search.lower()\n dashboards = [\n d\n for d in dashboards\n if search_lower in d.get(\"title\", \"\").lower()\n or search_lower in d.get(\"slug\", \"\").lower()\n ]\n\n total = len(dashboards)\n total_pages = (\n (total + page_size - 1) // page_size if total > 0 else 1\n )\n start_idx = (page - 1) * page_size\n end_idx = start_idx + page_size\n paginated_dashboards = dashboards[start_idx:end_idx]\n else:\n if can_apply_slug_filter:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=bool(git_filters),\n require_slug=True,\n )\n else:\n dashboards = await resource_service.get_dashboards_with_status(\n env,\n all_tasks,\n include_git_status=bool(git_filters),\n )\n\n if (\n can_apply_profile_filter\n and bound_username\n and profile_service is not None\n ):\n actor_aliases = _resolve_profile_actor_aliases(env, bound_username)\n if not actor_aliases:\n actor_aliases = [bound_username]\n logger.reason(\n \"Applying profile actor filter\",\n extra={\"src\": \"get_dashboards\", \"payload\": {\"env\": env_id, \"bound_username\": bound_username, \"actor_aliases\": actor_aliases, \"dashboards_before\": len(dashboards)}},\n )\n filtered_dashboards: list[dict[str, Any]] = []\n max_actor_samples = 15\n for index, dashboard in enumerate(dashboards):\n owners_value = dashboard.get(\"owners\")\n created_by_value = dashboard.get(\"created_by\")\n modified_by_value = dashboard.get(\"modified_by\")\n matches_actor = _matches_dashboard_actor_aliases(\n profile_service=profile_service,\n actor_aliases=actor_aliases,\n owners=owners_value,\n modified_by=modified_by_value,\n )\n if index < max_actor_samples:\n logger.reflect(\n \"Profile actor filter sample\",\n extra={\"src\": \"get_dashboards\", \"payload\": {\"env\": env_id, \"dashboard_id\": dashboard.get('id'), \"bound_username\": bound_username, \"actor_aliases\": actor_aliases, \"owners\": owners_value, \"created_by\": created_by_value, \"modified_by\": modified_by_value, \"matches\": matches_actor}},\n )\n if matches_actor:\n filtered_dashboards.append(dashboard)\n\n logger.reflect(\n \"Profile actor filter summary\",\n extra={\"src\": \"get_dashboards\", \"payload\": {\"env\": env_id, \"bound_username\": bound_username, \"dashboards_before\": len(dashboards), \"dashboards_after\": len(filtered_dashboards)}},\n )\n dashboards = filtered_dashboards\n\n if can_apply_slug_filter:\n dashboards = [\n dashboard\n for dashboard in dashboards\n if str(dashboard.get(\"slug\") or \"\").strip()\n ]\n\n if search:\n search_lower = search.lower()\n dashboards = [\n d\n for d in dashboards\n if search_lower in d.get(\"title\", \"\").lower()\n or search_lower in d.get(\"slug\", \"\").lower()\n ]\n\n def _matches_dashboard_filters(dashboard: dict[str, Any]) -> bool:\n title_value = str(dashboard.get(\"title\") or \"\").strip().lower()\n if title_filters and title_value not in title_filters:\n return False\n\n if git_filters:\n git_value = _dashboard_git_filter_value(dashboard)\n if git_value not in git_filters:\n return False\n\n llm_value = (\n str(\n (\n (dashboard.get(\"last_task\") or {}).get(\n \"validation_status\"\n )\n )\n or \"UNKNOWN\"\n )\n .strip()\n .lower()\n )\n if llm_filters and llm_value not in llm_filters:\n return False\n\n changed_on_raw = (\n str(dashboard.get(\"last_modified\") or \"\").strip().lower()\n )\n changed_on_prefix = (\n changed_on_raw[:10]\n if len(changed_on_raw) >= 10\n else changed_on_raw\n )\n if (\n changed_on_filters\n and changed_on_raw not in changed_on_filters\n and changed_on_prefix not in changed_on_filters\n ):\n return False\n\n owners = dashboard.get(\"owners\") or []\n if isinstance(owners, list):\n actor_value = \", \".join(\n str(item).strip() for item in owners if str(item).strip()\n ).lower()\n else:\n actor_value = str(owners).strip().lower()\n if not actor_value:\n actor_value = \"-\"\n if actor_filters and actor_value not in actor_filters:\n return False\n return True\n\n if has_column_filters:\n dashboards = [\n d for d in dashboards if _matches_dashboard_filters(d)\n ]\n\n total = len(dashboards)\n total_pages = (total + page_size - 1) // page_size if total > 0 else 1\n start_idx = (page - 1) * page_size\n end_idx = start_idx + page_size\n paginated_dashboards = dashboards[start_idx:end_idx]\n\n logger.info(\n f\"[get_dashboards][Coherence:OK] Returning {len(paginated_dashboards)} dashboards \"\n f\"(page {page}/{total_pages}, total: {total}, profile_filter_applied={effective_profile_filter.applied})\"\n )\n\n response_dashboards = _project_dashboard_response_items(\n paginated_dashboards\n )\n\n return DashboardsResponse(\n dashboards=response_dashboards,\n total=total,\n page=page,\n page_size=page_size,\n total_pages=total_pages,\n effective_profile_filter=effective_profile_filter,\n )\n\n except HTTPException:\n raise\n except Exception as e:\n logger.error(\n f\"[get_dashboards][Coherence:Failed] Failed to fetch dashboards: {e}\"\n )\n raise HTTPException(\n status_code=503, detail=f\"Failed to fetch dashboards: {e!s}\"\n )\n\n\n# #endregion get_dashboards\n# #endregion DashboardListingRoutes\n"
},
{
"contract_id": "get_dashboards",
@@ -10375,14 +10411,14 @@
{
"source_id": "GitPackage",
"relation_type": "CALLS",
- "target_id": "[EXT:list:GitPackage_all_routes]",
- "target_ref": "[[EXT:list:GitPackage_all_routes]]"
+ "target_id": "GitPackage",
+ "target_ref": "[GitPackage]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region GitPackage [C:5] [TYPE Module] [SEMANTICS git, api, package, sync]\n# @BRIEF Package root for decomposed git routes. Re-exports all public symbols from submodules.\n# @LAYER API\n# @RELATION CALLS -> [[EXT:list:GitPackage_all_routes]]\n# @INVARIANT git_service and os are module-level attributes for test monkeypatch compatibility.\n# @PRE Git service initialized\n# @POST Git API package exported\n# @SIDE_EFFECT Registers git route submodules\n# @DATA_CONTRACT GitRequest -> GitResponse\n# All route functions are re-exported for direct access via `from src.api.routes import git`.\n\nimport os\n\nfrom src.services.git_service import GitService\n\nfrom ._deps import MAX_REPOSITORY_STATUS_BATCH\nfrom ._router import router\n\n# -- git_service singleton (canonical instance; tests may monkeypatch git_routes.git_service) --\ngit_service = GitService()\n\n# -- Config routes --\nfrom ._config_routes import create_git_config, delete_git_config, get_git_configs, test_git_config, update_git_config # noqa: F401\n\n# -- Environment routes --\nfrom ._environment_routes import get_environments # noqa: F401\n\n# -- Gitea routes --\nfrom ._gitea_routes import create_gitea_repository, create_remote_repository, delete_gitea_repository, list_gitea_repositories # noqa: F401\nfrom ._helpers import _resolve_dashboard_id_from_ref, _resolve_dashboard_id_from_ref_async, _resolve_repo_key_from_ref # noqa: F401 — re-exported for test monkeypatch compatibility\n\n# -- Merge routes --\nfrom ._merge_routes import abort_merge, continue_merge, get_merge_conflicts, get_merge_status, resolve_merge_conflicts # noqa: F401\n\n# -- Repo lifecycle routes (sync, promote, deploy) --\nfrom ._repo_lifecycle_routes import deploy_dashboard, promote_dashboard, sync_dashboard # noqa: F401\n\n# -- Repo operations routes (commit, push, pull, status, diff, history, generate-message) --\nfrom ._repo_operations_routes import commit_changes, generate_commit_message, get_history, get_repository_diff, get_repository_status, get_repository_status_batch, pull_changes, push_changes # noqa: F401\n\n# -- Repo routes (core) --\nfrom ._repo_routes import checkout_branch, create_branch, delete_repository, get_branches, get_repository_binding, init_repository # noqa: F401\n\n# #endregion GitPackage\n"
+ "body": "# #region GitPackage [C:5] [TYPE Module] [SEMANTICS git, api, package, sync]\n# @BRIEF Package root for decomposed git routes. Re-exports all public symbols from submodules.\n# @LAYER API\n# @RELATION CALLS -> [GitPackage]\n# @INVARIANT git_service and os are module-level attributes for test monkeypatch compatibility.\n# @PRE Git service initialized\n# @POST Git API package exported\n# @SIDE_EFFECT Registers git route submodules\n# @DATA_CONTRACT GitRequest -> GitResponse\n# All route functions are re-exported for direct access via `from src.api.routes import git`.\n\nimport os\n\nfrom src.services.git_service import GitService\n\nfrom ._deps import MAX_REPOSITORY_STATUS_BATCH\nfrom ._router import router\n\n# -- git_service singleton (canonical instance; tests may monkeypatch git_routes.git_service) --\ngit_service = GitService()\n\n# -- Config routes --\nfrom ._config_routes import create_git_config, delete_git_config, get_git_configs, test_git_config, update_git_config # noqa: F401\n\n# -- Environment routes --\nfrom ._environment_routes import get_environments # noqa: F401\n\n# -- Gitea routes --\nfrom ._gitea_routes import create_gitea_repository, create_remote_repository, delete_gitea_repository, list_gitea_repositories # noqa: F401\nfrom ._helpers import _resolve_dashboard_id_from_ref, _resolve_dashboard_id_from_ref_async, _resolve_repo_key_from_ref # noqa: F401 — re-exported for test monkeypatch compatibility\n\n# -- Merge routes --\nfrom ._merge_routes import abort_merge, continue_merge, get_merge_conflicts, get_merge_status, resolve_merge_conflicts # noqa: F401\n\n# -- Repo lifecycle routes (sync, promote, deploy) --\nfrom ._repo_lifecycle_routes import deploy_dashboard, promote_dashboard, sync_dashboard # noqa: F401\n\n# -- Repo operations routes (commit, push, pull, status, diff, history, generate-message) --\nfrom ._repo_operations_routes import commit_changes, generate_commit_message, get_history, get_repository_diff, get_repository_status, get_repository_status_batch, pull_changes, push_changes # noqa: F401\n\n# -- Repo routes (core) --\nfrom ._repo_routes import checkout_branch, create_branch, delete_repository, get_branches, get_repository_binding, init_repository # noqa: F401\n\n# #endregion GitPackage\n"
},
{
"contract_id": "GitConfigRoutes",
@@ -11357,14 +11393,14 @@
{
"source_id": "GitSchemas",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:backend.src.models.git",
- "target_ref": "[EXT:path:backend.src.models.git]"
+ "target_id": "GitModels",
+ "target_ref": "[GitModels]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region GitSchemas [C:1] [TYPE Module] [SEMANTICS fastapi, git, api, git-server-config-base]\n#\n# @BRIEF Defines Pydantic models for the Git integration API layer.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [EXT:path:backend.src.models.git]\n#\n# @INVARIANT All schemas must be compatible with the FastAPI router.\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom pydantic import BaseModel, Field\n\nfrom src.models.git import GitProvider, GitStatus, SyncStatus\n\n\n# #region GitServerConfigBase [C:1] [TYPE Class]\n# @BRIEF Base schema for Git server configuration attributes.\nclass GitServerConfigBase(BaseModel):\n name: str = Field(..., description=\"Display name for the Git server\")\n provider: GitProvider = Field(..., description=\"Git provider (GITHUB, GITLAB, GITEA)\")\n url: str = Field(..., description=\"Server base URL\")\n pat: str = Field(..., description=\"Personal Access Token\")\n pat: str = Field(..., description=\"Personal Access Token\")\n default_repository: str | None = Field(None, description=\"Default repository path (org/repo)\")\n default_branch: str | None = Field(\"main\", description=\"Default branch logic/name\")\n# #endregion GitServerConfigBase\n\n# #region GitServerConfigUpdate [TYPE Class]\n# @BRIEF Schema for updating an existing Git server configuration.\nclass GitServerConfigUpdate(BaseModel):\n name: str | None = Field(None, description=\"Display name for the Git server\")\n provider: GitProvider | None = Field(None, description=\"Git provider (GITHUB, GITLAB, GITEA)\")\n url: str | None = Field(None, description=\"Server base URL\")\n pat: str | None = Field(None, description=\"Personal Access Token\")\n default_repository: str | None = Field(None, description=\"Default repository path (org/repo)\")\n default_branch: str | None = Field(None, description=\"Default branch logic/name\")\n# #endregion GitServerConfigUpdate\n\n# #region GitServerConfigCreate [TYPE Class]\n# @BRIEF Schema for creating a new Git server configuration.\nclass GitServerConfigCreate(GitServerConfigBase):\n \"\"\"Schema for creating a new Git server configuration.\"\"\"\n config_id: str | None = Field(None, description=\"Optional config ID, useful for testing an existing config without sending its full PAT\")\n# #endregion GitServerConfigCreate\n\n# #region GitServerConfigSchema [TYPE Class]\n# @BRIEF Schema for representing a Git server configuration with metadata.\nclass GitServerConfigSchema(GitServerConfigBase):\n \"\"\"Schema for representing a Git server configuration with metadata.\"\"\"\n id: str\n status: GitStatus\n last_validated: datetime\n\n class Config:\n from_attributes = True\n# #endregion GitServerConfigSchema\n\n# #region GitRepositorySchema [TYPE Class]\n# @BRIEF Schema for tracking a local Git repository linked to a dashboard.\nclass GitRepositorySchema(BaseModel):\n \"\"\"Schema for tracking a local Git repository linked to a dashboard.\"\"\"\n id: str\n dashboard_id: int\n config_id: str\n remote_url: str\n local_path: str\n current_branch: str\n sync_status: SyncStatus\n\n class Config:\n from_attributes = True\n# #endregion GitRepositorySchema\n\n# #region BranchSchema [TYPE Class]\n# @BRIEF Schema for representing a Git branch metadata.\nclass BranchSchema(BaseModel):\n \"\"\"Schema for representing a Git branch.\"\"\"\n name: str\n commit_hash: str\n is_remote: bool\n last_updated: datetime\n# #endregion BranchSchema\n\n# #region CommitSchema [TYPE Class]\n# @BRIEF Schema for representing Git commit details.\nclass CommitSchema(BaseModel):\n \"\"\"Schema for representing a Git commit.\"\"\"\n hash: str\n author: str\n email: str\n timestamp: datetime\n message: str\n files_changed: list[str]\n# #endregion CommitSchema\n\n# #region BranchCreate [TYPE Class]\n# @BRIEF Schema for branch creation requests.\nclass BranchCreate(BaseModel):\n \"\"\"Schema for branch creation requests.\"\"\"\n name: str\n from_branch: str\n# #endregion BranchCreate\n\n# #region BranchCheckout [TYPE Class]\n# @BRIEF Schema for branch checkout requests.\nclass BranchCheckout(BaseModel):\n \"\"\"Schema for branch checkout requests.\"\"\"\n name: str\n# #endregion BranchCheckout\n\n# #region CommitCreate [TYPE Class]\n# @BRIEF Schema for staging and committing changes.\nclass CommitCreate(BaseModel):\n \"\"\"Schema for staging and committing changes.\"\"\"\n message: str\n files: list[str]\n# #endregion CommitCreate\n\n# #region ConflictResolution [TYPE Class]\n# @BRIEF Schema for resolving merge conflicts.\nclass ConflictResolution(BaseModel):\n \"\"\"Schema for resolving merge conflicts.\"\"\"\n file_path: str\n resolution: str = Field(pattern=\"^(mine|theirs|manual)$\")\n content: str | None = None\n# #endregion ConflictResolution\n\n\n# #region MergeStatusSchema [TYPE Class]\n# @BRIEF Schema representing unfinished merge status for repository.\nclass MergeStatusSchema(BaseModel):\n has_unfinished_merge: bool\n repository_path: str\n git_dir: str\n current_branch: str\n merge_head: str | None = None\n merge_message_preview: str | None = None\n conflicts_count: int = 0\n# #endregion MergeStatusSchema\n\n\n# #region MergeConflictFileSchema [TYPE Class]\n# @BRIEF Schema describing one conflicted file with optional side snapshots.\nclass MergeConflictFileSchema(BaseModel):\n file_path: str\n mine: str | None = None\n theirs: str | None = None\n# #endregion MergeConflictFileSchema\n\n\n# #region MergeResolveRequest [TYPE Class]\n# @BRIEF Request schema for resolving one or multiple merge conflicts.\nclass MergeResolveRequest(BaseModel):\n resolutions: list[ConflictResolution] = Field(default_factory=list)\n# #endregion MergeResolveRequest\n\n\n# #region MergeContinueRequest [TYPE Class]\n# @BRIEF Request schema for finishing merge with optional explicit commit message.\nclass MergeContinueRequest(BaseModel):\n message: str | None = None\n# #endregion MergeContinueRequest\n\n# #region DeploymentEnvironmentSchema [TYPE Class]\n# @BRIEF Schema for representing a target deployment environment.\nclass DeploymentEnvironmentSchema(BaseModel):\n \"\"\"Schema for representing a target deployment environment.\"\"\"\n id: str\n name: str\n superset_url: str\n is_active: bool\n\n class Config:\n from_attributes = True\n# #endregion DeploymentEnvironmentSchema\n\n# #region DeployRequest [TYPE Class]\n# @BRIEF Schema for dashboard deployment requests.\nclass DeployRequest(BaseModel):\n \"\"\"Schema for deployment requests.\"\"\"\n environment_id: str\n# #endregion DeployRequest\n\n# #region RepoInitRequest [TYPE Class]\n# @BRIEF Schema for repository initialization requests.\nclass RepoInitRequest(BaseModel):\n \"\"\"Schema for repository initialization requests.\"\"\"\n config_id: str\n remote_url: str\n# #endregion RepoInitRequest\n\n\n# #region RepositoryBindingSchema [TYPE Class]\n# @BRIEF Schema describing repository-to-config binding and provider metadata.\nclass RepositoryBindingSchema(BaseModel):\n dashboard_id: int\n config_id: str\n provider: GitProvider\n remote_url: str\n local_path: str\n# #endregion RepositoryBindingSchema\n\n# #region RepoStatusBatchRequest [TYPE Class]\n# @BRIEF Schema for requesting repository statuses for multiple dashboards in a single call.\nclass RepoStatusBatchRequest(BaseModel):\n dashboard_ids: list[int] = Field(default_factory=list, description=\"Dashboard IDs to resolve repository statuses for\")\n# #endregion RepoStatusBatchRequest\n\n\n# #region RepoStatusBatchResponse [TYPE Class]\n# @BRIEF Schema for returning repository statuses keyed by dashboard ID.\nclass RepoStatusBatchResponse(BaseModel):\n statuses: dict[str, dict[str, Any]]\n# #endregion RepoStatusBatchResponse\n\n\n# #region GiteaRepoSchema [TYPE Class]\n# @BRIEF Schema describing a Gitea repository.\nclass GiteaRepoSchema(BaseModel):\n name: str\n full_name: str\n private: bool = False\n clone_url: str | None = None\n html_url: str | None = None\n ssh_url: str | None = None\n default_branch: str | None = None\n# #endregion GiteaRepoSchema\n\n\n# #region GiteaRepoCreateRequest [TYPE Class]\n# @BRIEF Request schema for creating a Gitea repository.\nclass GiteaRepoCreateRequest(BaseModel):\n name: str = Field(..., min_length=1, max_length=255)\n private: bool = True\n description: str | None = None\n auto_init: bool = True\n default_branch: str | None = \"main\"\n# #endregion GiteaRepoCreateRequest\n\n\n# #region RemoteRepoSchema [TYPE Class]\n# @BRIEF Provider-agnostic remote repository payload.\nclass RemoteRepoSchema(BaseModel):\n provider: GitProvider\n name: str\n full_name: str\n private: bool = False\n clone_url: str | None = None\n html_url: str | None = None\n ssh_url: str | None = None\n default_branch: str | None = None\n# #endregion RemoteRepoSchema\n\n\n# #region RemoteRepoCreateRequest [TYPE Class]\n# @BRIEF Provider-agnostic repository creation request.\nclass RemoteRepoCreateRequest(BaseModel):\n name: str = Field(..., min_length=1, max_length=255)\n private: bool = True\n description: str | None = None\n auto_init: bool = True\n default_branch: str | None = \"main\"\n# #endregion RemoteRepoCreateRequest\n\n\n# #region PromoteRequest [TYPE Class]\n# @BRIEF Request schema for branch promotion workflow.\nclass PromoteRequest(BaseModel):\n from_branch: str = Field(..., min_length=1, max_length=255)\n to_branch: str = Field(..., min_length=1, max_length=255)\n mode: str = Field(default=\"mr\", pattern=\"^(mr|direct)$\")\n title: str | None = None\n description: str | None = None\n reason: str | None = None\n draft: bool = False\n remove_source_branch: bool = False\n# #endregion PromoteRequest\n\n\n# #region PromoteResponse [TYPE Class]\n# @BRIEF Response schema for promotion operation result.\nclass PromoteResponse(BaseModel):\n mode: str\n from_branch: str\n to_branch: str\n status: str\n url: str | None = None\n reference_id: str | None = None\n policy_violation: bool = False\n# #endregion PromoteResponse\n\n# #endregion GitSchemas\n"
+ "body": "# #region GitSchemas [C:1] [TYPE Module] [SEMANTICS fastapi, git, api, git-server-config-base]\n#\n# @BRIEF Defines Pydantic models for the Git integration API layer.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [GitModels]\n#\n# @INVARIANT All schemas must be compatible with the FastAPI router.\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom pydantic import BaseModel, Field\n\nfrom src.models.git import GitProvider, GitStatus, SyncStatus\n\n\n# #region GitServerConfigBase [C:1] [TYPE Class]\n# @BRIEF Base schema for Git server configuration attributes.\nclass GitServerConfigBase(BaseModel):\n name: str = Field(..., description=\"Display name for the Git server\")\n provider: GitProvider = Field(..., description=\"Git provider (GITHUB, GITLAB, GITEA)\")\n url: str = Field(..., description=\"Server base URL\")\n pat: str = Field(..., description=\"Personal Access Token\")\n pat: str = Field(..., description=\"Personal Access Token\")\n default_repository: str | None = Field(None, description=\"Default repository path (org/repo)\")\n default_branch: str | None = Field(\"main\", description=\"Default branch logic/name\")\n# #endregion GitServerConfigBase\n\n# #region GitServerConfigUpdate [TYPE Class]\n# @BRIEF Schema for updating an existing Git server configuration.\nclass GitServerConfigUpdate(BaseModel):\n name: str | None = Field(None, description=\"Display name for the Git server\")\n provider: GitProvider | None = Field(None, description=\"Git provider (GITHUB, GITLAB, GITEA)\")\n url: str | None = Field(None, description=\"Server base URL\")\n pat: str | None = Field(None, description=\"Personal Access Token\")\n default_repository: str | None = Field(None, description=\"Default repository path (org/repo)\")\n default_branch: str | None = Field(None, description=\"Default branch logic/name\")\n# #endregion GitServerConfigUpdate\n\n# #region GitServerConfigCreate [TYPE Class]\n# @BRIEF Schema for creating a new Git server configuration.\nclass GitServerConfigCreate(GitServerConfigBase):\n \"\"\"Schema for creating a new Git server configuration.\"\"\"\n config_id: str | None = Field(None, description=\"Optional config ID, useful for testing an existing config without sending its full PAT\")\n# #endregion GitServerConfigCreate\n\n# #region GitServerConfigSchema [TYPE Class]\n# @BRIEF Schema for representing a Git server configuration with metadata.\nclass GitServerConfigSchema(GitServerConfigBase):\n \"\"\"Schema for representing a Git server configuration with metadata.\"\"\"\n id: str\n status: GitStatus\n last_validated: datetime\n\n class Config:\n from_attributes = True\n# #endregion GitServerConfigSchema\n\n# #region GitRepositorySchema [TYPE Class]\n# @BRIEF Schema for tracking a local Git repository linked to a dashboard.\nclass GitRepositorySchema(BaseModel):\n \"\"\"Schema for tracking a local Git repository linked to a dashboard.\"\"\"\n id: str\n dashboard_id: int\n config_id: str\n remote_url: str\n local_path: str\n current_branch: str\n sync_status: SyncStatus\n\n class Config:\n from_attributes = True\n# #endregion GitRepositorySchema\n\n# #region BranchSchema [TYPE Class]\n# @BRIEF Schema for representing a Git branch metadata.\nclass BranchSchema(BaseModel):\n \"\"\"Schema for representing a Git branch.\"\"\"\n name: str\n commit_hash: str\n is_remote: bool\n last_updated: datetime\n# #endregion BranchSchema\n\n# #region CommitSchema [TYPE Class]\n# @BRIEF Schema for representing Git commit details.\nclass CommitSchema(BaseModel):\n \"\"\"Schema for representing a Git commit.\"\"\"\n hash: str\n author: str\n email: str\n timestamp: datetime\n message: str\n files_changed: list[str]\n# #endregion CommitSchema\n\n# #region BranchCreate [TYPE Class]\n# @BRIEF Schema for branch creation requests.\nclass BranchCreate(BaseModel):\n \"\"\"Schema for branch creation requests.\"\"\"\n name: str\n from_branch: str\n# #endregion BranchCreate\n\n# #region BranchCheckout [TYPE Class]\n# @BRIEF Schema for branch checkout requests.\nclass BranchCheckout(BaseModel):\n \"\"\"Schema for branch checkout requests.\"\"\"\n name: str\n# #endregion BranchCheckout\n\n# #region CommitCreate [TYPE Class]\n# @BRIEF Schema for staging and committing changes.\nclass CommitCreate(BaseModel):\n \"\"\"Schema for staging and committing changes.\"\"\"\n message: str\n files: list[str]\n# #endregion CommitCreate\n\n# #region ConflictResolution [TYPE Class]\n# @BRIEF Schema for resolving merge conflicts.\nclass ConflictResolution(BaseModel):\n \"\"\"Schema for resolving merge conflicts.\"\"\"\n file_path: str\n resolution: str = Field(pattern=\"^(mine|theirs|manual)$\")\n content: str | None = None\n# #endregion ConflictResolution\n\n\n# #region MergeStatusSchema [TYPE Class]\n# @BRIEF Schema representing unfinished merge status for repository.\nclass MergeStatusSchema(BaseModel):\n has_unfinished_merge: bool\n repository_path: str\n git_dir: str\n current_branch: str\n merge_head: str | None = None\n merge_message_preview: str | None = None\n conflicts_count: int = 0\n# #endregion MergeStatusSchema\n\n\n# #region MergeConflictFileSchema [TYPE Class]\n# @BRIEF Schema describing one conflicted file with optional side snapshots.\nclass MergeConflictFileSchema(BaseModel):\n file_path: str\n mine: str | None = None\n theirs: str | None = None\n# #endregion MergeConflictFileSchema\n\n\n# #region MergeResolveRequest [TYPE Class]\n# @BRIEF Request schema for resolving one or multiple merge conflicts.\nclass MergeResolveRequest(BaseModel):\n resolutions: list[ConflictResolution] = Field(default_factory=list)\n# #endregion MergeResolveRequest\n\n\n# #region MergeContinueRequest [TYPE Class]\n# @BRIEF Request schema for finishing merge with optional explicit commit message.\nclass MergeContinueRequest(BaseModel):\n message: str | None = None\n# #endregion MergeContinueRequest\n\n# #region DeploymentEnvironmentSchema [TYPE Class]\n# @BRIEF Schema for representing a target deployment environment.\nclass DeploymentEnvironmentSchema(BaseModel):\n \"\"\"Schema for representing a target deployment environment.\"\"\"\n id: str\n name: str\n superset_url: str\n is_active: bool\n\n class Config:\n from_attributes = True\n# #endregion DeploymentEnvironmentSchema\n\n# #region DeployRequest [TYPE Class]\n# @BRIEF Schema for dashboard deployment requests.\nclass DeployRequest(BaseModel):\n \"\"\"Schema for deployment requests.\"\"\"\n environment_id: str\n# #endregion DeployRequest\n\n# #region RepoInitRequest [TYPE Class]\n# @BRIEF Schema for repository initialization requests.\nclass RepoInitRequest(BaseModel):\n \"\"\"Schema for repository initialization requests.\"\"\"\n config_id: str\n remote_url: str\n# #endregion RepoInitRequest\n\n\n# #region RepositoryBindingSchema [TYPE Class]\n# @BRIEF Schema describing repository-to-config binding and provider metadata.\nclass RepositoryBindingSchema(BaseModel):\n dashboard_id: int\n config_id: str\n provider: GitProvider\n remote_url: str\n local_path: str\n# #endregion RepositoryBindingSchema\n\n# #region RepoStatusBatchRequest [TYPE Class]\n# @BRIEF Schema for requesting repository statuses for multiple dashboards in a single call.\nclass RepoStatusBatchRequest(BaseModel):\n dashboard_ids: list[int] = Field(default_factory=list, description=\"Dashboard IDs to resolve repository statuses for\")\n# #endregion RepoStatusBatchRequest\n\n\n# #region RepoStatusBatchResponse [TYPE Class]\n# @BRIEF Schema for returning repository statuses keyed by dashboard ID.\nclass RepoStatusBatchResponse(BaseModel):\n statuses: dict[str, dict[str, Any]]\n# #endregion RepoStatusBatchResponse\n\n\n# #region GiteaRepoSchema [TYPE Class]\n# @BRIEF Schema describing a Gitea repository.\nclass GiteaRepoSchema(BaseModel):\n name: str\n full_name: str\n private: bool = False\n clone_url: str | None = None\n html_url: str | None = None\n ssh_url: str | None = None\n default_branch: str | None = None\n# #endregion GiteaRepoSchema\n\n\n# #region GiteaRepoCreateRequest [TYPE Class]\n# @BRIEF Request schema for creating a Gitea repository.\nclass GiteaRepoCreateRequest(BaseModel):\n name: str = Field(..., min_length=1, max_length=255)\n private: bool = True\n description: str | None = None\n auto_init: bool = True\n default_branch: str | None = \"main\"\n# #endregion GiteaRepoCreateRequest\n\n\n# #region RemoteRepoSchema [TYPE Class]\n# @BRIEF Provider-agnostic remote repository payload.\nclass RemoteRepoSchema(BaseModel):\n provider: GitProvider\n name: str\n full_name: str\n private: bool = False\n clone_url: str | None = None\n html_url: str | None = None\n ssh_url: str | None = None\n default_branch: str | None = None\n# #endregion RemoteRepoSchema\n\n\n# #region RemoteRepoCreateRequest [TYPE Class]\n# @BRIEF Provider-agnostic repository creation request.\nclass RemoteRepoCreateRequest(BaseModel):\n name: str = Field(..., min_length=1, max_length=255)\n private: bool = True\n description: str | None = None\n auto_init: bool = True\n default_branch: str | None = \"main\"\n# #endregion RemoteRepoCreateRequest\n\n\n# #region PromoteRequest [TYPE Class]\n# @BRIEF Request schema for branch promotion workflow.\nclass PromoteRequest(BaseModel):\n from_branch: str = Field(..., min_length=1, max_length=255)\n to_branch: str = Field(..., min_length=1, max_length=255)\n mode: str = Field(default=\"mr\", pattern=\"^(mr|direct)$\")\n title: str | None = None\n description: str | None = None\n reason: str | None = None\n draft: bool = False\n remove_source_branch: bool = False\n# #endregion PromoteRequest\n\n\n# #region PromoteResponse [TYPE Class]\n# @BRIEF Response schema for promotion operation result.\nclass PromoteResponse(BaseModel):\n mode: str\n from_branch: str\n to_branch: str\n status: str\n url: str | None = None\n reference_id: str | None = None\n policy_violation: bool = False\n# #endregion PromoteResponse\n\n# #endregion GitSchemas\n"
},
{
"contract_id": "GitServerConfigBase",
@@ -11850,7 +11886,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region health_router [C:3] [TYPE Module] [SEMANTICS fastapi, health, api, search, dashboard]\n# @BRIEF API endpoints for dashboard health monitoring and status aggregation.\n# @LAYER UI\n# @RELATION DEPENDS_ON -> [health_service]\n\n\nfrom fastapi import APIRouter, Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ...core.database import get_db\nfrom ...dependencies import get_config_manager, get_task_manager, has_permission\nfrom ...schemas.health import HealthSummaryResponse\nfrom ...services.health_service import HealthService\n\nrouter = APIRouter(prefix=\"/api/health\", tags=[\"Health\"])\n\n# #region get_health_summary [TYPE Function]\n# @BRIEF Get aggregated health status for all dashboards.\n# @PRE Caller has read permission for dashboard health view.\n# @POST Returns HealthSummaryResponse.\n# @RELATION CALLS -> [EXT:path:backend.src.services.health_service.HealthService]\n@router.get(\"/summary\", response_model=HealthSummaryResponse)\nasync def get_health_summary(\n environment_id: str | None = Query(None),\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n _ = Depends(has_permission(\"plugin:migration\", \"READ\"))\n):\n \"\"\"\n @PURPOSE: Get aggregated health status for all dashboards.\n @POST: Returns HealthSummaryResponse\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n return await service.get_health_summary(environment_id=environment_id)\n# #endregion get_health_summary\n\n\n# #region delete_health_report [TYPE Function]\n# @BRIEF Delete one persisted dashboard validation report from health summary.\n# @PRE Caller has write permission for tasks/report maintenance.\n# @POST Validation record is removed; linked task/logs are cleaned when available.\n# @RELATION CALLS -> [EXT:path:backend.src.services.health_service.HealthService]\n@router.delete(\"/summary/{record_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_health_report(\n record_id: str,\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n task_manager = Depends(get_task_manager),\n _ = Depends(has_permission(\"tasks\", \"WRITE\")),\n):\n \"\"\"\n @PURPOSE: Delete a persisted dashboard validation report from health summary.\n @POST: Validation record is removed; linked task/logs are deleted when present.\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n if not service.delete_validation_report(record_id, task_manager=task_manager):\n raise HTTPException(status_code=404, detail=\"Health report not found\")\n return\n# #endregion delete_health_report\n\n# #endregion health_router\n"
+ "body": "# #region health_router [C:3] [TYPE Module] [SEMANTICS fastapi, health, api, search, dashboard]\n# @BRIEF API endpoints for dashboard health monitoring and status aggregation.\n# @LAYER UI\n# @RELATION DEPENDS_ON -> [health_service]\n\n\nfrom fastapi import APIRouter, Depends, HTTPException, Query, status\nfrom sqlalchemy.orm import Session\n\nfrom ...core.database import get_db\nfrom ...dependencies import get_config_manager, get_task_manager, has_permission\nfrom ...schemas.health import HealthSummaryResponse\nfrom ...services.health_service import HealthService\n\nrouter = APIRouter(prefix=\"/api/health\", tags=[\"Health\"])\n\n# #region get_health_summary [TYPE Function]\n# @BRIEF Get aggregated health status for all dashboards.\n# @PRE Caller has read permission for dashboard health view.\n# @POST Returns HealthSummaryResponse.\n# @RELATION CALLS -> [HealthService]\n@router.get(\"/summary\", response_model=HealthSummaryResponse)\nasync def get_health_summary(\n environment_id: str | None = Query(None),\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n _ = Depends(has_permission(\"plugin:migration\", \"READ\"))\n):\n \"\"\"\n @PURPOSE: Get aggregated health status for all dashboards.\n @POST: Returns HealthSummaryResponse\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n return await service.get_health_summary(environment_id=environment_id)\n# #endregion get_health_summary\n\n\n# #region delete_health_report [TYPE Function]\n# @BRIEF Delete one persisted dashboard validation report from health summary.\n# @PRE Caller has write permission for tasks/report maintenance.\n# @POST Validation record is removed; linked task/logs are cleaned when available.\n# @RELATION CALLS -> [HealthService]\n@router.delete(\"/summary/{record_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_health_report(\n record_id: str,\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n task_manager = Depends(get_task_manager),\n _ = Depends(has_permission(\"tasks\", \"WRITE\")),\n):\n \"\"\"\n @PURPOSE: Delete a persisted dashboard validation report from health summary.\n @POST: Validation record is removed; linked task/logs are deleted when present.\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n if not service.delete_validation_report(record_id, task_manager=task_manager):\n raise HTTPException(status_code=404, detail=\"Health report not found\")\n return\n# #endregion delete_health_report\n\n# #endregion health_router\n"
},
{
"contract_id": "get_health_summary",
@@ -11869,14 +11905,14 @@
{
"source_id": "get_health_summary",
"relation_type": "CALLS",
- "target_id": "EXT:path:backend.src.services.health_service.HealthService",
- "target_ref": "[EXT:path:backend.src.services.health_service.HealthService]"
+ "target_id": "HealthService",
+ "target_ref": "[HealthService]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region get_health_summary [TYPE Function]\n# @BRIEF Get aggregated health status for all dashboards.\n# @PRE Caller has read permission for dashboard health view.\n# @POST Returns HealthSummaryResponse.\n# @RELATION CALLS -> [EXT:path:backend.src.services.health_service.HealthService]\n@router.get(\"/summary\", response_model=HealthSummaryResponse)\nasync def get_health_summary(\n environment_id: str | None = Query(None),\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n _ = Depends(has_permission(\"plugin:migration\", \"READ\"))\n):\n \"\"\"\n @PURPOSE: Get aggregated health status for all dashboards.\n @POST: Returns HealthSummaryResponse\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n return await service.get_health_summary(environment_id=environment_id)\n# #endregion get_health_summary\n"
+ "body": "# #region get_health_summary [TYPE Function]\n# @BRIEF Get aggregated health status for all dashboards.\n# @PRE Caller has read permission for dashboard health view.\n# @POST Returns HealthSummaryResponse.\n# @RELATION CALLS -> [HealthService]\n@router.get(\"/summary\", response_model=HealthSummaryResponse)\nasync def get_health_summary(\n environment_id: str | None = Query(None),\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n _ = Depends(has_permission(\"plugin:migration\", \"READ\"))\n):\n \"\"\"\n @PURPOSE: Get aggregated health status for all dashboards.\n @POST: Returns HealthSummaryResponse\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n return await service.get_health_summary(environment_id=environment_id)\n# #endregion get_health_summary\n"
},
{
"contract_id": "delete_health_report",
@@ -11895,14 +11931,14 @@
{
"source_id": "delete_health_report",
"relation_type": "CALLS",
- "target_id": "EXT:path:backend.src.services.health_service.HealthService",
- "target_ref": "[EXT:path:backend.src.services.health_service.HealthService]"
+ "target_id": "HealthService",
+ "target_ref": "[HealthService]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region delete_health_report [TYPE Function]\n# @BRIEF Delete one persisted dashboard validation report from health summary.\n# @PRE Caller has write permission for tasks/report maintenance.\n# @POST Validation record is removed; linked task/logs are cleaned when available.\n# @RELATION CALLS -> [EXT:path:backend.src.services.health_service.HealthService]\n@router.delete(\"/summary/{record_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_health_report(\n record_id: str,\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n task_manager = Depends(get_task_manager),\n _ = Depends(has_permission(\"tasks\", \"WRITE\")),\n):\n \"\"\"\n @PURPOSE: Delete a persisted dashboard validation report from health summary.\n @POST: Validation record is removed; linked task/logs are deleted when present.\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n if not service.delete_validation_report(record_id, task_manager=task_manager):\n raise HTTPException(status_code=404, detail=\"Health report not found\")\n return\n# #endregion delete_health_report\n"
+ "body": "# #region delete_health_report [TYPE Function]\n# @BRIEF Delete one persisted dashboard validation report from health summary.\n# @PRE Caller has write permission for tasks/report maintenance.\n# @POST Validation record is removed; linked task/logs are cleaned when available.\n# @RELATION CALLS -> [HealthService]\n@router.delete(\"/summary/{record_id}\", status_code=status.HTTP_204_NO_CONTENT)\nasync def delete_health_report(\n record_id: str,\n db: Session = Depends(get_db),\n config_manager = Depends(get_config_manager),\n task_manager = Depends(get_task_manager),\n _ = Depends(has_permission(\"tasks\", \"WRITE\")),\n):\n \"\"\"\n @PURPOSE: Delete a persisted dashboard validation report from health summary.\n @POST: Validation record is removed; linked task/logs are deleted when present.\n \"\"\"\n if not config_manager.get_config().settings.features.health_monitor:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=\"Health monitor feature is disabled\")\n service = HealthService(db, config_manager=config_manager)\n if not service.delete_validation_report(record_id, task_manager=task_manager):\n raise HTTPException(status_code=404, detail=\"Health report not found\")\n return\n# #endregion delete_health_report\n"
},
{
"contract_id": "LlmRoutes",
@@ -12382,7 +12418,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region MaintenanceRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, routes, maintenance, api]\n# @BRIEF Route handler stubs for all 7 Maintenance Banner API endpoints with RBAC guards per FR-015.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [MaintenanceSchemasModule]\n# @RELATION DEPENDS_ON -> [MaintenanceRouter]\n# @RELATION DEPENDS_ON -> [AppDependencies]\n# @RELATION DEPENDS_ON -> [EXT:frontend:MaintenanceServiceModule]\n# @INVARIANT All mutation endpoints return 202 {task_id} per spec.\n# @INVARIANT RBAC enforced per FR-015 matrix via has_permission() dependency.\n\nfrom datetime import datetime, timezone\nfrom typing import Any, cast\n\nfrom fastapi import APIRouter, Depends, HTTPException, Request, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.logger import belief_scope, logger as app_logger\nfrom ....core.task_manager import TaskManager\n\napp_logger = cast(Any, app_logger)\nfrom ....dependencies import (\n check_api_key_environment_scope,\n get_db,\n get_task_manager,\n has_permission,\n require_api_key_or_jwt,\n)\nfrom ....models.api_key import APIKey\nfrom ....models.maintenance import (\n MaintenanceDashboardBanner,\n MaintenanceDashboardBannerStatus,\n MaintenanceDashboardState,\n MaintenanceDashboardStateStatus,\n MaintenanceEvent,\n MaintenanceEventStatus,\n MaintenanceSettings,\n)\nfrom ._router import router\nfrom ._schemas import (\n MaintenanceAlreadyActiveResponse,\n MaintenanceDashboardBannerState,\n MaintenanceEndResponse,\n MaintenanceEventItem,\n MaintenanceEventListResponse,\n MaintenanceSettingsResponse,\n MaintenanceSettingsUpdate,\n MaintenanceStartRequest,\n MaintenanceStartResponse,\n)\n\n\n# ── GET /api/maintenance/dashboard-banners ───────────────────\n# FR-015: viewer, operator, admin all have READ access\n\n# #region list_dashboard_banners [C:2] [TYPE Function]\n# @BRIEF Get per-dashboard banner state for the Dashboard Hub indicator.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"READ\")]\n@router.get(\"/dashboard-banners\", response_model=list[MaintenanceDashboardBannerState])\nasync def list_dashboard_banners(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"list_dashboard_banners\"):\n # Query active banners with their linked active/pending states\n active_banners = (\n db.query(MaintenanceDashboardBanner)\n .filter(MaintenanceDashboardBanner.status == MaintenanceDashboardBannerStatus.ACTIVE)\n .all()\n )\n\n result: list[MaintenanceDashboardBannerState] = []\n for banner in active_banners:\n linked_states = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.banner_id == banner.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .all()\n )\n\n event_ids: list[str] = []\n start_times: list[str] = []\n end_times: list[str] = []\n\n for state in linked_states:\n event = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.id == state.event_id)\n .first()\n )\n if event:\n event_ids.append(event.id)\n if event.start_time:\n start_times.append(event.start_time.isoformat())\n if event.end_time:\n end_times.append(event.end_time.isoformat())\n\n result.append(\n MaintenanceDashboardBannerState(\n dashboard_id=banner.dashboard_id,\n active=True,\n events=event_ids,\n start_time=min(start_times) if start_times else None,\n end_time=max(end_times) if end_times else None,\n )\n )\n\n return result\n# #endregion list_dashboard_banners\n\n\n# ── GET /api/maintenance/events ──────────────────────────────\n# FR-015: operator, admin (NOT viewer)\n\n# #region list_events [C:2] [TYPE Function]\n# @BRIEF Get active and completed maintenance event lists with affected dashboard counts.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"READ\")]\n@router.get(\"/events\", response_model=MaintenanceEventListResponse)\nasync def list_events(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"list_events\"):\n # ── Auto-expiry: end events past their end_time ──\n now = datetime.now(timezone.utc)\n expired = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n MaintenanceEventStatus.ENDING,\n ]),\n MaintenanceEvent.end_time.isnot(None),\n MaintenanceEvent.end_time < now,\n )\n .all()\n )\n for ev in expired:\n app_logger.reason(\n \"Auto-ending expired maintenance event\",\n extra={\"event_id\": ev.id, \"end_time\": ev.end_time.isoformat()},\n )\n # Schedule proper cleanup via task manager (removes banner from dashboard)\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end\",\n \"event_id\": ev.id,\n \"environment_id\": ev.environment_id,\n \"user\": \"system\",\n },\n )\n app_logger.reflect(\n \"Scheduled cleanup for expired event\",\n extra={\"event_id\": ev.id, \"task_id\": task.id},\n )\n\n # Active events: ACTIVE, PARTIAL (per spec T040)\n active_statuses = [\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n ]\n active_events = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.status.in_(active_statuses))\n .order_by(MaintenanceEvent.created_at.desc())\n .all()\n )\n\n # Completed events: COMPLETED, FAILED\n completed_events = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.COMPLETED,\n MaintenanceEventStatus.FAILED,\n ])\n )\n .order_by(MaintenanceEvent.created_at.desc())\n .limit(50)\n .all()\n )\n\n def _to_item(event: MaintenanceEvent) -> MaintenanceEventItem:\n affected_count = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.event_id == event.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .count()\n )\n return MaintenanceEventItem(\n id=event.id,\n tables=list(event.tables) if event.tables else [],\n start_time=event.start_time.isoformat() if event.start_time else \"\",\n end_time=event.end_time.isoformat() if event.end_time else None,\n message=event.message or None,\n status=event.status.value,\n affected_count=affected_count,\n created_at=event.created_at.isoformat() if event.created_at else \"\",\n )\n\n return MaintenanceEventListResponse(\n active=[_to_item(e) for e in active_events],\n completed=[_to_item(e) for e in completed_events],\n )\n# #endregion list_events\n\n\n# ── POST /api/maintenance/start ──────────────────────────────\n# FR-001: Always returns 202 {task_id} after validation\n# FR-015: operator, admin (NOT viewer)\n\n# #region start_maintenance [C:3] [TYPE Function]\n# @BRIEF Start a maintenance event. Validates input, creates event, dispatches TaskManager task.\n# Always returns 202 with task_id and maintenance_id.\n# Idempotency: same (tables, start_time, end_time) returns already_active (409-like but 200).\n# Tables sorted & lowered for idempotency key. Message NOT in key.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"WRITE\")]\n# @RELATION DEPENDS_ON -> [TaskManager]\n@router.post(\n \"/start\",\n status_code=status.HTTP_202_ACCEPTED,\n responses={\n 202: {\"model\": MaintenanceStartResponse},\n 409: {\"model\": MaintenanceAlreadyActiveResponse},\n },\n)\nasync def start_maintenance(\n request: MaintenanceStartRequest,\n db: Session = Depends(get_db),\n _auth=Depends(require_api_key_or_jwt(\"maintenance:start\", \"maintenance\", \"WRITE\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"start_maintenance\"):\n # ── Validation ──\n\n # Validate end_time > start_time\n if request.end_time and request.start_time and request.end_time <= request.start_time:\n raise HTTPException(\n status_code=400,\n detail=\"end_time must be after start_time\",\n )\n\n # Validate times are within reasonable range (future ±1h grace period)\n now = datetime.now(timezone.utc)\n grace_threshold = 3600 # 1 hour in seconds\n if request.start_time:\n diff = (request.start_time - now).total_seconds() if request.start_time.tzinfo else \\\n (request.start_time.replace(tzinfo=timezone.utc) - now).total_seconds()\n if diff < -grace_threshold:\n raise HTTPException(\n status_code=400,\n detail=\"start_time is too far in the past (max 1h grace period)\",\n )\n\n # Validate tables list length\n if len(request.tables) > 100:\n raise HTTPException(\n status_code=400,\n detail=\"Maximum 100 tables allowed\",\n )\n\n # Sanitize message (HTML escape already done in rendering, but check for raw HTML)\n message = request.message\n if message:\n import html as _html\n sanitized = _html.escape(message)\n if sanitized != message:\n # Message contained HTML — accept it, it will be escaped at render time\n pass\n\n # ── Idempotency check ──\n from ....services.maintenance import build_idempotency_key\n\n sorted_tables = sorted(t.strip().lower() for t in request.tables if t.strip())\n idem_tables = frozenset(sorted_tables)\n idem_start = request.start_time.isoformat() if request.start_time else None\n idem_end = request.end_time.isoformat() if request.end_time else None\n\n # Find existing active event with same idempotency key\n active_statuses = [\n MaintenanceEventStatus.PENDING,\n MaintenanceEventStatus.APPLYING,\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n ]\n existing = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_(active_statuses),\n )\n .all()\n )\n for ev in existing:\n ev_tables = frozenset(\n sorted(t.lower() for t in (ev.tables or []) if t)\n )\n ev_start = ev.start_time.isoformat() if ev.start_time else None\n ev_end = ev.end_time.isoformat() if ev.end_time else None\n if ev_tables == idem_tables and ev_start == idem_start and ev_end == idem_end:\n # Same key → return already_active\n app_logger.reflect(\n \"Idempotency hit — event already active\",\n extra={\"existing_id\": ev.id},\n )\n return MaintenanceAlreadyActiveResponse(\n maintenance_id=ev.id,\n status=\"already_active\",\n )\n\n # ── Environment scoping ──\n env_id = request.environment_id\n\n # ── Create event ──\n event = MaintenanceEvent(\n tables=sorted_tables,\n start_time=request.start_time,\n end_time=request.end_time,\n message=message,\n status=MaintenanceEventStatus.PENDING,\n environment_id=env_id,\n )\n db.add(event)\n db.flush()\n\n # ── Dispatch TaskManager task ──\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"start\",\n \"event_id\": event.id,\n \"environment_id\": env_id,\n \"user\": _auth.split(\":\", 1)[1] if \":\" in _auth else _auth,\n },\n )\n event.task_id = task.id\n db.commit()\n\n app_logger.reflect(\n \"Maintenance start dispatched\",\n extra={\"event_id\": event.id, \"task_id\": task.id},\n )\n\n return MaintenanceStartResponse(\n task_id=task.id,\n maintenance_id=event.id,\n status=\"pending\",\n )\n# #endregion start_maintenance\n\n\n# ── POST /api/maintenance/{maintenance_id}/end ───────────────\n# FR-006: Remove banners for a specific maintenance event\n# FR-015: operator, admin (NOT viewer)\n\n# #region end_maintenance [C:3] [TYPE Function]\n# @BRIEF End a specific maintenance event by ID. Removes banners from affected dashboards.\n# Always returns 202 with task_id. Idempotent: already_completed returns success.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"WRITE\")]\n@router.post(\n \"/{maintenance_id}/end\",\n status_code=status.HTTP_202_ACCEPTED,\n response_model=MaintenanceEndResponse,\n)\nasync def end_maintenance(\n maintenance_id: str,\n request: Request,\n db: Session = Depends(get_db),\n _auth=Depends(require_api_key_or_jwt(\"maintenance:end\", \"maintenance\", \"WRITE\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"end_maintenance\", f\"maintenance_id={maintenance_id}\"):\n # Check event exists\n event = db.query(MaintenanceEvent).filter(\n MaintenanceEvent.id == maintenance_id\n ).first()\n\n if not event:\n raise HTTPException(\n status_code=404,\n detail=f\"Maintenance event {maintenance_id} not found\",\n )\n\n # Validate API key environment scope against event's environment\n if _auth.startswith(\"api_key:\"):\n await check_api_key_environment_scope(request, db, event.environment_id or \"\")\n\n # If already completed, return idempotent success\n if event.status == MaintenanceEventStatus.COMPLETED:\n app_logger.reflect(\n \"Event already completed, returning idempotent\",\n extra={\"event_id\": maintenance_id},\n )\n return MaintenanceEndResponse(\n task_id=event.task_id or \"\",\n status=\"already_completed\",\n )\n\n # ── Dispatch TaskManager task ──\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end\",\n \"event_id\": maintenance_id,\n \"environment_id\": event.environment_id,\n \"user\": _auth.split(\":\", 1)[1] if \":\" in _auth else _auth,\n },\n )\n\n app_logger.reflect(\n \"Maintenance end dispatched\",\n extra={\"event_id\": maintenance_id, \"task_id\": task.id},\n )\n\n return MaintenanceEndResponse(\n task_id=task.id,\n status=\"pending\",\n )\n# #endregion end_maintenance\n\n\n# ── POST /api/maintenance/end-all ────────────────────────────\n# FR-007: Bulk removal of all active banners\n# FR-015: operator, admin (NOT viewer)\n\n# #region end_all_maintenance [C:3] [TYPE Function]\n# @BRIEF End all active maintenance events. Removes all banners from all dashboards.\n# Always returns 202 with task_id. Supports environment scoping for API keys.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"WRITE\")]\n@router.post(\n \"/end-all\",\n status_code=status.HTTP_202_ACCEPTED,\n response_model=MaintenanceEndResponse,\n)\nasync def end_all_maintenance(\n request: Request,\n db: Session = Depends(get_db),\n _auth=Depends(require_api_key_or_jwt(\"maintenance:end_all\", \"maintenance\", \"WRITE\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"end_all_maintenance\"):\n # ── Resolve environment scope ──\n effective_env_id: str | None = None\n try:\n body = await request.json()\n effective_env_id = body.get(\"environment_id\")\n except Exception:\n pass\n\n # ── Enforce API key environment scoping ──\n if _auth.startswith(\"api_key:\"):\n # Auto-scope to the key's environment if not specified in body\n if not effective_env_id:\n raw_key = request.headers.get(\"X-API-Key\")\n if raw_key:\n from ....core.auth.api_key import hash_api_key\n key_hash = hash_api_key(raw_key)\n key_row = db.query(APIKey).filter(APIKey.key_hash == key_hash).first()\n if key_row and key_row.environment_id:\n effective_env_id = key_row.environment_id\n\n await check_api_key_environment_scope(request, db, effective_env_id or \"\")\n\n # ── Dispatch TaskManager task ──\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end_all\",\n \"environment_id\": effective_env_id or \"\",\n \"user\": _auth.split(\":\", 1)[1] if \":\" in _auth else _auth,\n },\n )\n\n app_logger.reflect(\n \"End-all maintenance dispatched\",\n extra={\"task_id\": task.id, \"environment_id\": effective_env_id},\n )\n\n return MaintenanceEndResponse(\n task_id=task.id,\n status=\"pending\",\n )\n# #endregion end_all_maintenance\n\n\n# ── GET /api/maintenance/settings ────────────────────────────\n# FR-009: Get maintenance settings configuration\n# FR-015: operator, admin (NOT viewer)\n\n# #region get_maintenance_settings [C:2] [TYPE Function]\n# @BRIEF Get current maintenance settings configuration.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"READ\")]\n@router.get(\"/settings\", response_model=MaintenanceSettingsResponse)\nasync def get_maintenance_settings(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"get_maintenance_settings\"):\n settings = db.query(MaintenanceSettings).filter(\n MaintenanceSettings.id == \"default\"\n ).first()\n\n if not settings:\n raise HTTPException(\n status_code=404,\n detail=\"Maintenance settings not configured\",\n )\n\n return MaintenanceSettingsResponse(\n target_environment_id=settings.target_environment_id,\n display_timezone=settings.display_timezone,\n banner_template=settings.banner_template,\n dashboard_scope=settings.dashboard_scope.value,\n excluded_dashboard_ids=list(settings.excluded_dashboard_ids or []),\n forced_dashboard_ids=list(settings.forced_dashboard_ids or []),\n updated_at=settings.updated_at.isoformat() if settings.updated_at else None,\n )\n# #endregion get_maintenance_settings\n\n\n# ── PUT /api/maintenance/settings ────────────────────────────\n# FR-009: Update maintenance settings configuration\n# FR-015: admin ONLY (NOT operator, NOT viewer)\n\n# #region update_maintenance_settings [C:2] [TYPE Function]\n# @BRIEF Update maintenance settings. All fields optional for partial update.\n# admin role required per FR-015.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"admin:settings\", \"WRITE\")]\n@router.put(\"/settings\", response_model=MaintenanceSettingsResponse)\nasync def update_maintenance_settings(\n settings_data: MaintenanceSettingsUpdate,\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n with belief_scope(\"update_maintenance_settings\"):\n settings = db.query(MaintenanceSettings).filter(\n MaintenanceSettings.id == \"default\"\n ).first()\n\n if not settings:\n # Auto-create with defaults on first save (upsert behavior).\n # Column-level defaults from the model apply for omitted fields.\n settings = MaintenanceSettings(\n id=\"default\",\n target_environment_id=settings_data.target_environment_id or \"\",\n )\n db.add(settings)\n db.flush()\n\n # Apply partial updates\n update_data = settings_data.model_dump(exclude_unset=True)\n\n if \"target_environment_id\" in update_data:\n settings.target_environment_id = update_data[\"target_environment_id\"]\n if \"display_timezone\" in update_data:\n settings.display_timezone = update_data[\"display_timezone\"]\n if \"banner_template\" in update_data:\n settings.banner_template = update_data[\"banner_template\"]\n if \"dashboard_scope\" in update_data:\n from ....models.maintenance import DashboardScope\n settings.dashboard_scope = DashboardScope(update_data[\"dashboard_scope\"])\n if \"excluded_dashboard_ids\" in update_data:\n settings.excluded_dashboard_ids = update_data[\"excluded_dashboard_ids\"]\n if \"forced_dashboard_ids\" in update_data:\n settings.forced_dashboard_ids = update_data[\"forced_dashboard_ids\"]\n\n db.commit()\n db.refresh(settings)\n\n return MaintenanceSettingsResponse(\n target_environment_id=settings.target_environment_id,\n display_timezone=settings.display_timezone,\n banner_template=settings.banner_template,\n dashboard_scope=settings.dashboard_scope.value,\n excluded_dashboard_ids=list(settings.excluded_dashboard_ids or []),\n forced_dashboard_ids=list(settings.forced_dashboard_ids or []),\n updated_at=settings.updated_at.isoformat() if settings.updated_at else None,\n )\n# #endregion update_maintenance_settings\n\n# #endregion MaintenanceRoutesModule\n"
+ "body": "# #region MaintenanceRoutesModule [C:3] [TYPE Module] [SEMANTICS fastapi, routes, maintenance, api]\n# @BRIEF Route handler stubs for all 7 Maintenance Banner API endpoints with RBAC guards per FR-015.\n# @LAYER API\n# @RELATION DEPENDS_ON -> [MaintenanceSchemasModule]\n# @RELATION DEPENDS_ON -> [MaintenanceRouter]\n# @RELATION DEPENDS_ON -> [AppDependencies]\n# @RELATION DEPENDS_ON -> [EXT:frontend:MaintenanceServiceModule]\n# @INVARIANT All mutation endpoints return 202 {task_id} per spec.\n# @INVARIANT RBAC enforced per FR-015 matrix via has_permission() dependency.\n\nfrom datetime import datetime, timezone\nfrom typing import Any, cast\n\nfrom fastapi import APIRouter, Depends, HTTPException, Request, status\nfrom sqlalchemy.orm import Session\n\nfrom ....core.logger import belief_scope, logger as app_logger\nfrom ....core.task_manager import TaskManager\n\napp_logger = cast(Any, app_logger)\nfrom ....dependencies import (\n check_api_key_environment_scope,\n get_db,\n get_task_manager,\n has_permission,\n require_api_key_or_jwt,\n)\nfrom ....models.api_key import APIKey\nfrom ....models.maintenance import (\n MaintenanceDashboardBanner,\n MaintenanceDashboardBannerStatus,\n MaintenanceDashboardState,\n MaintenanceDashboardStateStatus,\n MaintenanceEvent,\n MaintenanceEventStatus,\n MaintenanceSettings,\n)\nfrom ._router import router\nfrom ._schemas import (\n MaintenanceAlreadyActiveResponse,\n MaintenanceDashboardBannerState,\n MaintenanceEndResponse,\n MaintenanceEventItem,\n MaintenanceEventListResponse,\n MaintenanceSettingsResponse,\n MaintenanceSettingsUpdate,\n MaintenanceStartRequest,\n MaintenanceStartResponse,\n)\n\n\n# ── GET /api/maintenance/dashboard-banners ───────────────────\n# FR-015: viewer, operator, admin all have READ access\n\n# #region list_dashboard_banners [C:2] [TYPE Function]\n# @BRIEF Get per-dashboard banner state for the Dashboard Hub indicator.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]\n@router.get(\"/dashboard-banners\", response_model=list[MaintenanceDashboardBannerState])\nasync def list_dashboard_banners(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"list_dashboard_banners\"):\n # Query active banners with their linked active/pending states\n active_banners = (\n db.query(MaintenanceDashboardBanner)\n .filter(MaintenanceDashboardBanner.status == MaintenanceDashboardBannerStatus.ACTIVE)\n .all()\n )\n\n result: list[MaintenanceDashboardBannerState] = []\n for banner in active_banners:\n linked_states = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.banner_id == banner.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .all()\n )\n\n event_ids: list[str] = []\n start_times: list[str] = []\n end_times: list[str] = []\n\n for state in linked_states:\n event = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.id == state.event_id)\n .first()\n )\n if event:\n event_ids.append(event.id)\n if event.start_time:\n start_times.append(event.start_time.isoformat())\n if event.end_time:\n end_times.append(event.end_time.isoformat())\n\n result.append(\n MaintenanceDashboardBannerState(\n dashboard_id=banner.dashboard_id,\n active=True,\n events=event_ids,\n start_time=min(start_times) if start_times else None,\n end_time=max(end_times) if end_times else None,\n )\n )\n\n return result\n# #endregion list_dashboard_banners\n\n\n# ── GET /api/maintenance/events ──────────────────────────────\n# FR-015: operator, admin (NOT viewer)\n\n# #region list_events [C:2] [TYPE Function]\n# @BRIEF Get active and completed maintenance event lists with affected dashboard counts.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]\n@router.get(\"/events\", response_model=MaintenanceEventListResponse)\nasync def list_events(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"list_events\"):\n # ── Auto-expiry: end events past their end_time ──\n now = datetime.now(timezone.utc)\n expired = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n MaintenanceEventStatus.ENDING,\n ]),\n MaintenanceEvent.end_time.isnot(None),\n MaintenanceEvent.end_time < now,\n )\n .all()\n )\n for ev in expired:\n app_logger.reason(\n \"Auto-ending expired maintenance event\",\n extra={\"event_id\": ev.id, \"end_time\": ev.end_time.isoformat()},\n )\n # Schedule proper cleanup via task manager (removes banner from dashboard)\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end\",\n \"event_id\": ev.id,\n \"environment_id\": ev.environment_id,\n \"user\": \"system\",\n },\n )\n app_logger.reflect(\n \"Scheduled cleanup for expired event\",\n extra={\"event_id\": ev.id, \"task_id\": task.id},\n )\n\n # Active events: ACTIVE, PARTIAL (per spec T040)\n active_statuses = [\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n ]\n active_events = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.status.in_(active_statuses))\n .order_by(MaintenanceEvent.created_at.desc())\n .all()\n )\n\n # Completed events: COMPLETED, FAILED\n completed_events = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.COMPLETED,\n MaintenanceEventStatus.FAILED,\n ])\n )\n .order_by(MaintenanceEvent.created_at.desc())\n .limit(50)\n .all()\n )\n\n def _to_item(event: MaintenanceEvent) -> MaintenanceEventItem:\n affected_count = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.event_id == event.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .count()\n )\n return MaintenanceEventItem(\n id=event.id,\n tables=list(event.tables) if event.tables else [],\n start_time=event.start_time.isoformat() if event.start_time else \"\",\n end_time=event.end_time.isoformat() if event.end_time else None,\n message=event.message or None,\n status=event.status.value,\n affected_count=affected_count,\n created_at=event.created_at.isoformat() if event.created_at else \"\",\n )\n\n return MaintenanceEventListResponse(\n active=[_to_item(e) for e in active_events],\n completed=[_to_item(e) for e in completed_events],\n )\n# #endregion list_events\n\n\n# ── POST /api/maintenance/start ──────────────────────────────\n# FR-001: Always returns 202 {task_id} after validation\n# FR-015: operator, admin (NOT viewer)\n\n# #region start_maintenance [C:3] [TYPE Function]\n# @BRIEF Start a maintenance event. Validates input, creates event, dispatches TaskManager task.\n# Always returns 202 with task_id and maintenance_id.\n# Idempotency: same (tables, start_time, end_time) returns already_active (409-like but 200).\n# Tables sorted & lowered for idempotency key. Message NOT in key.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"WRITE\")]\n# @RELATION DEPENDS_ON -> [TaskManager]\n@router.post(\n \"/start\",\n status_code=status.HTTP_202_ACCEPTED,\n responses={\n 202: {\"model\": MaintenanceStartResponse},\n 409: {\"model\": MaintenanceAlreadyActiveResponse},\n },\n)\nasync def start_maintenance(\n request: MaintenanceStartRequest,\n db: Session = Depends(get_db),\n _auth=Depends(require_api_key_or_jwt(\"maintenance:start\", \"maintenance\", \"WRITE\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"start_maintenance\"):\n # ── Validation ──\n\n # Validate end_time > start_time\n if request.end_time and request.start_time and request.end_time <= request.start_time:\n raise HTTPException(\n status_code=400,\n detail=\"end_time must be after start_time\",\n )\n\n # Validate times are within reasonable range (future ±1h grace period)\n now = datetime.now(timezone.utc)\n grace_threshold = 3600 # 1 hour in seconds\n if request.start_time:\n diff = (request.start_time - now).total_seconds() if request.start_time.tzinfo else \\\n (request.start_time.replace(tzinfo=timezone.utc) - now).total_seconds()\n if diff < -grace_threshold:\n raise HTTPException(\n status_code=400,\n detail=\"start_time is too far in the past (max 1h grace period)\",\n )\n\n # Validate tables list length\n if len(request.tables) > 100:\n raise HTTPException(\n status_code=400,\n detail=\"Maximum 100 tables allowed\",\n )\n\n # Sanitize message (HTML escape already done in rendering, but check for raw HTML)\n message = request.message\n if message:\n import html as _html\n sanitized = _html.escape(message)\n if sanitized != message:\n # Message contained HTML — accept it, it will be escaped at render time\n pass\n\n # ── Idempotency check ──\n from ....services.maintenance import build_idempotency_key\n\n sorted_tables = sorted(t.strip().lower() for t in request.tables if t.strip())\n idem_tables = frozenset(sorted_tables)\n idem_start = request.start_time.isoformat() if request.start_time else None\n idem_end = request.end_time.isoformat() if request.end_time else None\n\n # Find existing active event with same idempotency key\n active_statuses = [\n MaintenanceEventStatus.PENDING,\n MaintenanceEventStatus.APPLYING,\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n ]\n existing = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_(active_statuses),\n )\n .all()\n )\n for ev in existing:\n ev_tables = frozenset(\n sorted(t.lower() for t in (ev.tables or []) if t)\n )\n ev_start = ev.start_time.isoformat() if ev.start_time else None\n ev_end = ev.end_time.isoformat() if ev.end_time else None\n if ev_tables == idem_tables and ev_start == idem_start and ev_end == idem_end:\n # Same key → return already_active\n app_logger.reflect(\n \"Idempotency hit — event already active\",\n extra={\"existing_id\": ev.id},\n )\n return MaintenanceAlreadyActiveResponse(\n maintenance_id=ev.id,\n status=\"already_active\",\n )\n\n # ── Environment scoping ──\n env_id = request.environment_id\n\n # ── Create event ──\n event = MaintenanceEvent(\n tables=sorted_tables,\n start_time=request.start_time,\n end_time=request.end_time,\n message=message,\n status=MaintenanceEventStatus.PENDING,\n environment_id=env_id,\n )\n db.add(event)\n db.flush()\n\n # ── Dispatch TaskManager task ──\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"start\",\n \"event_id\": event.id,\n \"environment_id\": env_id,\n \"user\": _auth.split(\":\", 1)[1] if \":\" in _auth else _auth,\n },\n )\n event.task_id = task.id\n db.commit()\n\n app_logger.reflect(\n \"Maintenance start dispatched\",\n extra={\"event_id\": event.id, \"task_id\": task.id},\n )\n\n return MaintenanceStartResponse(\n task_id=task.id,\n maintenance_id=event.id,\n status=\"pending\",\n )\n# #endregion start_maintenance\n\n\n# ── POST /api/maintenance/{maintenance_id}/end ───────────────\n# FR-006: Remove banners for a specific maintenance event\n# FR-015: operator, admin (NOT viewer)\n\n# #region end_maintenance [C:3] [TYPE Function]\n# @BRIEF End a specific maintenance event by ID. Removes banners from affected dashboards.\n# Always returns 202 with task_id. Idempotent: already_completed returns success.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"WRITE\")]\n@router.post(\n \"/{maintenance_id}/end\",\n status_code=status.HTTP_202_ACCEPTED,\n response_model=MaintenanceEndResponse,\n)\nasync def end_maintenance(\n maintenance_id: str,\n request: Request,\n db: Session = Depends(get_db),\n _auth=Depends(require_api_key_or_jwt(\"maintenance:end\", \"maintenance\", \"WRITE\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"end_maintenance\", f\"maintenance_id={maintenance_id}\"):\n # Check event exists\n event = db.query(MaintenanceEvent).filter(\n MaintenanceEvent.id == maintenance_id\n ).first()\n\n if not event:\n raise HTTPException(\n status_code=404,\n detail=f\"Maintenance event {maintenance_id} not found\",\n )\n\n # Validate API key environment scope against event's environment\n if _auth.startswith(\"api_key:\"):\n await check_api_key_environment_scope(request, db, event.environment_id or \"\")\n\n # If already completed, return idempotent success\n if event.status == MaintenanceEventStatus.COMPLETED:\n app_logger.reflect(\n \"Event already completed, returning idempotent\",\n extra={\"event_id\": maintenance_id},\n )\n return MaintenanceEndResponse(\n task_id=event.task_id or \"\",\n status=\"already_completed\",\n )\n\n # ── Dispatch TaskManager task ──\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end\",\n \"event_id\": maintenance_id,\n \"environment_id\": event.environment_id,\n \"user\": _auth.split(\":\", 1)[1] if \":\" in _auth else _auth,\n },\n )\n\n app_logger.reflect(\n \"Maintenance end dispatched\",\n extra={\"event_id\": maintenance_id, \"task_id\": task.id},\n )\n\n return MaintenanceEndResponse(\n task_id=task.id,\n status=\"pending\",\n )\n# #endregion end_maintenance\n\n\n# ── POST /api/maintenance/end-all ────────────────────────────\n# FR-007: Bulk removal of all active banners\n# FR-015: operator, admin (NOT viewer)\n\n# #region end_all_maintenance [C:3] [TYPE Function]\n# @BRIEF End all active maintenance events. Removes all banners from all dashboards.\n# Always returns 202 with task_id. Supports environment scoping for API keys.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"WRITE\")]\n@router.post(\n \"/end-all\",\n status_code=status.HTTP_202_ACCEPTED,\n response_model=MaintenanceEndResponse,\n)\nasync def end_all_maintenance(\n request: Request,\n db: Session = Depends(get_db),\n _auth=Depends(require_api_key_or_jwt(\"maintenance:end_all\", \"maintenance\", \"WRITE\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"end_all_maintenance\"):\n # ── Resolve environment scope ──\n effective_env_id: str | None = None\n try:\n body = await request.json()\n effective_env_id = body.get(\"environment_id\")\n except Exception:\n pass\n\n # ── Enforce API key environment scoping ──\n if _auth.startswith(\"api_key:\"):\n # Auto-scope to the key's environment if not specified in body\n if not effective_env_id:\n raw_key = request.headers.get(\"X-API-Key\")\n if raw_key:\n from ....core.auth.api_key import hash_api_key\n key_hash = hash_api_key(raw_key)\n key_row = db.query(APIKey).filter(APIKey.key_hash == key_hash).first()\n if key_row and key_row.environment_id:\n effective_env_id = key_row.environment_id\n\n await check_api_key_environment_scope(request, db, effective_env_id or \"\")\n\n # ── Dispatch TaskManager task ──\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end_all\",\n \"environment_id\": effective_env_id or \"\",\n \"user\": _auth.split(\":\", 1)[1] if \":\" in _auth else _auth,\n },\n )\n\n app_logger.reflect(\n \"End-all maintenance dispatched\",\n extra={\"task_id\": task.id, \"environment_id\": effective_env_id},\n )\n\n return MaintenanceEndResponse(\n task_id=task.id,\n status=\"pending\",\n )\n# #endregion end_all_maintenance\n\n\n# ── GET /api/maintenance/settings ────────────────────────────\n# FR-009: Get maintenance settings configuration\n# FR-015: operator, admin (NOT viewer)\n\n# #region get_maintenance_settings [C:2] [TYPE Function]\n# @BRIEF Get current maintenance settings configuration.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]\n@router.get(\"/settings\", response_model=MaintenanceSettingsResponse)\nasync def get_maintenance_settings(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"get_maintenance_settings\"):\n settings = db.query(MaintenanceSettings).filter(\n MaintenanceSettings.id == \"default\"\n ).first()\n\n if not settings:\n raise HTTPException(\n status_code=404,\n detail=\"Maintenance settings not configured\",\n )\n\n return MaintenanceSettingsResponse(\n target_environment_id=settings.target_environment_id,\n display_timezone=settings.display_timezone,\n banner_template=settings.banner_template,\n dashboard_scope=settings.dashboard_scope.value,\n excluded_dashboard_ids=list(settings.excluded_dashboard_ids or []),\n forced_dashboard_ids=list(settings.forced_dashboard_ids or []),\n updated_at=settings.updated_at.isoformat() if settings.updated_at else None,\n )\n# #endregion get_maintenance_settings\n\n\n# ── PUT /api/maintenance/settings ────────────────────────────\n# FR-009: Update maintenance settings configuration\n# FR-015: admin ONLY (NOT operator, NOT viewer)\n\n# #region update_maintenance_settings [C:2] [TYPE Function]\n# @BRIEF Update maintenance settings. All fields optional for partial update.\n# admin role required per FR-015.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"admin:settings\", \"WRITE\")]\n@router.put(\"/settings\", response_model=MaintenanceSettingsResponse)\nasync def update_maintenance_settings(\n settings_data: MaintenanceSettingsUpdate,\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"admin:settings\", \"WRITE\")),\n):\n with belief_scope(\"update_maintenance_settings\"):\n settings = db.query(MaintenanceSettings).filter(\n MaintenanceSettings.id == \"default\"\n ).first()\n\n if not settings:\n # Auto-create with defaults on first save (upsert behavior).\n # Column-level defaults from the model apply for omitted fields.\n settings = MaintenanceSettings(\n id=\"default\",\n target_environment_id=settings_data.target_environment_id or \"\",\n )\n db.add(settings)\n db.flush()\n\n # Apply partial updates\n update_data = settings_data.model_dump(exclude_unset=True)\n\n if \"target_environment_id\" in update_data:\n settings.target_environment_id = update_data[\"target_environment_id\"]\n if \"display_timezone\" in update_data:\n settings.display_timezone = update_data[\"display_timezone\"]\n if \"banner_template\" in update_data:\n settings.banner_template = update_data[\"banner_template\"]\n if \"dashboard_scope\" in update_data:\n from ....models.maintenance import DashboardScope\n settings.dashboard_scope = DashboardScope(update_data[\"dashboard_scope\"])\n if \"excluded_dashboard_ids\" in update_data:\n settings.excluded_dashboard_ids = update_data[\"excluded_dashboard_ids\"]\n if \"forced_dashboard_ids\" in update_data:\n settings.forced_dashboard_ids = update_data[\"forced_dashboard_ids\"]\n\n db.commit()\n db.refresh(settings)\n\n return MaintenanceSettingsResponse(\n target_environment_id=settings.target_environment_id,\n display_timezone=settings.display_timezone,\n banner_template=settings.banner_template,\n dashboard_scope=settings.dashboard_scope.value,\n excluded_dashboard_ids=list(settings.excluded_dashboard_ids or []),\n forced_dashboard_ids=list(settings.forced_dashboard_ids or []),\n updated_at=settings.updated_at.isoformat() if settings.updated_at else None,\n )\n# #endregion update_maintenance_settings\n\n# #endregion MaintenanceRoutesModule\n"
},
{
"contract_id": "list_dashboard_banners",
@@ -12400,14 +12436,14 @@
{
"source_id": "list_dashboard_banners",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:code:has_permission(\"maintenance\", \"READ\")",
- "target_ref": "[EXT:code:has_permission(\"maintenance\", \"READ\")]"
+ "target_id": "EXT:code:has_permission_maintenance_READ",
+ "target_ref": "[EXT:code:has_permission_maintenance_READ]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region list_dashboard_banners [C:2] [TYPE Function]\n# @BRIEF Get per-dashboard banner state for the Dashboard Hub indicator.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"READ\")]\n@router.get(\"/dashboard-banners\", response_model=list[MaintenanceDashboardBannerState])\nasync def list_dashboard_banners(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"list_dashboard_banners\"):\n # Query active banners with their linked active/pending states\n active_banners = (\n db.query(MaintenanceDashboardBanner)\n .filter(MaintenanceDashboardBanner.status == MaintenanceDashboardBannerStatus.ACTIVE)\n .all()\n )\n\n result: list[MaintenanceDashboardBannerState] = []\n for banner in active_banners:\n linked_states = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.banner_id == banner.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .all()\n )\n\n event_ids: list[str] = []\n start_times: list[str] = []\n end_times: list[str] = []\n\n for state in linked_states:\n event = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.id == state.event_id)\n .first()\n )\n if event:\n event_ids.append(event.id)\n if event.start_time:\n start_times.append(event.start_time.isoformat())\n if event.end_time:\n end_times.append(event.end_time.isoformat())\n\n result.append(\n MaintenanceDashboardBannerState(\n dashboard_id=banner.dashboard_id,\n active=True,\n events=event_ids,\n start_time=min(start_times) if start_times else None,\n end_time=max(end_times) if end_times else None,\n )\n )\n\n return result\n# #endregion list_dashboard_banners\n"
+ "body": "# #region list_dashboard_banners [C:2] [TYPE Function]\n# @BRIEF Get per-dashboard banner state for the Dashboard Hub indicator.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]\n@router.get(\"/dashboard-banners\", response_model=list[MaintenanceDashboardBannerState])\nasync def list_dashboard_banners(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"list_dashboard_banners\"):\n # Query active banners with their linked active/pending states\n active_banners = (\n db.query(MaintenanceDashboardBanner)\n .filter(MaintenanceDashboardBanner.status == MaintenanceDashboardBannerStatus.ACTIVE)\n .all()\n )\n\n result: list[MaintenanceDashboardBannerState] = []\n for banner in active_banners:\n linked_states = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.banner_id == banner.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .all()\n )\n\n event_ids: list[str] = []\n start_times: list[str] = []\n end_times: list[str] = []\n\n for state in linked_states:\n event = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.id == state.event_id)\n .first()\n )\n if event:\n event_ids.append(event.id)\n if event.start_time:\n start_times.append(event.start_time.isoformat())\n if event.end_time:\n end_times.append(event.end_time.isoformat())\n\n result.append(\n MaintenanceDashboardBannerState(\n dashboard_id=banner.dashboard_id,\n active=True,\n events=event_ids,\n start_time=min(start_times) if start_times else None,\n end_time=max(end_times) if end_times else None,\n )\n )\n\n return result\n# #endregion list_dashboard_banners\n"
},
{
"contract_id": "list_events",
@@ -12425,14 +12461,14 @@
{
"source_id": "list_events",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:code:has_permission(\"maintenance\", \"READ\")",
- "target_ref": "[EXT:code:has_permission(\"maintenance\", \"READ\")]"
+ "target_id": "EXT:code:has_permission_maintenance_READ",
+ "target_ref": "[EXT:code:has_permission_maintenance_READ]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region list_events [C:2] [TYPE Function]\n# @BRIEF Get active and completed maintenance event lists with affected dashboard counts.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"READ\")]\n@router.get(\"/events\", response_model=MaintenanceEventListResponse)\nasync def list_events(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"list_events\"):\n # ── Auto-expiry: end events past their end_time ──\n now = datetime.now(timezone.utc)\n expired = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n MaintenanceEventStatus.ENDING,\n ]),\n MaintenanceEvent.end_time.isnot(None),\n MaintenanceEvent.end_time < now,\n )\n .all()\n )\n for ev in expired:\n app_logger.reason(\n \"Auto-ending expired maintenance event\",\n extra={\"event_id\": ev.id, \"end_time\": ev.end_time.isoformat()},\n )\n # Schedule proper cleanup via task manager (removes banner from dashboard)\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end\",\n \"event_id\": ev.id,\n \"environment_id\": ev.environment_id,\n \"user\": \"system\",\n },\n )\n app_logger.reflect(\n \"Scheduled cleanup for expired event\",\n extra={\"event_id\": ev.id, \"task_id\": task.id},\n )\n\n # Active events: ACTIVE, PARTIAL (per spec T040)\n active_statuses = [\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n ]\n active_events = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.status.in_(active_statuses))\n .order_by(MaintenanceEvent.created_at.desc())\n .all()\n )\n\n # Completed events: COMPLETED, FAILED\n completed_events = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.COMPLETED,\n MaintenanceEventStatus.FAILED,\n ])\n )\n .order_by(MaintenanceEvent.created_at.desc())\n .limit(50)\n .all()\n )\n\n def _to_item(event: MaintenanceEvent) -> MaintenanceEventItem:\n affected_count = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.event_id == event.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .count()\n )\n return MaintenanceEventItem(\n id=event.id,\n tables=list(event.tables) if event.tables else [],\n start_time=event.start_time.isoformat() if event.start_time else \"\",\n end_time=event.end_time.isoformat() if event.end_time else None,\n message=event.message or None,\n status=event.status.value,\n affected_count=affected_count,\n created_at=event.created_at.isoformat() if event.created_at else \"\",\n )\n\n return MaintenanceEventListResponse(\n active=[_to_item(e) for e in active_events],\n completed=[_to_item(e) for e in completed_events],\n )\n# #endregion list_events\n"
+ "body": "# #region list_events [C:2] [TYPE Function]\n# @BRIEF Get active and completed maintenance event lists with affected dashboard counts.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]\n@router.get(\"/events\", response_model=MaintenanceEventListResponse)\nasync def list_events(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n task_manager: TaskManager = Depends(get_task_manager),\n):\n with belief_scope(\"list_events\"):\n # ── Auto-expiry: end events past their end_time ──\n now = datetime.now(timezone.utc)\n expired = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n MaintenanceEventStatus.ENDING,\n ]),\n MaintenanceEvent.end_time.isnot(None),\n MaintenanceEvent.end_time < now,\n )\n .all()\n )\n for ev in expired:\n app_logger.reason(\n \"Auto-ending expired maintenance event\",\n extra={\"event_id\": ev.id, \"end_time\": ev.end_time.isoformat()},\n )\n # Schedule proper cleanup via task manager (removes banner from dashboard)\n task = await task_manager.create_task(\n plugin_id=\"maintenance_banner_apply\",\n params={\n \"operation\": \"end\",\n \"event_id\": ev.id,\n \"environment_id\": ev.environment_id,\n \"user\": \"system\",\n },\n )\n app_logger.reflect(\n \"Scheduled cleanup for expired event\",\n extra={\"event_id\": ev.id, \"task_id\": task.id},\n )\n\n # Active events: ACTIVE, PARTIAL (per spec T040)\n active_statuses = [\n MaintenanceEventStatus.ACTIVE,\n MaintenanceEventStatus.PARTIAL,\n ]\n active_events = (\n db.query(MaintenanceEvent)\n .filter(MaintenanceEvent.status.in_(active_statuses))\n .order_by(MaintenanceEvent.created_at.desc())\n .all()\n )\n\n # Completed events: COMPLETED, FAILED\n completed_events = (\n db.query(MaintenanceEvent)\n .filter(\n MaintenanceEvent.status.in_([\n MaintenanceEventStatus.COMPLETED,\n MaintenanceEventStatus.FAILED,\n ])\n )\n .order_by(MaintenanceEvent.created_at.desc())\n .limit(50)\n .all()\n )\n\n def _to_item(event: MaintenanceEvent) -> MaintenanceEventItem:\n affected_count = (\n db.query(MaintenanceDashboardState)\n .filter(\n MaintenanceDashboardState.event_id == event.id,\n MaintenanceDashboardState.status.in_([\n MaintenanceDashboardStateStatus.ACTIVE,\n MaintenanceDashboardStateStatus.PENDING_APPLY,\n ]),\n )\n .count()\n )\n return MaintenanceEventItem(\n id=event.id,\n tables=list(event.tables) if event.tables else [],\n start_time=event.start_time.isoformat() if event.start_time else \"\",\n end_time=event.end_time.isoformat() if event.end_time else None,\n message=event.message or None,\n status=event.status.value,\n affected_count=affected_count,\n created_at=event.created_at.isoformat() if event.created_at else \"\",\n )\n\n return MaintenanceEventListResponse(\n active=[_to_item(e) for e in active_events],\n completed=[_to_item(e) for e in completed_events],\n )\n# #endregion list_events\n"
},
{
"contract_id": "start_maintenance",
@@ -12504,14 +12540,14 @@
{
"source_id": "get_maintenance_settings",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:code:has_permission(\"maintenance\", \"READ\")",
- "target_ref": "[EXT:code:has_permission(\"maintenance\", \"READ\")]"
+ "target_id": "EXT:code:has_permission_maintenance_READ",
+ "target_ref": "[EXT:code:has_permission_maintenance_READ]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region get_maintenance_settings [C:2] [TYPE Function]\n# @BRIEF Get current maintenance settings configuration.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission(\"maintenance\", \"READ\")]\n@router.get(\"/settings\", response_model=MaintenanceSettingsResponse)\nasync def get_maintenance_settings(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"get_maintenance_settings\"):\n settings = db.query(MaintenanceSettings).filter(\n MaintenanceSettings.id == \"default\"\n ).first()\n\n if not settings:\n raise HTTPException(\n status_code=404,\n detail=\"Maintenance settings not configured\",\n )\n\n return MaintenanceSettingsResponse(\n target_environment_id=settings.target_environment_id,\n display_timezone=settings.display_timezone,\n banner_template=settings.banner_template,\n dashboard_scope=settings.dashboard_scope.value,\n excluded_dashboard_ids=list(settings.excluded_dashboard_ids or []),\n forced_dashboard_ids=list(settings.forced_dashboard_ids or []),\n updated_at=settings.updated_at.isoformat() if settings.updated_at else None,\n )\n# #endregion get_maintenance_settings\n"
+ "body": "# #region get_maintenance_settings [C:2] [TYPE Function]\n# @BRIEF Get current maintenance settings configuration.\n# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]\n@router.get(\"/settings\", response_model=MaintenanceSettingsResponse)\nasync def get_maintenance_settings(\n db: Session = Depends(get_db),\n _=Depends(has_permission(\"maintenance\", \"READ\")),\n):\n with belief_scope(\"get_maintenance_settings\"):\n settings = db.query(MaintenanceSettings).filter(\n MaintenanceSettings.id == \"default\"\n ).first()\n\n if not settings:\n raise HTTPException(\n status_code=404,\n detail=\"Maintenance settings not configured\",\n )\n\n return MaintenanceSettingsResponse(\n target_environment_id=settings.target_environment_id,\n display_timezone=settings.display_timezone,\n banner_template=settings.banner_template,\n dashboard_scope=settings.dashboard_scope.value,\n excluded_dashboard_ids=list(settings.excluded_dashboard_ids or []),\n forced_dashboard_ids=list(settings.forced_dashboard_ids or []),\n updated_at=settings.updated_at.isoformat() if settings.updated_at else None,\n )\n# #endregion get_maintenance_settings\n"
},
{
"contract_id": "update_maintenance_settings",
@@ -16943,14 +16979,14 @@
{
"source_id": "NativeFilterExtractionTests",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge]",
- "target_ref": "[[EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge]]"
+ "target_id": "FilterState",
+ "target_ref": "[FilterState]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region NativeFilterExtractionTests [TYPE Module] [C:3] [SEMANTICS tests, superset, native, filters, permalink, filter_state]\n# @BRIEF Verify native filter extraction from permalinks and native_filters_key URLs.\n# @LAYER Domain\n# @RELATION BINDS_TO ->[SupersetClient]\n# @RELATION BINDS_TO ->[AsyncSupersetClient]\n# @RELATION BINDS_TO ->[[EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge]]\nimport json\nfrom unittest.mock import MagicMock\n\nfrom src.core.config_models import Environment\nfrom src.core.superset_client import SupersetClient\nfrom src.core.utils.superset_context_extractor import (\n SupersetContextExtractor,\n SupersetParsedContext,\n sanitize_imported_filter_for_assistant,\n)\nfrom src.models.filter_state import (\n ExtraFormDataMerge,\n FilterState,\n NativeFilterDataMask,\n ParsedNativeFilters,\n)\n\n\n# #region _make_environment [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\ndef _make_environment() -> Environment:\n return Environment(\n id=\"env-1\",\n name=\"DEV\",\n url=\"http://superset.local\",\n username=\"demo\",\n password=\"secret\",\n )\n# #endregion _make_environment\n# #region test_extract_native_filters_from_permalink [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Extract native filters from a permalink key.\ndef test_extract_native_filters_from_permalink():\n client = SupersetClient(_make_environment())\n client.get_dashboard_permalink_state = MagicMock(\n return_value={\n \"result\": {\n \"state\": {\n \"dataMask\": {\n \"filter_country\": {\n \"extraFormData\": {\n \"filters\": [\n {\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}\n ]\n },\n \"filterState\": {\"value\": [\"DE\", \"FR\"]},\n \"ownState\": {},\n },\n \"filter_date\": {\n \"extraFormData\": {\"time_range\": \"2020-01-01 : 2024-12-31\"},\n \"filterState\": {\"value\": \"2020-01-01 : 2024-12-31\"},\n \"ownState\": {},\n },\n },\n \"activeTabs\": [\"tab1\", \"tab2\"],\n \"anchor\": \"SECTION1\",\n \"chartStates\": {\"chart_1\": {}},\n }\n }\n }\n )\n result = client.extract_native_filters_from_permalink(\"test-permalink-key\")\n assert result[\"permalink_key\"] == \"test-permalink-key\"\n assert \"dataMask\" in result\n assert \"filter_country\" in result[\"dataMask\"]\n assert \"filter_date\" in result[\"dataMask\"]\n assert result[\"dataMask\"][\"filter_country\"][\"extraFormData\"][\"filters\"][0][\n \"val\"\n ] == [\"DE\", \"FR\"]\n assert result[\"activeTabs\"] == [\"tab1\", \"tab2\"]\n assert result[\"anchor\"] == \"SECTION1\"\n# #endregion test_extract_native_filters_from_permalink\n# #region test_extract_native_filters_from_permalink_direct_response [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Handle permalink response without result wrapper.\ndef test_extract_native_filters_from_permalink_direct_response():\n client = SupersetClient(_make_environment())\n client.get_dashboard_permalink_state = MagicMock(\n return_value={\n \"state\": {\n \"dataMask\": {\n \"filter_1\": {\n \"extraFormData\": {\"filters\": []},\n \"filterState\": {},\n \"ownState\": {},\n }\n }\n }\n }\n )\n result = client.extract_native_filters_from_permalink(\"direct-key\")\n assert result[\"permalink_key\"] == \"direct-key\"\n assert \"filter_1\" in result[\"dataMask\"]\n# #endregion test_extract_native_filters_from_permalink_direct_response\n# #region test_extract_native_filters_from_key [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Extract native filters from a native_filters_key.\ndef test_extract_native_filters_from_key():\n client = SupersetClient(_make_environment())\n client.get_native_filter_state = MagicMock(\n return_value={\n \"result\": {\n \"value\": json.dumps(\n {\n \"filter_region\": {\n \"id\": \"filter_region\",\n \"extraFormData\": {\n \"filters\": [\n {\"col\": \"region\", \"op\": \"IN\", \"val\": [\"EMEA\"]}\n ]\n },\n \"filterState\": {\"value\": [\"EMEA\"]},\n }\n }\n )\n }\n }\n )\n result = client.extract_native_filters_from_key(123, \"filter-state-key\")\n assert result[\"dashboard_id\"] == 123\n assert result[\"filter_state_key\"] == \"filter-state-key\"\n assert \"dataMask\" in result\n assert \"filter_region\" in result[\"dataMask\"]\n assert result[\"dataMask\"][\"filter_region\"][\"extraFormData\"][\"filters\"][0][\n \"val\"\n ] == [\"EMEA\"]\n# #endregion test_extract_native_filters_from_key\n# #region test_extract_native_filters_from_key_single_filter [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Handle single filter format in native filter state.\ndef test_extract_native_filters_from_key_single_filter():\n client = SupersetClient(_make_environment())\n client.get_native_filter_state = MagicMock(\n return_value={\n \"result\": {\n \"value\": json.dumps(\n {\n \"id\": \"single_filter\",\n \"extraFormData\": {\n \"filters\": [{\"col\": \"status\", \"op\": \"==\", \"val\": \"active\"}]\n },\n \"filterState\": {\"value\": \"active\"},\n }\n )\n }\n }\n )\n result = client.extract_native_filters_from_key(456, \"single-key\")\n assert \"dataMask\" in result\n assert \"single_filter\" in result[\"dataMask\"]\n assert (\n result[\"dataMask\"][\"single_filter\"][\"extraFormData\"][\"filters\"][0][\"col\"]\n == \"status\"\n )\n# #endregion test_extract_native_filters_from_key_single_filter\n# #region test_extract_native_filters_from_key_dict_value [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Handle filter state value as dict instead of JSON string.\ndef test_extract_native_filters_from_key_dict_value():\n client = SupersetClient(_make_environment())\n client.get_native_filter_state = MagicMock(\n return_value={\n \"result\": {\n \"value\": {\n \"filter_id\": {\n \"extraFormData\": {\"filters\": []},\n \"filterState\": {},\n }\n }\n }\n }\n )\n result = client.extract_native_filters_from_key(789, \"dict-key\")\n assert \"dataMask\" in result\n assert \"filter_id\" in result[\"dataMask\"]\n# #endregion test_extract_native_filters_from_key_dict_value\n# #region test_parse_dashboard_url_for_filters_permalink [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse permalink URL format.\ndef test_parse_dashboard_url_for_filters_permalink():\n client = SupersetClient(_make_environment())\n client.extract_native_filters_from_permalink = MagicMock(\n return_value={\"dataMask\": {\"f1\": {}}, \"permalink_key\": \"abc123\"}\n )\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/superset/dashboard/p/abc123/\"\n )\n assert result[\"filter_type\"] == \"permalink\"\n assert result[\"filters\"][\"dataMask\"][\"f1\"] == {}\n# #endregion test_parse_dashboard_url_for_filters_permalink\n# #region test_parse_dashboard_url_for_filters_native_key [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse native_filters_key URL format with numeric dashboard ID.\ndef test_parse_dashboard_url_for_filters_native_key():\n client = SupersetClient(_make_environment())\n client.extract_native_filters_from_key = MagicMock(\n return_value={\n \"dataMask\": {\"f2\": {}},\n \"dashboard_id\": 42,\n \"filter_state_key\": \"xyz\",\n }\n )\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/42/?native_filters_key=xyz\"\n )\n assert result[\"filter_type\"] == \"native_filters_key\"\n assert result[\"dashboard_id\"] == 42\n assert result[\"filters\"][\"dataMask\"][\"f2\"] == {}\n# #endregion test_parse_dashboard_url_for_filters_native_key\n# #region test_parse_dashboard_url_for_filters_native_key_slug [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse native_filters_key URL format when dashboard reference is a slug, not a numeric ID.\ndef test_parse_dashboard_url_for_filters_native_key_slug():\n client = SupersetClient(_make_environment())\n # Simulate slug resolution: get_dashboard returns the dashboard with numeric ID\n client.get_dashboard = MagicMock(\n return_value={\n \"result\": {\"id\": 99, \"dashboard_title\": \"COVID Dashboard\", \"slug\": \"covid\"}\n }\n )\n client.extract_native_filters_from_key = MagicMock(\n return_value={\n \"dataMask\": {\"f_slug\": {}},\n \"dashboard_id\": 99,\n \"filter_state_key\": \"abc123\",\n }\n )\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/superset/dashboard/covid/?native_filters_key=abc123\"\n )\n assert result[\"filter_type\"] == \"native_filters_key\"\n assert result[\"dashboard_id\"] == 99\n assert result[\"filters\"][\"dataMask\"][\"f_slug\"] == {}\n client.get_dashboard.assert_called_once_with(\"covid\")\n client.extract_native_filters_from_key.assert_called_once_with(99, \"abc123\")\n# #endregion test_parse_dashboard_url_for_filters_native_key_slug\n# #region test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Gracefully handle slug resolution failure for native_filters_key URL.\ndef test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails():\n client = SupersetClient(_make_environment())\n client.get_dashboard = MagicMock(side_effect=Exception(\"Not found\"))\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/unknownslug/?native_filters_key=key1\"\n )\n assert result[\"filter_type\"] is None\n assert result[\"dashboard_id\"] is None\n# #endregion test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails\n# #region test_parse_dashboard_url_for_filters_native_filters_direct [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse native_filters direct query param.\ndef test_parse_dashboard_url_for_filters_native_filters_direct():\n client = SupersetClient(_make_environment())\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/1/?native_filters=\"\n + json.dumps({\"filter_1\": {\"col\": \"x\", \"op\": \"==\", \"val\": \"y\"}})\n )\n assert result[\"filter_type\"] == \"native_filters\"\n assert \"dataMask\" in result[\"filters\"]\n# #endregion test_parse_dashboard_url_for_filters_native_filters_direct\n# #region test_parse_dashboard_url_for_filters_no_filters [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Return empty result when no filters present.\ndef test_parse_dashboard_url_for_filters_no_filters():\n client = SupersetClient(_make_environment())\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/1/\"\n )\n assert result[\"filter_type\"] is None\n assert result[\"filters\"] == {}\n# #endregion test_parse_dashboard_url_for_filters_no_filters\n# #region test_extra_form_data_merge [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test ExtraFormDataMerge correctly merges dictionaries.\ndef test_extra_form_data_merge():\n merger = ExtraFormDataMerge()\n original = {\n \"filters\": [{\"col\": \"a\", \"op\": \"IN\", \"val\": [1, 2]}],\n \"time_range\": \"2020-01-01 : 2021-01-01\",\n \"extras\": {\"where\": \"x > 0\"},\n }\n new = {\n \"filters\": [{\"col\": \"b\", \"op\": \"==\", \"val\": \"test\"}],\n \"time_range\": \"2022-01-01 : 2023-01-01\",\n \"columns\": [\"col1\", \"col2\"],\n }\n result = merger.merge(original, new)\n # Filters should be appended\n assert len(result[\"filters\"]) == 2\n assert result[\"filters\"][0][\"col\"] == \"a\"\n assert result[\"filters\"][1][\"col\"] == \"b\"\n # Time range should be overridden\n assert result[\"time_range\"] == \"2022-01-01 : 2023-01-01\"\n # Extras should remain\n assert result[\"extras\"] == {\"where\": \"x > 0\"}\n # New columns should be added\n assert result[\"columns\"] == [\"col1\", \"col2\"]\n# #endregion test_extra_form_data_merge\n# #region test_filter_state_model [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test FilterState Pydantic model.\ndef test_filter_state_model():\n state = FilterState(\n extraFormData={\"filters\": [{\"col\": \"x\", \"op\": \"==\", \"val\": \"y\"}]},\n filterState={\"value\": \"y\"},\n ownState={\"selectedValues\": [\"y\"]},\n )\n assert state.extraFormData[\"filters\"][0][\"col\"] == \"x\"\n assert state.filterState[\"value\"] == \"y\"\n assert state.ownState[\"selectedValues\"] == [\"y\"]\n# #endregion test_filter_state_model\n# #region test_parsed_native_filters_model [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test ParsedNativeFilters Pydantic model.\ndef test_parsed_native_filters_model():\n filters = ParsedNativeFilters(\n dataMask={\"f1\": {\"extraFormData\": {}, \"filterState\": {}}},\n filter_type=\"permalink\",\n dashboard_id=\"42\",\n permalink_key=\"abc\",\n )\n assert filters.has_filters() is True\n assert filters.get_filter_count() == 1\n assert filters.filter_type == \"permalink\"\n# #endregion test_parsed_native_filters_model\n# #region test_parsed_native_filters_empty [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test ParsedNativeFilters with no filters.\ndef test_parsed_native_filters_empty():\n filters = ParsedNativeFilters()\n assert filters.has_filters() is False\n assert filters.get_filter_count() == 0\n# #endregion test_parsed_native_filters_empty\n# #region test_native_filter_data_mask_model [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test NativeFilterDataMask model.\ndef test_native_filter_data_mask_model():\n data_mask = NativeFilterDataMask(\n filters={\n \"filter_1\": FilterState(extraFormData={\"filters\": []}, filterState={}),\n \"filter_2\": FilterState(\n extraFormData={\"time_range\": \"...\"}, filterState={}\n ),\n }\n )\n assert data_mask.get_filter_ids() == [\"filter_1\", \"filter_2\"]\n assert data_mask.get_extra_form_data(\"filter_1\") == {\"filters\": []}\n assert data_mask.get_extra_form_data(\"nonexistent\") == {}\n# #endregion test_native_filter_data_mask_model\n# #region test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Reconcile raw native filter ids from state to canonical metadata filter names.\ndef test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names():\n client = MagicMock()\n client.get_dashboard.return_value = {\n \"result\": {\n \"json_metadata\": json.dumps(\n {\n \"native_filter_configuration\": [\n {\n \"id\": \"NATIVE_FILTER-EWNH3M70z\",\n \"name\": \"Country\",\n \"label\": \"Country\",\n }\n ]\n }\n )\n }\n }\n extractor = SupersetContextExtractor(_make_environment(), client=client)\n parsed_context = SupersetParsedContext(\n source_url=\"http://superset.local/dashboard/42/?native_filters_key=abc\",\n dataset_ref=\"dataset:42\",\n dashboard_id=42,\n imported_filters=[\n {\n \"filter_name\": \"NATIVE_FILTER-EWNH3M70z\",\n \"display_name\": \"NATIVE_FILTER-EWNH3M70z\",\n \"raw_value\": [\"DE\", \"FR\"],\n \"normalized_value\": {\n \"filter_clauses\": [\n {\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}\n ],\n \"extra_form_data\": {\n \"filters\": [{\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}]\n },\n \"value_origin\": \"filter_state\",\n },\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ],\n )\n result = extractor.recover_imported_filters(parsed_context)\n assert len(result) == 1\n assert result[0][\"filter_name\"] == \"Country\"\n assert result[0][\"display_name\"] == \"Country\"\n assert result[0][\"raw_value\"] == [\"DE\", \"FR\"]\n assert result[0][\"source\"] == \"superset_native_filters_key\"\n assert result[0][\"normalized_value\"] == {\n \"filter_clauses\": [{\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}],\n \"extra_form_data\": {\n \"filters\": [{\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}]\n },\n \"value_origin\": \"filter_state\",\n }\n# #endregion test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names\n# #region test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Collapse raw-id state entries and metadata entries into one canonical filter.\ndef test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter():\n client = MagicMock()\n client.get_dashboard.return_value = {\n \"result\": {\n \"json_metadata\": json.dumps(\n {\n \"native_filter_configuration\": [\n {\n \"id\": \"NATIVE_FILTER-EWNH3M70z\",\n \"name\": \"Country\",\n \"label\": \"Country\",\n },\n {\n \"id\": \"NATIVE_FILTER-vv123\",\n \"name\": \"Region\",\n \"label\": \"Region\",\n },\n ]\n }\n )\n }\n }\n extractor = SupersetContextExtractor(_make_environment(), client=client)\n parsed_context = SupersetParsedContext(\n source_url=\"http://superset.local/dashboard/42/?native_filters_key=abc\",\n dataset_ref=\"dataset:42\",\n dashboard_id=42,\n imported_filters=[\n {\n \"filter_name\": \"NATIVE_FILTER-EWNH3M70z\",\n \"display_name\": \"Country\",\n \"raw_value\": [\"DE\", \"FR\"],\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ],\n )\n result = extractor.recover_imported_filters(parsed_context)\n assert len(result) == 2\n country_filter = next(item for item in result if item[\"filter_name\"] == \"Country\")\n region_filter = next(item for item in result if item[\"filter_name\"] == \"Region\")\n assert country_filter[\"raw_value\"] == [\"DE\", \"FR\"]\n assert country_filter[\"recovery_status\"] == \"recovered\"\n assert region_filter[\"raw_value\"] is None\n assert region_filter[\"recovery_status\"] == \"partial\"\n# #endregion test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter\n# #region test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Preserve unmatched raw native filter ids as fallback diagnostics when metadata mapping is unavailable.\ndef test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids():\n client = MagicMock()\n client.get_dashboard.return_value = {\n \"result\": {\n \"json_metadata\": json.dumps(\n {\n \"native_filter_configuration\": [\n {\n \"id\": \"NATIVE_FILTER-EWNH3M70z\",\n \"name\": \"Country\",\n \"label\": \"Country\",\n }\n ]\n }\n )\n }\n }\n extractor = SupersetContextExtractor(_make_environment(), client=client)\n parsed_context = SupersetParsedContext(\n source_url=\"http://superset.local/dashboard/42/?native_filters_key=abc\",\n dataset_ref=\"dataset:42\",\n dashboard_id=42,\n imported_filters=[\n {\n \"filter_name\": \"UNKNOWN_NATIVE_FILTER\",\n \"display_name\": \"UNKNOWN_NATIVE_FILTER\",\n \"raw_value\": [\"orphan\"],\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ],\n )\n result = extractor.recover_imported_filters(parsed_context)\n assert len(result) == 2\n assert any(\n item[\"filter_name\"] == \"Country\" and item[\"recovery_status\"] == \"partial\"\n for item in result\n )\n assert any(\n item[\"filter_name\"] == \"UNKNOWN_NATIVE_FILTER\"\n and item[\"raw_value\"] == [\"orphan\"]\n and item[\"source\"] == \"superset_native_filters_key\"\n for item in result\n )\n# #endregion test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids\n# #region test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Recovered native filter state should preserve exact Superset clause payload and time extras for preview compilation.\ndef test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview():\n extractor = SupersetContextExtractor(_make_environment(), client=MagicMock())\n imported_filters = extractor._extract_imported_filters(\n {\n \"native_filter_state\": {\n \"NATIVE_FILTER-1\": {\n \"id\": \"NATIVE_FILTER-1\",\n \"filterState\": {\"label\": \"Country\", \"value\": [\"DE\"]},\n \"extraFormData\": {\n \"filters\": [{\"col\": \"country_code\", \"op\": \"IN\", \"val\": [\"DE\"]}],\n \"time_range\": \"Last month\",\n },\n }\n }\n }\n )\n assert imported_filters == [\n {\n \"filter_name\": \"NATIVE_FILTER-1\",\n \"raw_value\": [\"DE\"],\n \"display_name\": \"Country\",\n \"normalized_value\": {\n \"filter_clauses\": [{\"col\": \"country_code\", \"op\": \"IN\", \"val\": [\"DE\"]}],\n \"extra_form_data\": {\n \"filters\": [{\"col\": \"country_code\", \"op\": \"IN\", \"val\": [\"DE\"]}],\n \"time_range\": \"Last month\",\n },\n \"value_origin\": \"filter_state\",\n },\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ]\n# #endregion test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview\n# #region test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Assistant-facing imported-filter payload should redact likely PII while preserving structure metadata.\ndef test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values():\n result = sanitize_imported_filter_for_assistant(\n {\n \"filter_name\": \"customer_email\",\n \"raw_value\": [\"alice@example.com\", \"1234567890\"],\n \"normalized_value\": {\"filter_clauses\": []},\n \"source\": \"manual\",\n }\n )\n assert result[\"raw_value\"] == [\"***@example.com\", \"********90\"]\n assert result[\"raw_value_masked\"] is True\n assert result[\"normalized_value\"] == {\"filter_clauses\": []}\n# #endregion test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values\n# #endregion NativeFilterExtractionTests\n"
+ "body": "# #region NativeFilterExtractionTests [TYPE Module] [C:3] [SEMANTICS tests, superset, native, filters, permalink, filter_state]\n# @BRIEF Verify native filter extraction from permalinks and native_filters_key URLs.\n# @LAYER Domain\n# @RELATION BINDS_TO ->[SupersetClient]\n# @RELATION BINDS_TO ->[AsyncSupersetClient]\n# @RELATION BINDS_TO ->[FilterState]\nimport json\nfrom unittest.mock import MagicMock\n\nfrom src.core.config_models import Environment\nfrom src.core.superset_client import SupersetClient\nfrom src.core.utils.superset_context_extractor import (\n SupersetContextExtractor,\n SupersetParsedContext,\n sanitize_imported_filter_for_assistant,\n)\nfrom src.models.filter_state import (\n ExtraFormDataMerge,\n FilterState,\n NativeFilterDataMask,\n ParsedNativeFilters,\n)\n\n\n# #region _make_environment [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\ndef _make_environment() -> Environment:\n return Environment(\n id=\"env-1\",\n name=\"DEV\",\n url=\"http://superset.local\",\n username=\"demo\",\n password=\"secret\",\n )\n# #endregion _make_environment\n# #region test_extract_native_filters_from_permalink [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Extract native filters from a permalink key.\ndef test_extract_native_filters_from_permalink():\n client = SupersetClient(_make_environment())\n client.get_dashboard_permalink_state = MagicMock(\n return_value={\n \"result\": {\n \"state\": {\n \"dataMask\": {\n \"filter_country\": {\n \"extraFormData\": {\n \"filters\": [\n {\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}\n ]\n },\n \"filterState\": {\"value\": [\"DE\", \"FR\"]},\n \"ownState\": {},\n },\n \"filter_date\": {\n \"extraFormData\": {\"time_range\": \"2020-01-01 : 2024-12-31\"},\n \"filterState\": {\"value\": \"2020-01-01 : 2024-12-31\"},\n \"ownState\": {},\n },\n },\n \"activeTabs\": [\"tab1\", \"tab2\"],\n \"anchor\": \"SECTION1\",\n \"chartStates\": {\"chart_1\": {}},\n }\n }\n }\n )\n result = client.extract_native_filters_from_permalink(\"test-permalink-key\")\n assert result[\"permalink_key\"] == \"test-permalink-key\"\n assert \"dataMask\" in result\n assert \"filter_country\" in result[\"dataMask\"]\n assert \"filter_date\" in result[\"dataMask\"]\n assert result[\"dataMask\"][\"filter_country\"][\"extraFormData\"][\"filters\"][0][\n \"val\"\n ] == [\"DE\", \"FR\"]\n assert result[\"activeTabs\"] == [\"tab1\", \"tab2\"]\n assert result[\"anchor\"] == \"SECTION1\"\n# #endregion test_extract_native_filters_from_permalink\n# #region test_extract_native_filters_from_permalink_direct_response [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Handle permalink response without result wrapper.\ndef test_extract_native_filters_from_permalink_direct_response():\n client = SupersetClient(_make_environment())\n client.get_dashboard_permalink_state = MagicMock(\n return_value={\n \"state\": {\n \"dataMask\": {\n \"filter_1\": {\n \"extraFormData\": {\"filters\": []},\n \"filterState\": {},\n \"ownState\": {},\n }\n }\n }\n }\n )\n result = client.extract_native_filters_from_permalink(\"direct-key\")\n assert result[\"permalink_key\"] == \"direct-key\"\n assert \"filter_1\" in result[\"dataMask\"]\n# #endregion test_extract_native_filters_from_permalink_direct_response\n# #region test_extract_native_filters_from_key [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Extract native filters from a native_filters_key.\ndef test_extract_native_filters_from_key():\n client = SupersetClient(_make_environment())\n client.get_native_filter_state = MagicMock(\n return_value={\n \"result\": {\n \"value\": json.dumps(\n {\n \"filter_region\": {\n \"id\": \"filter_region\",\n \"extraFormData\": {\n \"filters\": [\n {\"col\": \"region\", \"op\": \"IN\", \"val\": [\"EMEA\"]}\n ]\n },\n \"filterState\": {\"value\": [\"EMEA\"]},\n }\n }\n )\n }\n }\n )\n result = client.extract_native_filters_from_key(123, \"filter-state-key\")\n assert result[\"dashboard_id\"] == 123\n assert result[\"filter_state_key\"] == \"filter-state-key\"\n assert \"dataMask\" in result\n assert \"filter_region\" in result[\"dataMask\"]\n assert result[\"dataMask\"][\"filter_region\"][\"extraFormData\"][\"filters\"][0][\n \"val\"\n ] == [\"EMEA\"]\n# #endregion test_extract_native_filters_from_key\n# #region test_extract_native_filters_from_key_single_filter [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Handle single filter format in native filter state.\ndef test_extract_native_filters_from_key_single_filter():\n client = SupersetClient(_make_environment())\n client.get_native_filter_state = MagicMock(\n return_value={\n \"result\": {\n \"value\": json.dumps(\n {\n \"id\": \"single_filter\",\n \"extraFormData\": {\n \"filters\": [{\"col\": \"status\", \"op\": \"==\", \"val\": \"active\"}]\n },\n \"filterState\": {\"value\": \"active\"},\n }\n )\n }\n }\n )\n result = client.extract_native_filters_from_key(456, \"single-key\")\n assert \"dataMask\" in result\n assert \"single_filter\" in result[\"dataMask\"]\n assert (\n result[\"dataMask\"][\"single_filter\"][\"extraFormData\"][\"filters\"][0][\"col\"]\n == \"status\"\n )\n# #endregion test_extract_native_filters_from_key_single_filter\n# #region test_extract_native_filters_from_key_dict_value [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Handle filter state value as dict instead of JSON string.\ndef test_extract_native_filters_from_key_dict_value():\n client = SupersetClient(_make_environment())\n client.get_native_filter_state = MagicMock(\n return_value={\n \"result\": {\n \"value\": {\n \"filter_id\": {\n \"extraFormData\": {\"filters\": []},\n \"filterState\": {},\n }\n }\n }\n }\n )\n result = client.extract_native_filters_from_key(789, \"dict-key\")\n assert \"dataMask\" in result\n assert \"filter_id\" in result[\"dataMask\"]\n# #endregion test_extract_native_filters_from_key_dict_value\n# #region test_parse_dashboard_url_for_filters_permalink [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse permalink URL format.\ndef test_parse_dashboard_url_for_filters_permalink():\n client = SupersetClient(_make_environment())\n client.extract_native_filters_from_permalink = MagicMock(\n return_value={\"dataMask\": {\"f1\": {}}, \"permalink_key\": \"abc123\"}\n )\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/superset/dashboard/p/abc123/\"\n )\n assert result[\"filter_type\"] == \"permalink\"\n assert result[\"filters\"][\"dataMask\"][\"f1\"] == {}\n# #endregion test_parse_dashboard_url_for_filters_permalink\n# #region test_parse_dashboard_url_for_filters_native_key [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse native_filters_key URL format with numeric dashboard ID.\ndef test_parse_dashboard_url_for_filters_native_key():\n client = SupersetClient(_make_environment())\n client.extract_native_filters_from_key = MagicMock(\n return_value={\n \"dataMask\": {\"f2\": {}},\n \"dashboard_id\": 42,\n \"filter_state_key\": \"xyz\",\n }\n )\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/42/?native_filters_key=xyz\"\n )\n assert result[\"filter_type\"] == \"native_filters_key\"\n assert result[\"dashboard_id\"] == 42\n assert result[\"filters\"][\"dataMask\"][\"f2\"] == {}\n# #endregion test_parse_dashboard_url_for_filters_native_key\n# #region test_parse_dashboard_url_for_filters_native_key_slug [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse native_filters_key URL format when dashboard reference is a slug, not a numeric ID.\ndef test_parse_dashboard_url_for_filters_native_key_slug():\n client = SupersetClient(_make_environment())\n # Simulate slug resolution: get_dashboard returns the dashboard with numeric ID\n client.get_dashboard = MagicMock(\n return_value={\n \"result\": {\"id\": 99, \"dashboard_title\": \"COVID Dashboard\", \"slug\": \"covid\"}\n }\n )\n client.extract_native_filters_from_key = MagicMock(\n return_value={\n \"dataMask\": {\"f_slug\": {}},\n \"dashboard_id\": 99,\n \"filter_state_key\": \"abc123\",\n }\n )\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/superset/dashboard/covid/?native_filters_key=abc123\"\n )\n assert result[\"filter_type\"] == \"native_filters_key\"\n assert result[\"dashboard_id\"] == 99\n assert result[\"filters\"][\"dataMask\"][\"f_slug\"] == {}\n client.get_dashboard.assert_called_once_with(\"covid\")\n client.extract_native_filters_from_key.assert_called_once_with(99, \"abc123\")\n# #endregion test_parse_dashboard_url_for_filters_native_key_slug\n# #region test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Gracefully handle slug resolution failure for native_filters_key URL.\ndef test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails():\n client = SupersetClient(_make_environment())\n client.get_dashboard = MagicMock(side_effect=Exception(\"Not found\"))\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/unknownslug/?native_filters_key=key1\"\n )\n assert result[\"filter_type\"] is None\n assert result[\"dashboard_id\"] is None\n# #endregion test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails\n# #region test_parse_dashboard_url_for_filters_native_filters_direct [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Parse native_filters direct query param.\ndef test_parse_dashboard_url_for_filters_native_filters_direct():\n client = SupersetClient(_make_environment())\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/1/?native_filters=\"\n + json.dumps({\"filter_1\": {\"col\": \"x\", \"op\": \"==\", \"val\": \"y\"}})\n )\n assert result[\"filter_type\"] == \"native_filters\"\n assert \"dataMask\" in result[\"filters\"]\n# #endregion test_parse_dashboard_url_for_filters_native_filters_direct\n# #region test_parse_dashboard_url_for_filters_no_filters [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Return empty result when no filters present.\ndef test_parse_dashboard_url_for_filters_no_filters():\n client = SupersetClient(_make_environment())\n result = client.parse_dashboard_url_for_filters(\n \"http://superset.local/dashboard/1/\"\n )\n assert result[\"filter_type\"] is None\n assert result[\"filters\"] == {}\n# #endregion test_parse_dashboard_url_for_filters_no_filters\n# #region test_extra_form_data_merge [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test ExtraFormDataMerge correctly merges dictionaries.\ndef test_extra_form_data_merge():\n merger = ExtraFormDataMerge()\n original = {\n \"filters\": [{\"col\": \"a\", \"op\": \"IN\", \"val\": [1, 2]}],\n \"time_range\": \"2020-01-01 : 2021-01-01\",\n \"extras\": {\"where\": \"x > 0\"},\n }\n new = {\n \"filters\": [{\"col\": \"b\", \"op\": \"==\", \"val\": \"test\"}],\n \"time_range\": \"2022-01-01 : 2023-01-01\",\n \"columns\": [\"col1\", \"col2\"],\n }\n result = merger.merge(original, new)\n # Filters should be appended\n assert len(result[\"filters\"]) == 2\n assert result[\"filters\"][0][\"col\"] == \"a\"\n assert result[\"filters\"][1][\"col\"] == \"b\"\n # Time range should be overridden\n assert result[\"time_range\"] == \"2022-01-01 : 2023-01-01\"\n # Extras should remain\n assert result[\"extras\"] == {\"where\": \"x > 0\"}\n # New columns should be added\n assert result[\"columns\"] == [\"col1\", \"col2\"]\n# #endregion test_extra_form_data_merge\n# #region test_filter_state_model [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test FilterState Pydantic model.\ndef test_filter_state_model():\n state = FilterState(\n extraFormData={\"filters\": [{\"col\": \"x\", \"op\": \"==\", \"val\": \"y\"}]},\n filterState={\"value\": \"y\"},\n ownState={\"selectedValues\": [\"y\"]},\n )\n assert state.extraFormData[\"filters\"][0][\"col\"] == \"x\"\n assert state.filterState[\"value\"] == \"y\"\n assert state.ownState[\"selectedValues\"] == [\"y\"]\n# #endregion test_filter_state_model\n# #region test_parsed_native_filters_model [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test ParsedNativeFilters Pydantic model.\ndef test_parsed_native_filters_model():\n filters = ParsedNativeFilters(\n dataMask={\"f1\": {\"extraFormData\": {}, \"filterState\": {}}},\n filter_type=\"permalink\",\n dashboard_id=\"42\",\n permalink_key=\"abc\",\n )\n assert filters.has_filters() is True\n assert filters.get_filter_count() == 1\n assert filters.filter_type == \"permalink\"\n# #endregion test_parsed_native_filters_model\n# #region test_parsed_native_filters_empty [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test ParsedNativeFilters with no filters.\ndef test_parsed_native_filters_empty():\n filters = ParsedNativeFilters()\n assert filters.has_filters() is False\n assert filters.get_filter_count() == 0\n# #endregion test_parsed_native_filters_empty\n# #region test_native_filter_data_mask_model [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Test NativeFilterDataMask model.\ndef test_native_filter_data_mask_model():\n data_mask = NativeFilterDataMask(\n filters={\n \"filter_1\": FilterState(extraFormData={\"filters\": []}, filterState={}),\n \"filter_2\": FilterState(\n extraFormData={\"time_range\": \"...\"}, filterState={}\n ),\n }\n )\n assert data_mask.get_filter_ids() == [\"filter_1\", \"filter_2\"]\n assert data_mask.get_extra_form_data(\"filter_1\") == {\"filters\": []}\n assert data_mask.get_extra_form_data(\"nonexistent\") == {}\n# #endregion test_native_filter_data_mask_model\n# #region test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Reconcile raw native filter ids from state to canonical metadata filter names.\ndef test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names():\n client = MagicMock()\n client.get_dashboard.return_value = {\n \"result\": {\n \"json_metadata\": json.dumps(\n {\n \"native_filter_configuration\": [\n {\n \"id\": \"NATIVE_FILTER-EWNH3M70z\",\n \"name\": \"Country\",\n \"label\": \"Country\",\n }\n ]\n }\n )\n }\n }\n extractor = SupersetContextExtractor(_make_environment(), client=client)\n parsed_context = SupersetParsedContext(\n source_url=\"http://superset.local/dashboard/42/?native_filters_key=abc\",\n dataset_ref=\"dataset:42\",\n dashboard_id=42,\n imported_filters=[\n {\n \"filter_name\": \"NATIVE_FILTER-EWNH3M70z\",\n \"display_name\": \"NATIVE_FILTER-EWNH3M70z\",\n \"raw_value\": [\"DE\", \"FR\"],\n \"normalized_value\": {\n \"filter_clauses\": [\n {\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}\n ],\n \"extra_form_data\": {\n \"filters\": [{\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}]\n },\n \"value_origin\": \"filter_state\",\n },\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ],\n )\n result = extractor.recover_imported_filters(parsed_context)\n assert len(result) == 1\n assert result[0][\"filter_name\"] == \"Country\"\n assert result[0][\"display_name\"] == \"Country\"\n assert result[0][\"raw_value\"] == [\"DE\", \"FR\"]\n assert result[0][\"source\"] == \"superset_native_filters_key\"\n assert result[0][\"normalized_value\"] == {\n \"filter_clauses\": [{\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}],\n \"extra_form_data\": {\n \"filters\": [{\"col\": \"country\", \"op\": \"IN\", \"val\": [\"DE\", \"FR\"]}]\n },\n \"value_origin\": \"filter_state\",\n }\n# #endregion test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names\n# #region test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Collapse raw-id state entries and metadata entries into one canonical filter.\ndef test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter():\n client = MagicMock()\n client.get_dashboard.return_value = {\n \"result\": {\n \"json_metadata\": json.dumps(\n {\n \"native_filter_configuration\": [\n {\n \"id\": \"NATIVE_FILTER-EWNH3M70z\",\n \"name\": \"Country\",\n \"label\": \"Country\",\n },\n {\n \"id\": \"NATIVE_FILTER-vv123\",\n \"name\": \"Region\",\n \"label\": \"Region\",\n },\n ]\n }\n )\n }\n }\n extractor = SupersetContextExtractor(_make_environment(), client=client)\n parsed_context = SupersetParsedContext(\n source_url=\"http://superset.local/dashboard/42/?native_filters_key=abc\",\n dataset_ref=\"dataset:42\",\n dashboard_id=42,\n imported_filters=[\n {\n \"filter_name\": \"NATIVE_FILTER-EWNH3M70z\",\n \"display_name\": \"Country\",\n \"raw_value\": [\"DE\", \"FR\"],\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ],\n )\n result = extractor.recover_imported_filters(parsed_context)\n assert len(result) == 2\n country_filter = next(item for item in result if item[\"filter_name\"] == \"Country\")\n region_filter = next(item for item in result if item[\"filter_name\"] == \"Region\")\n assert country_filter[\"raw_value\"] == [\"DE\", \"FR\"]\n assert country_filter[\"recovery_status\"] == \"recovered\"\n assert region_filter[\"raw_value\"] is None\n assert region_filter[\"recovery_status\"] == \"partial\"\n# #endregion test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter\n# #region test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Preserve unmatched raw native filter ids as fallback diagnostics when metadata mapping is unavailable.\ndef test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids():\n client = MagicMock()\n client.get_dashboard.return_value = {\n \"result\": {\n \"json_metadata\": json.dumps(\n {\n \"native_filter_configuration\": [\n {\n \"id\": \"NATIVE_FILTER-EWNH3M70z\",\n \"name\": \"Country\",\n \"label\": \"Country\",\n }\n ]\n }\n )\n }\n }\n extractor = SupersetContextExtractor(_make_environment(), client=client)\n parsed_context = SupersetParsedContext(\n source_url=\"http://superset.local/dashboard/42/?native_filters_key=abc\",\n dataset_ref=\"dataset:42\",\n dashboard_id=42,\n imported_filters=[\n {\n \"filter_name\": \"UNKNOWN_NATIVE_FILTER\",\n \"display_name\": \"UNKNOWN_NATIVE_FILTER\",\n \"raw_value\": [\"orphan\"],\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ],\n )\n result = extractor.recover_imported_filters(parsed_context)\n assert len(result) == 2\n assert any(\n item[\"filter_name\"] == \"Country\" and item[\"recovery_status\"] == \"partial\"\n for item in result\n )\n assert any(\n item[\"filter_name\"] == \"UNKNOWN_NATIVE_FILTER\"\n and item[\"raw_value\"] == [\"orphan\"]\n and item[\"source\"] == \"superset_native_filters_key\"\n for item in result\n )\n# #endregion test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids\n# #region test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Recovered native filter state should preserve exact Superset clause payload and time extras for preview compilation.\ndef test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview():\n extractor = SupersetContextExtractor(_make_environment(), client=MagicMock())\n imported_filters = extractor._extract_imported_filters(\n {\n \"native_filter_state\": {\n \"NATIVE_FILTER-1\": {\n \"id\": \"NATIVE_FILTER-1\",\n \"filterState\": {\"label\": \"Country\", \"value\": [\"DE\"]},\n \"extraFormData\": {\n \"filters\": [{\"col\": \"country_code\", \"op\": \"IN\", \"val\": [\"DE\"]}],\n \"time_range\": \"Last month\",\n },\n }\n }\n }\n )\n assert imported_filters == [\n {\n \"filter_name\": \"NATIVE_FILTER-1\",\n \"raw_value\": [\"DE\"],\n \"display_name\": \"Country\",\n \"normalized_value\": {\n \"filter_clauses\": [{\"col\": \"country_code\", \"op\": \"IN\", \"val\": [\"DE\"]}],\n \"extra_form_data\": {\n \"filters\": [{\"col\": \"country_code\", \"op\": \"IN\", \"val\": [\"DE\"]}],\n \"time_range\": \"Last month\",\n },\n \"value_origin\": \"filter_state\",\n },\n \"source\": \"superset_native_filters_key\",\n \"recovery_status\": \"recovered\",\n \"requires_confirmation\": False,\n \"notes\": \"Recovered from Superset native_filters_key state\",\n }\n ]\n# #endregion test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview\n# #region test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values [TYPE Function]\n# @RELATION BINDS_TO -> NativeFilterExtractionTests\n# @BRIEF Assistant-facing imported-filter payload should redact likely PII while preserving structure metadata.\ndef test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values():\n result = sanitize_imported_filter_for_assistant(\n {\n \"filter_name\": \"customer_email\",\n \"raw_value\": [\"alice@example.com\", \"1234567890\"],\n \"normalized_value\": {\"filter_clauses\": []},\n \"source\": \"manual\",\n }\n )\n assert result[\"raw_value\"] == [\"***@example.com\", \"********90\"]\n assert result[\"raw_value_masked\"] is True\n assert result[\"normalized_value\"] == {\"filter_clauses\": []}\n# #endregion test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values\n# #endregion NativeFilterExtractionTests\n"
},
{
"contract_id": "_make_environment",
@@ -18092,7 +18128,7 @@
"contract_type": "Module",
"file_path": "backend/src/core/async_superset_client.py",
"start_line": 1,
- "end_line": 615,
+ "end_line": 614,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18104,14 +18140,14 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region AsyncSupersetClientModule [C:3] [TYPE Module] [SEMANTICS superset, transform, dashboard, filter, async-superset-client]\n# @BRIEF Parse a Superset dashboard URL and extract native filter state asynchronously.\n# @LAYER Core\nimport asyncio\nimport json\nimport re\nfrom typing import Any, cast\n\nfrom .config_models import Environment\nfrom .logger import belief_scope, logger as app_logger\nfrom .superset_client import SupersetClient\nfrom .utils.async_network import AsyncAPIClient\n\n\n# #region AsyncSupersetClient [C:3] [TYPE Class]\n# @BRIEF Async sibling of SupersetClient for dashboard read paths.\n# @RELATION INHERITS -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [AsyncAPIClient]\n# @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\nclass AsyncSupersetClient(SupersetClient):\n # #region AsyncSupersetClientInit [TYPE Function] [C:3]\n # @PURPOSE: Initialize async Superset client with AsyncAPIClient transport.\n # @PRE env is valid Environment instance.\n # @POST Client uses async network transport and inherited projection helpers.\n # @DATA_CONTRACT Input[Environment] -> self.network[AsyncAPIClient]\n # @RELATION DEPENDS_ON -> [AsyncAPIClient]\n def __init__(self, env: Environment):\n self.env = env\n auth_payload = {\n \"username\": env.username,\n \"password\": env.password,\n \"provider\": \"db\",\n \"refresh\": \"true\",\n }\n self.network = AsyncAPIClient(\n config={\"base_url\": env.url, \"auth\": auth_payload},\n verify_ssl=env.verify_ssl,\n timeout=env.timeout,\n )\n self.delete_before_reimport = False\n # #endregion AsyncSupersetClientInit\n # #region AsyncSupersetClientClose [TYPE Function] [C:3]\n # @PURPOSE: Close async transport resources.\n # @POST Underlying AsyncAPIClient is closed.\n # @SIDE_EFFECT Closes network sockets.\n # @RELATION CALLS -> [AsyncAPIClient.aclose]\n async def aclose(self) -> None:\n await self.network.aclose()\n # #endregion AsyncSupersetClientClose\n # #region get_dashboards_page_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboards page asynchronously.\n # @POST Returns total count and page result list.\n # @DATA_CONTRACT Input[query: Optional[Dict]] -> Output[Tuple[int, List[Dict]]]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboards_page_async(\n self, query: dict | None = None\n ) -> tuple[int, list[dict]]:\n with belief_scope(\"AsyncSupersetClient.get_dashboards_page_async\"):\n validated_query = self._validate_query_params(query or {})\n if \"columns\" not in validated_query:\n validated_query[\"columns\"] = [\n \"slug\",\n \"id\",\n \"url\",\n \"changed_on_utc\",\n \"dashboard_title\",\n \"published\",\n \"created_by\",\n \"changed_by\",\n \"changed_by_name\",\n \"owners\",\n ]\n response_json = cast(\n dict[str, Any],\n await self.network.request(\n method=\"GET\",\n endpoint=\"/dashboard/\",\n params={\"q\": json.dumps(validated_query)},\n ),\n )\n result = response_json.get(\"result\", [])\n total_count = response_json.get(\"count\", len(result))\n return total_count, result\n # #endregion get_dashboards_page_async\n # #region get_dashboard_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboard payload asynchronously.\n # @POST Returns raw dashboard payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboard_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_async\", f\"id={dashboard_id}\"\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_async\n # #region get_chart_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one chart payload asynchronously.\n # @POST Returns raw chart payload from Superset API.\n # @DATA_CONTRACT Input[chart_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_chart_async(self, chart_id: int) -> dict:\n with belief_scope(\"AsyncSupersetClient.get_chart_async\", f\"id={chart_id}\"):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/chart/{chart_id}\"\n )\n return cast(dict, response)\n # #endregion get_chart_async\n # #region get_dashboard_detail_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch dashboard detail asynchronously with concurrent charts/datasets requests.\n # @POST Returns dashboard detail payload for overview page.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_async]\n # @RELATION CALLS -> [get_chart_async]\n async def get_dashboard_detail_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_detail_async\", f\"id={dashboard_id}\"\n ):\n dashboard_response = await self.get_dashboard_async(dashboard_id)\n dashboard_data = dashboard_response.get(\"result\", dashboard_response)\n charts: list[dict] = []\n datasets: list[dict] = []\n def extract_dataset_id_from_form_data(\n form_data: dict | None,\n ) -> int | None:\n if not isinstance(form_data, dict):\n return None\n datasource = form_data.get(\"datasource\")\n if isinstance(datasource, str):\n matched = re.match(r\"^(\\d+)__\", datasource)\n if matched:\n try:\n return int(matched.group(1))\n except ValueError:\n return None\n if isinstance(datasource, dict):\n ds_id = datasource.get(\"id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n ds_id = form_data.get(\"datasource_id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n chart_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/charts\",\n )\n dataset_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/datasets\",\n )\n charts_response, datasets_response = await asyncio.gather(\n chart_task,\n dataset_task,\n return_exceptions=True,\n )\n if not isinstance(charts_response, Exception):\n charts_payload = (\n charts_response.get(\"result\", [])\n if isinstance(charts_response, dict)\n else []\n )\n for chart_obj in charts_payload:\n if not isinstance(chart_obj, dict):\n continue\n chart_id = chart_obj.get(\"id\")\n if chart_id is None:\n continue\n form_data = chart_obj.get(\"form_data\")\n if isinstance(form_data, str):\n try:\n form_data = json.loads(form_data)\n except Exception:\n form_data = {}\n dataset_id = extract_dataset_id_from_form_data(\n form_data\n ) or chart_obj.get(\"datasource_id\")\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_obj.get(\"slice_name\")\n or chart_obj.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n ),\n \"dataset_id\": int(dataset_id)\n if dataset_id is not None\n else None,\n \"last_modified\": chart_obj.get(\"changed_on\"),\n \"overview\": chart_obj.get(\"description\")\n or (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n )\n or \"Chart\",\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard charts: %s\",\n charts_response,\n )\n if not isinstance(datasets_response, Exception):\n datasets_payload = (\n datasets_response.get(\"result\", [])\n if isinstance(datasets_response, dict)\n else []\n )\n for dataset_obj in datasets_payload:\n if not isinstance(dataset_obj, dict):\n continue\n dataset_id = dataset_obj.get(\"id\")\n if dataset_id is None:\n continue\n db_payload = dataset_obj.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_obj.get(\"table_name\")\n or dataset_obj.get(\"datasource_name\")\n or dataset_obj.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_obj.get(\"schema\")\n fq_name = f\"{schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_obj.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_obj.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard datasets: %s\",\n datasets_response,\n )\n if not charts:\n raw_position_json = dashboard_data.get(\"position_json\")\n chart_ids_from_position = set()\n if isinstance(raw_position_json, str) and raw_position_json:\n try:\n parsed_position = json.loads(raw_position_json)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_position)\n )\n except Exception:\n app_logger.debug(\"Could not parse position JSON for dashboard %s\", dashboard_ref)\n elif isinstance(raw_position_json, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_position_json)\n )\n raw_json_metadata = dashboard_data.get(\"json_metadata\")\n if isinstance(raw_json_metadata, str) and raw_json_metadata:\n try:\n parsed_metadata = json.loads(raw_json_metadata)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_metadata)\n )\n except Exception:\n app_logger.debug(\"Could not parse json_metadata for dashboard %s\", dashboard_ref)\n elif isinstance(raw_json_metadata, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_json_metadata)\n )\n fallback_chart_tasks = [\n self.get_chart_async(int(chart_id))\n for chart_id in sorted(chart_ids_from_position)\n ]\n fallback_chart_responses = await asyncio.gather(\n *fallback_chart_tasks,\n return_exceptions=True,\n )\n for chart_id, chart_response in zip(\n sorted(chart_ids_from_position), fallback_chart_responses\n ):\n if isinstance(chart_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to resolve fallback chart %s: %s\",\n chart_id,\n chart_response,\n )\n continue\n chart_data = chart_response.get(\"result\", chart_response)\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_data.get(\"slice_name\")\n or chart_data.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": chart_data.get(\"viz_type\"),\n \"dataset_id\": chart_data.get(\"datasource_id\"),\n \"last_modified\": chart_data.get(\"changed_on\"),\n \"overview\": chart_data.get(\"description\")\n or chart_data.get(\"viz_type\")\n or \"Chart\",\n }\n )\n dataset_ids_from_charts = {\n c.get(\"dataset_id\") for c in charts if c.get(\"dataset_id\") is not None\n }\n known_dataset_ids = {\n d.get(\"id\") for d in datasets if d.get(\"id\") is not None\n }\n missing_dataset_ids = sorted(\n int(item)\n for item in dataset_ids_from_charts\n if item not in known_dataset_ids\n )\n if missing_dataset_ids:\n dataset_fetch_tasks = [\n self.network.request(\n method=\"GET\", endpoint=f\"/dataset/{dataset_id}\"\n )\n for dataset_id in missing_dataset_ids\n ]\n dataset_fetch_responses = await asyncio.gather(\n *dataset_fetch_tasks,\n return_exceptions=True,\n )\n for dataset_id, dataset_response in zip(\n missing_dataset_ids, dataset_fetch_responses\n ):\n if isinstance(dataset_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to backfill dataset %s: %s\",\n dataset_id,\n dataset_response,\n )\n continue\n dataset_data = (\n dataset_response.get(\"result\", dataset_response)\n if isinstance(dataset_response, dict)\n else {}\n )\n db_payload = dataset_data.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_data.get(\"table_name\")\n or dataset_data.get(\"datasource_name\")\n or dataset_data.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_data.get(\"schema\")\n fq_name = f\" {schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_data.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_data.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n return {\n \"id\": int(dashboard_data.get(\"id\") or dashboard_id),\n \"title\": dashboard_data.get(\"dashboard_title\")\n or dashboard_data.get(\"title\")\n or f\"Dashboard {dashboard_id}\",\n \"slug\": dashboard_data.get(\"slug\"),\n \"url\": dashboard_data.get(\"url\"),\n \"description\": dashboard_data.get(\"description\"),\n \"last_modified\": dashboard_data.get(\"changed_on_utc\")\n or dashboard_data.get(\"changed_on\"),\n \"published\": dashboard_data.get(\"published\"),\n \"charts\": charts,\n \"datasets\": datasets,\n \"chart_count\": len(charts),\n \"dataset_count\": len(datasets),\n }\n # #endregion get_dashboard_detail_async\n # #region get_dashboard_permalink_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored dashboard permalink state asynchronously.\n # @POST Returns dashboard permalink state payload from Superset API.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n async def get_dashboard_permalink_state_async(self, permalink_key: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_permalink_state_async\",\n f\"key={permalink_key}\",\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/permalink/{permalink_key}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_permalink_state_async\n # #region get_native_filter_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored native filter state asynchronously.\n # @POST Returns native filter state payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n async def get_native_filter_state_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_native_filter_state_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n response = await self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/filter_state/{filter_state_key}\",\n )\n return cast(dict, response)\n # #endregion get_native_filter_state_async\n # #region extract_native_filters_from_permalink_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters dataMask from a permalink key asynchronously.\n # @POST Returns extracted dataMask with filter states.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_permalink_state_async]\n async def extract_native_filters_from_permalink_async(\n self, permalink_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_permalink_async\",\n f\"key={permalink_key}\",\n ):\n permalink_response = await self.get_dashboard_permalink_state_async(\n permalink_key\n )\n result = permalink_response.get(\"result\", permalink_response)\n state = result.get(\"state\", result)\n data_mask = state.get(\"dataMask\", {})\n extracted_filters = {}\n for filter_id, filter_data in data_mask.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"activeTabs\": state.get(\"activeTabs\", []),\n \"anchor\": state.get(\"anchor\"),\n \"chartStates\": state.get(\"chartStates\", {}),\n \"permalink_key\": permalink_key,\n }\n # #endregion extract_native_filters_from_permalink_async\n # #region extract_native_filters_from_key_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters from a native_filters_key URL parameter asynchronously.\n # @POST Returns extracted filter state with extraFormData.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_native_filter_state_async]\n async def extract_native_filters_from_key_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_key_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n filter_response = await self.get_native_filter_state_async(\n dashboard_id, filter_state_key\n )\n result = filter_response.get(\"result\", filter_response)\n value = result.get(\"value\")\n if isinstance(value, str):\n try:\n parsed_value = json.loads(value)\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[extract_native_filters_from_key_async][Warning] Failed to parse filter state JSON: %s\",\n e,\n )\n parsed_value = {}\n elif isinstance(value, dict):\n parsed_value = value\n else:\n parsed_value = {}\n extracted_filters = {}\n if \"id\" in parsed_value and \"extraFormData\" in parsed_value:\n filter_id = parsed_value.get(\"id\", filter_state_key)\n extracted_filters[filter_id] = {\n \"extraFormData\": parsed_value.get(\"extraFormData\", {}),\n \"filterState\": parsed_value.get(\"filterState\", {}),\n \"ownState\": parsed_value.get(\"ownState\", {}),\n }\n else:\n for filter_id, filter_data in parsed_value.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"dashboard_id\": dashboard_id,\n \"filter_state_key\": filter_state_key,\n }\n # #endregion extract_native_filters_from_key_async\n # #region parse_dashboard_url_for_filters_async [TYPE Function] [C:3]\n # @PURPOSE: Parse a Superset dashboard URL and extract native filter state asynchronously.\n # @POST Returns extracted filter state or empty dict if no filters found.\n # @DATA_CONTRACT Input[url: str] -> Output[Dict]\n # @RELATION CALLS -> [extract_native_filters_from_permalink_async]\n # @RELATION CALLS -> [extract_native_filters_from_key_async]\n async def parse_dashboard_url_for_filters_async(self, url: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.parse_dashboard_url_for_filters_async\", f\"url={url}\"\n ):\n import urllib.parse\n parsed_url = urllib.parse.urlparse(url)\n query_params = urllib.parse.parse_qs(parsed_url.query)\n path_parts = parsed_url.path.rstrip(\"/\").split(\"/\")\n result = {\n \"url\": url,\n \"dashboard_id\": None,\n \"filter_type\": None,\n \"filters\": {},\n }\n # Check for permalink URL: /dashboard/p/{key}/\n if \"p\" in path_parts:\n try:\n p_index = path_parts.index(\"p\")\n if p_index + 1 < len(path_parts):\n permalink_key = path_parts[p_index + 1]\n filter_data = (\n await self.extract_native_filters_from_permalink_async(\n permalink_key\n )\n )\n result[\"filter_type\"] = \"permalink\"\n result[\"filters\"] = filter_data\n return result\n except ValueError:\n app_logger.debug(\"Permalink key not found in URL for dashboard %s\", dashboard_ref)\n # Check for native_filters_key in query params\n native_filters_key = query_params.get(\"native_filters_key\", [None])[0]\n if native_filters_key:\n dashboard_ref = None\n if \"dashboard\" in path_parts:\n try:\n dash_index = path_parts.index(\"dashboard\")\n if dash_index + 1 < len(path_parts):\n potential_id = path_parts[dash_index + 1]\n if potential_id not in (\"p\", \"list\", \"new\"):\n dashboard_ref = potential_id\n except ValueError:\n app_logger.debug(\"Dashboard not found in path_parts for native_filters_key\")\n if dashboard_ref:\n # Resolve slug to numeric ID — the filter_state API requires a numeric ID\n resolved_id = None\n try:\n resolved_id = int(dashboard_ref)\n except (ValueError, TypeError):\n try:\n dash_resp = await self.get_dashboard_async(dashboard_ref)\n dash_data = (\n dash_resp.get(\"result\", dash_resp)\n if isinstance(dash_resp, dict)\n else {}\n )\n raw_id = dash_data.get(\"id\")\n if raw_id is not None:\n resolved_id = int(raw_id)\n except Exception as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to resolve dashboard slug '%s' to ID: %s\",\n dashboard_ref,\n e,\n )\n if resolved_id is not None:\n filter_data = await self.extract_native_filters_from_key_async(\n resolved_id, native_filters_key\n )\n result[\"filter_type\"] = \"native_filters_key\"\n result[\"dashboard_id\"] = resolved_id\n result[\"filters\"] = filter_data\n return result\n else:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Could not resolve dashboard_id from URL for native_filters_key\"\n )\n return result\n # Check for native_filters in query params (direct filter values)\n native_filters = query_params.get(\"native_filters\", [None])[0]\n if native_filters:\n try:\n parsed_filters = json.loads(native_filters)\n result[\"filter_type\"] = \"native_filters\"\n result[\"filters\"] = {\"dataMask\": parsed_filters}\n return result\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to parse native_filters JSON: %s\",\n e,\n )\n return result\n # #endregion parse_dashboard_url_for_filters_async\n# #endregion AsyncSupersetClient\n# #endregion AsyncSupersetClientModule\n"
+ "body": "# #region AsyncSupersetClientModule [C:3] [TYPE Module] [SEMANTICS superset, transform, dashboard, filter, async-superset-client]\n# @BRIEF Parse a Superset dashboard URL and extract native filter state asynchronously.\n# @LAYER Core\nimport asyncio\nimport json\nimport re\nfrom typing import Any, cast\n\nfrom .config_models import Environment\nfrom .logger import belief_scope, logger as app_logger\nfrom .superset_client import SupersetClient\nfrom .utils.async_network import AsyncAPIClient\n\n\n# #region AsyncSupersetClient [C:3] [TYPE Class]\n# @BRIEF Async sibling of SupersetClient for dashboard read paths.\n# @RELATION INHERITS -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [AsyncAPIClient]\nclass AsyncSupersetClient(SupersetClient):\n # #region AsyncSupersetClientInit [TYPE Function] [C:3]\n # @PURPOSE: Initialize async Superset client with AsyncAPIClient transport.\n # @PRE env is valid Environment instance.\n # @POST Client uses async network transport and inherited projection helpers.\n # @DATA_CONTRACT Input[Environment] -> self.network[AsyncAPIClient]\n # @RELATION DEPENDS_ON -> [AsyncAPIClient]\n def __init__(self, env: Environment):\n self.env = env\n auth_payload = {\n \"username\": env.username,\n \"password\": env.password,\n \"provider\": \"db\",\n \"refresh\": \"true\",\n }\n self.network = AsyncAPIClient(\n config={\"base_url\": env.url, \"auth\": auth_payload},\n verify_ssl=env.verify_ssl,\n timeout=env.timeout,\n )\n self.delete_before_reimport = False\n # #endregion AsyncSupersetClientInit\n # #region AsyncSupersetClientClose [TYPE Function] [C:3]\n # @PURPOSE: Close async transport resources.\n # @POST Underlying AsyncAPIClient is closed.\n # @SIDE_EFFECT Closes network sockets.\n # @RELATION CALLS -> [AsyncAPIClient.aclose]\n async def aclose(self) -> None:\n await self.network.aclose()\n # #endregion AsyncSupersetClientClose\n # #region get_dashboards_page_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboards page asynchronously.\n # @POST Returns total count and page result list.\n # @DATA_CONTRACT Input[query: Optional[Dict]] -> Output[Tuple[int, List[Dict]]]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboards_page_async(\n self, query: dict | None = None\n ) -> tuple[int, list[dict]]:\n with belief_scope(\"AsyncSupersetClient.get_dashboards_page_async\"):\n validated_query = self._validate_query_params(query or {})\n if \"columns\" not in validated_query:\n validated_query[\"columns\"] = [\n \"slug\",\n \"id\",\n \"url\",\n \"changed_on_utc\",\n \"dashboard_title\",\n \"published\",\n \"created_by\",\n \"changed_by\",\n \"changed_by_name\",\n \"owners\",\n ]\n response_json = cast(\n dict[str, Any],\n await self.network.request(\n method=\"GET\",\n endpoint=\"/dashboard/\",\n params={\"q\": json.dumps(validated_query)},\n ),\n )\n result = response_json.get(\"result\", [])\n total_count = response_json.get(\"count\", len(result))\n return total_count, result\n # #endregion get_dashboards_page_async\n # #region get_dashboard_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboard payload asynchronously.\n # @POST Returns raw dashboard payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboard_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_async\", f\"id={dashboard_id}\"\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_async\n # #region get_chart_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one chart payload asynchronously.\n # @POST Returns raw chart payload from Superset API.\n # @DATA_CONTRACT Input[chart_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_chart_async(self, chart_id: int) -> dict:\n with belief_scope(\"AsyncSupersetClient.get_chart_async\", f\"id={chart_id}\"):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/chart/{chart_id}\"\n )\n return cast(dict, response)\n # #endregion get_chart_async\n # #region get_dashboard_detail_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch dashboard detail asynchronously with concurrent charts/datasets requests.\n # @POST Returns dashboard detail payload for overview page.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_async]\n # @RELATION CALLS -> [get_chart_async]\n async def get_dashboard_detail_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_detail_async\", f\"id={dashboard_id}\"\n ):\n dashboard_response = await self.get_dashboard_async(dashboard_id)\n dashboard_data = dashboard_response.get(\"result\", dashboard_response)\n charts: list[dict] = []\n datasets: list[dict] = []\n def extract_dataset_id_from_form_data(\n form_data: dict | None,\n ) -> int | None:\n if not isinstance(form_data, dict):\n return None\n datasource = form_data.get(\"datasource\")\n if isinstance(datasource, str):\n matched = re.match(r\"^(\\d+)__\", datasource)\n if matched:\n try:\n return int(matched.group(1))\n except ValueError:\n return None\n if isinstance(datasource, dict):\n ds_id = datasource.get(\"id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n ds_id = form_data.get(\"datasource_id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n chart_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/charts\",\n )\n dataset_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/datasets\",\n )\n charts_response, datasets_response = await asyncio.gather(\n chart_task,\n dataset_task,\n return_exceptions=True,\n )\n if not isinstance(charts_response, Exception):\n charts_payload = (\n charts_response.get(\"result\", [])\n if isinstance(charts_response, dict)\n else []\n )\n for chart_obj in charts_payload:\n if not isinstance(chart_obj, dict):\n continue\n chart_id = chart_obj.get(\"id\")\n if chart_id is None:\n continue\n form_data = chart_obj.get(\"form_data\")\n if isinstance(form_data, str):\n try:\n form_data = json.loads(form_data)\n except Exception:\n form_data = {}\n dataset_id = extract_dataset_id_from_form_data(\n form_data\n ) or chart_obj.get(\"datasource_id\")\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_obj.get(\"slice_name\")\n or chart_obj.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n ),\n \"dataset_id\": int(dataset_id)\n if dataset_id is not None\n else None,\n \"last_modified\": chart_obj.get(\"changed_on\"),\n \"overview\": chart_obj.get(\"description\")\n or (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n )\n or \"Chart\",\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard charts: %s\",\n charts_response,\n )\n if not isinstance(datasets_response, Exception):\n datasets_payload = (\n datasets_response.get(\"result\", [])\n if isinstance(datasets_response, dict)\n else []\n )\n for dataset_obj in datasets_payload:\n if not isinstance(dataset_obj, dict):\n continue\n dataset_id = dataset_obj.get(\"id\")\n if dataset_id is None:\n continue\n db_payload = dataset_obj.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_obj.get(\"table_name\")\n or dataset_obj.get(\"datasource_name\")\n or dataset_obj.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_obj.get(\"schema\")\n fq_name = f\"{schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_obj.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_obj.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard datasets: %s\",\n datasets_response,\n )\n if not charts:\n raw_position_json = dashboard_data.get(\"position_json\")\n chart_ids_from_position = set()\n if isinstance(raw_position_json, str) and raw_position_json:\n try:\n parsed_position = json.loads(raw_position_json)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_position)\n )\n except Exception:\n app_logger.debug(\"Could not parse position JSON for dashboard %s\", dashboard_ref)\n elif isinstance(raw_position_json, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_position_json)\n )\n raw_json_metadata = dashboard_data.get(\"json_metadata\")\n if isinstance(raw_json_metadata, str) and raw_json_metadata:\n try:\n parsed_metadata = json.loads(raw_json_metadata)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_metadata)\n )\n except Exception:\n app_logger.debug(\"Could not parse json_metadata for dashboard %s\", dashboard_ref)\n elif isinstance(raw_json_metadata, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_json_metadata)\n )\n fallback_chart_tasks = [\n self.get_chart_async(int(chart_id))\n for chart_id in sorted(chart_ids_from_position)\n ]\n fallback_chart_responses = await asyncio.gather(\n *fallback_chart_tasks,\n return_exceptions=True,\n )\n for chart_id, chart_response in zip(\n sorted(chart_ids_from_position), fallback_chart_responses\n ):\n if isinstance(chart_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to resolve fallback chart %s: %s\",\n chart_id,\n chart_response,\n )\n continue\n chart_data = chart_response.get(\"result\", chart_response)\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_data.get(\"slice_name\")\n or chart_data.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": chart_data.get(\"viz_type\"),\n \"dataset_id\": chart_data.get(\"datasource_id\"),\n \"last_modified\": chart_data.get(\"changed_on\"),\n \"overview\": chart_data.get(\"description\")\n or chart_data.get(\"viz_type\")\n or \"Chart\",\n }\n )\n dataset_ids_from_charts = {\n c.get(\"dataset_id\") for c in charts if c.get(\"dataset_id\") is not None\n }\n known_dataset_ids = {\n d.get(\"id\") for d in datasets if d.get(\"id\") is not None\n }\n missing_dataset_ids = sorted(\n int(item)\n for item in dataset_ids_from_charts\n if item not in known_dataset_ids\n )\n if missing_dataset_ids:\n dataset_fetch_tasks = [\n self.network.request(\n method=\"GET\", endpoint=f\"/dataset/{dataset_id}\"\n )\n for dataset_id in missing_dataset_ids\n ]\n dataset_fetch_responses = await asyncio.gather(\n *dataset_fetch_tasks,\n return_exceptions=True,\n )\n for dataset_id, dataset_response in zip(\n missing_dataset_ids, dataset_fetch_responses\n ):\n if isinstance(dataset_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to backfill dataset %s: %s\",\n dataset_id,\n dataset_response,\n )\n continue\n dataset_data = (\n dataset_response.get(\"result\", dataset_response)\n if isinstance(dataset_response, dict)\n else {}\n )\n db_payload = dataset_data.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_data.get(\"table_name\")\n or dataset_data.get(\"datasource_name\")\n or dataset_data.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_data.get(\"schema\")\n fq_name = f\" {schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_data.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_data.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n return {\n \"id\": int(dashboard_data.get(\"id\") or dashboard_id),\n \"title\": dashboard_data.get(\"dashboard_title\")\n or dashboard_data.get(\"title\")\n or f\"Dashboard {dashboard_id}\",\n \"slug\": dashboard_data.get(\"slug\"),\n \"url\": dashboard_data.get(\"url\"),\n \"description\": dashboard_data.get(\"description\"),\n \"last_modified\": dashboard_data.get(\"changed_on_utc\")\n or dashboard_data.get(\"changed_on\"),\n \"published\": dashboard_data.get(\"published\"),\n \"charts\": charts,\n \"datasets\": datasets,\n \"chart_count\": len(charts),\n \"dataset_count\": len(datasets),\n }\n # #endregion get_dashboard_detail_async\n # #region get_dashboard_permalink_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored dashboard permalink state asynchronously.\n # @POST Returns dashboard permalink state payload from Superset API.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n async def get_dashboard_permalink_state_async(self, permalink_key: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_permalink_state_async\",\n f\"key={permalink_key}\",\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/permalink/{permalink_key}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_permalink_state_async\n # #region get_native_filter_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored native filter state asynchronously.\n # @POST Returns native filter state payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n async def get_native_filter_state_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_native_filter_state_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n response = await self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/filter_state/{filter_state_key}\",\n )\n return cast(dict, response)\n # #endregion get_native_filter_state_async\n # #region extract_native_filters_from_permalink_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters dataMask from a permalink key asynchronously.\n # @POST Returns extracted dataMask with filter states.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_permalink_state_async]\n async def extract_native_filters_from_permalink_async(\n self, permalink_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_permalink_async\",\n f\"key={permalink_key}\",\n ):\n permalink_response = await self.get_dashboard_permalink_state_async(\n permalink_key\n )\n result = permalink_response.get(\"result\", permalink_response)\n state = result.get(\"state\", result)\n data_mask = state.get(\"dataMask\", {})\n extracted_filters = {}\n for filter_id, filter_data in data_mask.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"activeTabs\": state.get(\"activeTabs\", []),\n \"anchor\": state.get(\"anchor\"),\n \"chartStates\": state.get(\"chartStates\", {}),\n \"permalink_key\": permalink_key,\n }\n # #endregion extract_native_filters_from_permalink_async\n # #region extract_native_filters_from_key_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters from a native_filters_key URL parameter asynchronously.\n # @POST Returns extracted filter state with extraFormData.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_native_filter_state_async]\n async def extract_native_filters_from_key_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_key_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n filter_response = await self.get_native_filter_state_async(\n dashboard_id, filter_state_key\n )\n result = filter_response.get(\"result\", filter_response)\n value = result.get(\"value\")\n if isinstance(value, str):\n try:\n parsed_value = json.loads(value)\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[extract_native_filters_from_key_async][Warning] Failed to parse filter state JSON: %s\",\n e,\n )\n parsed_value = {}\n elif isinstance(value, dict):\n parsed_value = value\n else:\n parsed_value = {}\n extracted_filters = {}\n if \"id\" in parsed_value and \"extraFormData\" in parsed_value:\n filter_id = parsed_value.get(\"id\", filter_state_key)\n extracted_filters[filter_id] = {\n \"extraFormData\": parsed_value.get(\"extraFormData\", {}),\n \"filterState\": parsed_value.get(\"filterState\", {}),\n \"ownState\": parsed_value.get(\"ownState\", {}),\n }\n else:\n for filter_id, filter_data in parsed_value.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"dashboard_id\": dashboard_id,\n \"filter_state_key\": filter_state_key,\n }\n # #endregion extract_native_filters_from_key_async\n # #region parse_dashboard_url_for_filters_async [TYPE Function] [C:3]\n # @PURPOSE: Parse a Superset dashboard URL and extract native filter state asynchronously.\n # @POST Returns extracted filter state or empty dict if no filters found.\n # @DATA_CONTRACT Input[url: str] -> Output[Dict]\n # @RELATION CALLS -> [extract_native_filters_from_permalink_async]\n # @RELATION CALLS -> [extract_native_filters_from_key_async]\n async def parse_dashboard_url_for_filters_async(self, url: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.parse_dashboard_url_for_filters_async\", f\"url={url}\"\n ):\n import urllib.parse\n parsed_url = urllib.parse.urlparse(url)\n query_params = urllib.parse.parse_qs(parsed_url.query)\n path_parts = parsed_url.path.rstrip(\"/\").split(\"/\")\n result = {\n \"url\": url,\n \"dashboard_id\": None,\n \"filter_type\": None,\n \"filters\": {},\n }\n # Check for permalink URL: /dashboard/p/{key}/\n if \"p\" in path_parts:\n try:\n p_index = path_parts.index(\"p\")\n if p_index + 1 < len(path_parts):\n permalink_key = path_parts[p_index + 1]\n filter_data = (\n await self.extract_native_filters_from_permalink_async(\n permalink_key\n )\n )\n result[\"filter_type\"] = \"permalink\"\n result[\"filters\"] = filter_data\n return result\n except ValueError:\n app_logger.debug(\"Permalink key not found in URL for dashboard %s\", dashboard_ref)\n # Check for native_filters_key in query params\n native_filters_key = query_params.get(\"native_filters_key\", [None])[0]\n if native_filters_key:\n dashboard_ref = None\n if \"dashboard\" in path_parts:\n try:\n dash_index = path_parts.index(\"dashboard\")\n if dash_index + 1 < len(path_parts):\n potential_id = path_parts[dash_index + 1]\n if potential_id not in (\"p\", \"list\", \"new\"):\n dashboard_ref = potential_id\n except ValueError:\n app_logger.debug(\"Dashboard not found in path_parts for native_filters_key\")\n if dashboard_ref:\n # Resolve slug to numeric ID — the filter_state API requires a numeric ID\n resolved_id = None\n try:\n resolved_id = int(dashboard_ref)\n except (ValueError, TypeError):\n try:\n dash_resp = await self.get_dashboard_async(dashboard_ref)\n dash_data = (\n dash_resp.get(\"result\", dash_resp)\n if isinstance(dash_resp, dict)\n else {}\n )\n raw_id = dash_data.get(\"id\")\n if raw_id is not None:\n resolved_id = int(raw_id)\n except Exception as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to resolve dashboard slug '%s' to ID: %s\",\n dashboard_ref,\n e,\n )\n if resolved_id is not None:\n filter_data = await self.extract_native_filters_from_key_async(\n resolved_id, native_filters_key\n )\n result[\"filter_type\"] = \"native_filters_key\"\n result[\"dashboard_id\"] = resolved_id\n result[\"filters\"] = filter_data\n return result\n else:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Could not resolve dashboard_id from URL for native_filters_key\"\n )\n return result\n # Check for native_filters in query params (direct filter values)\n native_filters = query_params.get(\"native_filters\", [None])[0]\n if native_filters:\n try:\n parsed_filters = json.loads(native_filters)\n result[\"filter_type\"] = \"native_filters\"\n result[\"filters\"] = {\"dataMask\": parsed_filters}\n return result\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to parse native_filters JSON: %s\",\n e,\n )\n return result\n # #endregion parse_dashboard_url_for_filters_async\n# #endregion AsyncSupersetClient\n# #endregion AsyncSupersetClientModule\n"
},
{
"contract_id": "AsyncSupersetClient",
"contract_type": "Class",
"file_path": "backend/src/core/async_superset_client.py",
"start_line": 15,
- "end_line": 614,
+ "end_line": 613,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18130,25 +18166,19 @@
"relation_type": "DEPENDS_ON",
"target_id": "AsyncAPIClient",
"target_ref": "[AsyncAPIClient]"
- },
- {
- "source_id": "AsyncSupersetClient",
- "relation_type": "CALLS",
- "target_id": "EXT:method:AsyncAPIClient.request",
- "target_ref": "[EXT:method:AsyncAPIClient.request]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region AsyncSupersetClient [C:3] [TYPE Class]\n# @BRIEF Async sibling of SupersetClient for dashboard read paths.\n# @RELATION INHERITS -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [AsyncAPIClient]\n# @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\nclass AsyncSupersetClient(SupersetClient):\n # #region AsyncSupersetClientInit [TYPE Function] [C:3]\n # @PURPOSE: Initialize async Superset client with AsyncAPIClient transport.\n # @PRE env is valid Environment instance.\n # @POST Client uses async network transport and inherited projection helpers.\n # @DATA_CONTRACT Input[Environment] -> self.network[AsyncAPIClient]\n # @RELATION DEPENDS_ON -> [AsyncAPIClient]\n def __init__(self, env: Environment):\n self.env = env\n auth_payload = {\n \"username\": env.username,\n \"password\": env.password,\n \"provider\": \"db\",\n \"refresh\": \"true\",\n }\n self.network = AsyncAPIClient(\n config={\"base_url\": env.url, \"auth\": auth_payload},\n verify_ssl=env.verify_ssl,\n timeout=env.timeout,\n )\n self.delete_before_reimport = False\n # #endregion AsyncSupersetClientInit\n # #region AsyncSupersetClientClose [TYPE Function] [C:3]\n # @PURPOSE: Close async transport resources.\n # @POST Underlying AsyncAPIClient is closed.\n # @SIDE_EFFECT Closes network sockets.\n # @RELATION CALLS -> [AsyncAPIClient.aclose]\n async def aclose(self) -> None:\n await self.network.aclose()\n # #endregion AsyncSupersetClientClose\n # #region get_dashboards_page_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboards page asynchronously.\n # @POST Returns total count and page result list.\n # @DATA_CONTRACT Input[query: Optional[Dict]] -> Output[Tuple[int, List[Dict]]]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboards_page_async(\n self, query: dict | None = None\n ) -> tuple[int, list[dict]]:\n with belief_scope(\"AsyncSupersetClient.get_dashboards_page_async\"):\n validated_query = self._validate_query_params(query or {})\n if \"columns\" not in validated_query:\n validated_query[\"columns\"] = [\n \"slug\",\n \"id\",\n \"url\",\n \"changed_on_utc\",\n \"dashboard_title\",\n \"published\",\n \"created_by\",\n \"changed_by\",\n \"changed_by_name\",\n \"owners\",\n ]\n response_json = cast(\n dict[str, Any],\n await self.network.request(\n method=\"GET\",\n endpoint=\"/dashboard/\",\n params={\"q\": json.dumps(validated_query)},\n ),\n )\n result = response_json.get(\"result\", [])\n total_count = response_json.get(\"count\", len(result))\n return total_count, result\n # #endregion get_dashboards_page_async\n # #region get_dashboard_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboard payload asynchronously.\n # @POST Returns raw dashboard payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboard_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_async\", f\"id={dashboard_id}\"\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_async\n # #region get_chart_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one chart payload asynchronously.\n # @POST Returns raw chart payload from Superset API.\n # @DATA_CONTRACT Input[chart_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_chart_async(self, chart_id: int) -> dict:\n with belief_scope(\"AsyncSupersetClient.get_chart_async\", f\"id={chart_id}\"):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/chart/{chart_id}\"\n )\n return cast(dict, response)\n # #endregion get_chart_async\n # #region get_dashboard_detail_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch dashboard detail asynchronously with concurrent charts/datasets requests.\n # @POST Returns dashboard detail payload for overview page.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_async]\n # @RELATION CALLS -> [get_chart_async]\n async def get_dashboard_detail_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_detail_async\", f\"id={dashboard_id}\"\n ):\n dashboard_response = await self.get_dashboard_async(dashboard_id)\n dashboard_data = dashboard_response.get(\"result\", dashboard_response)\n charts: list[dict] = []\n datasets: list[dict] = []\n def extract_dataset_id_from_form_data(\n form_data: dict | None,\n ) -> int | None:\n if not isinstance(form_data, dict):\n return None\n datasource = form_data.get(\"datasource\")\n if isinstance(datasource, str):\n matched = re.match(r\"^(\\d+)__\", datasource)\n if matched:\n try:\n return int(matched.group(1))\n except ValueError:\n return None\n if isinstance(datasource, dict):\n ds_id = datasource.get(\"id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n ds_id = form_data.get(\"datasource_id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n chart_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/charts\",\n )\n dataset_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/datasets\",\n )\n charts_response, datasets_response = await asyncio.gather(\n chart_task,\n dataset_task,\n return_exceptions=True,\n )\n if not isinstance(charts_response, Exception):\n charts_payload = (\n charts_response.get(\"result\", [])\n if isinstance(charts_response, dict)\n else []\n )\n for chart_obj in charts_payload:\n if not isinstance(chart_obj, dict):\n continue\n chart_id = chart_obj.get(\"id\")\n if chart_id is None:\n continue\n form_data = chart_obj.get(\"form_data\")\n if isinstance(form_data, str):\n try:\n form_data = json.loads(form_data)\n except Exception:\n form_data = {}\n dataset_id = extract_dataset_id_from_form_data(\n form_data\n ) or chart_obj.get(\"datasource_id\")\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_obj.get(\"slice_name\")\n or chart_obj.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n ),\n \"dataset_id\": int(dataset_id)\n if dataset_id is not None\n else None,\n \"last_modified\": chart_obj.get(\"changed_on\"),\n \"overview\": chart_obj.get(\"description\")\n or (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n )\n or \"Chart\",\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard charts: %s\",\n charts_response,\n )\n if not isinstance(datasets_response, Exception):\n datasets_payload = (\n datasets_response.get(\"result\", [])\n if isinstance(datasets_response, dict)\n else []\n )\n for dataset_obj in datasets_payload:\n if not isinstance(dataset_obj, dict):\n continue\n dataset_id = dataset_obj.get(\"id\")\n if dataset_id is None:\n continue\n db_payload = dataset_obj.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_obj.get(\"table_name\")\n or dataset_obj.get(\"datasource_name\")\n or dataset_obj.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_obj.get(\"schema\")\n fq_name = f\"{schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_obj.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_obj.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard datasets: %s\",\n datasets_response,\n )\n if not charts:\n raw_position_json = dashboard_data.get(\"position_json\")\n chart_ids_from_position = set()\n if isinstance(raw_position_json, str) and raw_position_json:\n try:\n parsed_position = json.loads(raw_position_json)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_position)\n )\n except Exception:\n app_logger.debug(\"Could not parse position JSON for dashboard %s\", dashboard_ref)\n elif isinstance(raw_position_json, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_position_json)\n )\n raw_json_metadata = dashboard_data.get(\"json_metadata\")\n if isinstance(raw_json_metadata, str) and raw_json_metadata:\n try:\n parsed_metadata = json.loads(raw_json_metadata)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_metadata)\n )\n except Exception:\n app_logger.debug(\"Could not parse json_metadata for dashboard %s\", dashboard_ref)\n elif isinstance(raw_json_metadata, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_json_metadata)\n )\n fallback_chart_tasks = [\n self.get_chart_async(int(chart_id))\n for chart_id in sorted(chart_ids_from_position)\n ]\n fallback_chart_responses = await asyncio.gather(\n *fallback_chart_tasks,\n return_exceptions=True,\n )\n for chart_id, chart_response in zip(\n sorted(chart_ids_from_position), fallback_chart_responses\n ):\n if isinstance(chart_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to resolve fallback chart %s: %s\",\n chart_id,\n chart_response,\n )\n continue\n chart_data = chart_response.get(\"result\", chart_response)\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_data.get(\"slice_name\")\n or chart_data.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": chart_data.get(\"viz_type\"),\n \"dataset_id\": chart_data.get(\"datasource_id\"),\n \"last_modified\": chart_data.get(\"changed_on\"),\n \"overview\": chart_data.get(\"description\")\n or chart_data.get(\"viz_type\")\n or \"Chart\",\n }\n )\n dataset_ids_from_charts = {\n c.get(\"dataset_id\") for c in charts if c.get(\"dataset_id\") is not None\n }\n known_dataset_ids = {\n d.get(\"id\") for d in datasets if d.get(\"id\") is not None\n }\n missing_dataset_ids = sorted(\n int(item)\n for item in dataset_ids_from_charts\n if item not in known_dataset_ids\n )\n if missing_dataset_ids:\n dataset_fetch_tasks = [\n self.network.request(\n method=\"GET\", endpoint=f\"/dataset/{dataset_id}\"\n )\n for dataset_id in missing_dataset_ids\n ]\n dataset_fetch_responses = await asyncio.gather(\n *dataset_fetch_tasks,\n return_exceptions=True,\n )\n for dataset_id, dataset_response in zip(\n missing_dataset_ids, dataset_fetch_responses\n ):\n if isinstance(dataset_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to backfill dataset %s: %s\",\n dataset_id,\n dataset_response,\n )\n continue\n dataset_data = (\n dataset_response.get(\"result\", dataset_response)\n if isinstance(dataset_response, dict)\n else {}\n )\n db_payload = dataset_data.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_data.get(\"table_name\")\n or dataset_data.get(\"datasource_name\")\n or dataset_data.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_data.get(\"schema\")\n fq_name = f\" {schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_data.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_data.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n return {\n \"id\": int(dashboard_data.get(\"id\") or dashboard_id),\n \"title\": dashboard_data.get(\"dashboard_title\")\n or dashboard_data.get(\"title\")\n or f\"Dashboard {dashboard_id}\",\n \"slug\": dashboard_data.get(\"slug\"),\n \"url\": dashboard_data.get(\"url\"),\n \"description\": dashboard_data.get(\"description\"),\n \"last_modified\": dashboard_data.get(\"changed_on_utc\")\n or dashboard_data.get(\"changed_on\"),\n \"published\": dashboard_data.get(\"published\"),\n \"charts\": charts,\n \"datasets\": datasets,\n \"chart_count\": len(charts),\n \"dataset_count\": len(datasets),\n }\n # #endregion get_dashboard_detail_async\n # #region get_dashboard_permalink_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored dashboard permalink state asynchronously.\n # @POST Returns dashboard permalink state payload from Superset API.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n async def get_dashboard_permalink_state_async(self, permalink_key: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_permalink_state_async\",\n f\"key={permalink_key}\",\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/permalink/{permalink_key}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_permalink_state_async\n # #region get_native_filter_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored native filter state asynchronously.\n # @POST Returns native filter state payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n async def get_native_filter_state_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_native_filter_state_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n response = await self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/filter_state/{filter_state_key}\",\n )\n return cast(dict, response)\n # #endregion get_native_filter_state_async\n # #region extract_native_filters_from_permalink_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters dataMask from a permalink key asynchronously.\n # @POST Returns extracted dataMask with filter states.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_permalink_state_async]\n async def extract_native_filters_from_permalink_async(\n self, permalink_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_permalink_async\",\n f\"key={permalink_key}\",\n ):\n permalink_response = await self.get_dashboard_permalink_state_async(\n permalink_key\n )\n result = permalink_response.get(\"result\", permalink_response)\n state = result.get(\"state\", result)\n data_mask = state.get(\"dataMask\", {})\n extracted_filters = {}\n for filter_id, filter_data in data_mask.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"activeTabs\": state.get(\"activeTabs\", []),\n \"anchor\": state.get(\"anchor\"),\n \"chartStates\": state.get(\"chartStates\", {}),\n \"permalink_key\": permalink_key,\n }\n # #endregion extract_native_filters_from_permalink_async\n # #region extract_native_filters_from_key_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters from a native_filters_key URL parameter asynchronously.\n # @POST Returns extracted filter state with extraFormData.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_native_filter_state_async]\n async def extract_native_filters_from_key_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_key_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n filter_response = await self.get_native_filter_state_async(\n dashboard_id, filter_state_key\n )\n result = filter_response.get(\"result\", filter_response)\n value = result.get(\"value\")\n if isinstance(value, str):\n try:\n parsed_value = json.loads(value)\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[extract_native_filters_from_key_async][Warning] Failed to parse filter state JSON: %s\",\n e,\n )\n parsed_value = {}\n elif isinstance(value, dict):\n parsed_value = value\n else:\n parsed_value = {}\n extracted_filters = {}\n if \"id\" in parsed_value and \"extraFormData\" in parsed_value:\n filter_id = parsed_value.get(\"id\", filter_state_key)\n extracted_filters[filter_id] = {\n \"extraFormData\": parsed_value.get(\"extraFormData\", {}),\n \"filterState\": parsed_value.get(\"filterState\", {}),\n \"ownState\": parsed_value.get(\"ownState\", {}),\n }\n else:\n for filter_id, filter_data in parsed_value.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"dashboard_id\": dashboard_id,\n \"filter_state_key\": filter_state_key,\n }\n # #endregion extract_native_filters_from_key_async\n # #region parse_dashboard_url_for_filters_async [TYPE Function] [C:3]\n # @PURPOSE: Parse a Superset dashboard URL and extract native filter state asynchronously.\n # @POST Returns extracted filter state or empty dict if no filters found.\n # @DATA_CONTRACT Input[url: str] -> Output[Dict]\n # @RELATION CALLS -> [extract_native_filters_from_permalink_async]\n # @RELATION CALLS -> [extract_native_filters_from_key_async]\n async def parse_dashboard_url_for_filters_async(self, url: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.parse_dashboard_url_for_filters_async\", f\"url={url}\"\n ):\n import urllib.parse\n parsed_url = urllib.parse.urlparse(url)\n query_params = urllib.parse.parse_qs(parsed_url.query)\n path_parts = parsed_url.path.rstrip(\"/\").split(\"/\")\n result = {\n \"url\": url,\n \"dashboard_id\": None,\n \"filter_type\": None,\n \"filters\": {},\n }\n # Check for permalink URL: /dashboard/p/{key}/\n if \"p\" in path_parts:\n try:\n p_index = path_parts.index(\"p\")\n if p_index + 1 < len(path_parts):\n permalink_key = path_parts[p_index + 1]\n filter_data = (\n await self.extract_native_filters_from_permalink_async(\n permalink_key\n )\n )\n result[\"filter_type\"] = \"permalink\"\n result[\"filters\"] = filter_data\n return result\n except ValueError:\n app_logger.debug(\"Permalink key not found in URL for dashboard %s\", dashboard_ref)\n # Check for native_filters_key in query params\n native_filters_key = query_params.get(\"native_filters_key\", [None])[0]\n if native_filters_key:\n dashboard_ref = None\n if \"dashboard\" in path_parts:\n try:\n dash_index = path_parts.index(\"dashboard\")\n if dash_index + 1 < len(path_parts):\n potential_id = path_parts[dash_index + 1]\n if potential_id not in (\"p\", \"list\", \"new\"):\n dashboard_ref = potential_id\n except ValueError:\n app_logger.debug(\"Dashboard not found in path_parts for native_filters_key\")\n if dashboard_ref:\n # Resolve slug to numeric ID — the filter_state API requires a numeric ID\n resolved_id = None\n try:\n resolved_id = int(dashboard_ref)\n except (ValueError, TypeError):\n try:\n dash_resp = await self.get_dashboard_async(dashboard_ref)\n dash_data = (\n dash_resp.get(\"result\", dash_resp)\n if isinstance(dash_resp, dict)\n else {}\n )\n raw_id = dash_data.get(\"id\")\n if raw_id is not None:\n resolved_id = int(raw_id)\n except Exception as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to resolve dashboard slug '%s' to ID: %s\",\n dashboard_ref,\n e,\n )\n if resolved_id is not None:\n filter_data = await self.extract_native_filters_from_key_async(\n resolved_id, native_filters_key\n )\n result[\"filter_type\"] = \"native_filters_key\"\n result[\"dashboard_id\"] = resolved_id\n result[\"filters\"] = filter_data\n return result\n else:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Could not resolve dashboard_id from URL for native_filters_key\"\n )\n return result\n # Check for native_filters in query params (direct filter values)\n native_filters = query_params.get(\"native_filters\", [None])[0]\n if native_filters:\n try:\n parsed_filters = json.loads(native_filters)\n result[\"filter_type\"] = \"native_filters\"\n result[\"filters\"] = {\"dataMask\": parsed_filters}\n return result\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to parse native_filters JSON: %s\",\n e,\n )\n return result\n # #endregion parse_dashboard_url_for_filters_async\n# #endregion AsyncSupersetClient\n"
+ "body": "# #region AsyncSupersetClient [C:3] [TYPE Class]\n# @BRIEF Async sibling of SupersetClient for dashboard read paths.\n# @RELATION INHERITS -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [AsyncAPIClient]\nclass AsyncSupersetClient(SupersetClient):\n # #region AsyncSupersetClientInit [TYPE Function] [C:3]\n # @PURPOSE: Initialize async Superset client with AsyncAPIClient transport.\n # @PRE env is valid Environment instance.\n # @POST Client uses async network transport and inherited projection helpers.\n # @DATA_CONTRACT Input[Environment] -> self.network[AsyncAPIClient]\n # @RELATION DEPENDS_ON -> [AsyncAPIClient]\n def __init__(self, env: Environment):\n self.env = env\n auth_payload = {\n \"username\": env.username,\n \"password\": env.password,\n \"provider\": \"db\",\n \"refresh\": \"true\",\n }\n self.network = AsyncAPIClient(\n config={\"base_url\": env.url, \"auth\": auth_payload},\n verify_ssl=env.verify_ssl,\n timeout=env.timeout,\n )\n self.delete_before_reimport = False\n # #endregion AsyncSupersetClientInit\n # #region AsyncSupersetClientClose [TYPE Function] [C:3]\n # @PURPOSE: Close async transport resources.\n # @POST Underlying AsyncAPIClient is closed.\n # @SIDE_EFFECT Closes network sockets.\n # @RELATION CALLS -> [AsyncAPIClient.aclose]\n async def aclose(self) -> None:\n await self.network.aclose()\n # #endregion AsyncSupersetClientClose\n # #region get_dashboards_page_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboards page asynchronously.\n # @POST Returns total count and page result list.\n # @DATA_CONTRACT Input[query: Optional[Dict]] -> Output[Tuple[int, List[Dict]]]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboards_page_async(\n self, query: dict | None = None\n ) -> tuple[int, list[dict]]:\n with belief_scope(\"AsyncSupersetClient.get_dashboards_page_async\"):\n validated_query = self._validate_query_params(query or {})\n if \"columns\" not in validated_query:\n validated_query[\"columns\"] = [\n \"slug\",\n \"id\",\n \"url\",\n \"changed_on_utc\",\n \"dashboard_title\",\n \"published\",\n \"created_by\",\n \"changed_by\",\n \"changed_by_name\",\n \"owners\",\n ]\n response_json = cast(\n dict[str, Any],\n await self.network.request(\n method=\"GET\",\n endpoint=\"/dashboard/\",\n params={\"q\": json.dumps(validated_query)},\n ),\n )\n result = response_json.get(\"result\", [])\n total_count = response_json.get(\"count\", len(result))\n return total_count, result\n # #endregion get_dashboards_page_async\n # #region get_dashboard_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one dashboard payload asynchronously.\n # @POST Returns raw dashboard payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_dashboard_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_async\", f\"id={dashboard_id}\"\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_async\n # #region get_chart_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch one chart payload asynchronously.\n # @POST Returns raw chart payload from Superset API.\n # @DATA_CONTRACT Input[chart_id: int] -> Output[Dict]\n # @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]\n async def get_chart_async(self, chart_id: int) -> dict:\n with belief_scope(\"AsyncSupersetClient.get_chart_async\", f\"id={chart_id}\"):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/chart/{chart_id}\"\n )\n return cast(dict, response)\n # #endregion get_chart_async\n # #region get_dashboard_detail_async [TYPE Function] [C:3]\n # @PURPOSE: Fetch dashboard detail asynchronously with concurrent charts/datasets requests.\n # @POST Returns dashboard detail payload for overview page.\n # @DATA_CONTRACT Input[dashboard_id: int] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_async]\n # @RELATION CALLS -> [get_chart_async]\n async def get_dashboard_detail_async(self, dashboard_id: int) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_detail_async\", f\"id={dashboard_id}\"\n ):\n dashboard_response = await self.get_dashboard_async(dashboard_id)\n dashboard_data = dashboard_response.get(\"result\", dashboard_response)\n charts: list[dict] = []\n datasets: list[dict] = []\n def extract_dataset_id_from_form_data(\n form_data: dict | None,\n ) -> int | None:\n if not isinstance(form_data, dict):\n return None\n datasource = form_data.get(\"datasource\")\n if isinstance(datasource, str):\n matched = re.match(r\"^(\\d+)__\", datasource)\n if matched:\n try:\n return int(matched.group(1))\n except ValueError:\n return None\n if isinstance(datasource, dict):\n ds_id = datasource.get(\"id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n ds_id = form_data.get(\"datasource_id\")\n try:\n return int(ds_id) if ds_id is not None else None\n except (TypeError, ValueError):\n return None\n chart_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/charts\",\n )\n dataset_task = self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/datasets\",\n )\n charts_response, datasets_response = await asyncio.gather(\n chart_task,\n dataset_task,\n return_exceptions=True,\n )\n if not isinstance(charts_response, Exception):\n charts_payload = (\n charts_response.get(\"result\", [])\n if isinstance(charts_response, dict)\n else []\n )\n for chart_obj in charts_payload:\n if not isinstance(chart_obj, dict):\n continue\n chart_id = chart_obj.get(\"id\")\n if chart_id is None:\n continue\n form_data = chart_obj.get(\"form_data\")\n if isinstance(form_data, str):\n try:\n form_data = json.loads(form_data)\n except Exception:\n form_data = {}\n dataset_id = extract_dataset_id_from_form_data(\n form_data\n ) or chart_obj.get(\"datasource_id\")\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_obj.get(\"slice_name\")\n or chart_obj.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n ),\n \"dataset_id\": int(dataset_id)\n if dataset_id is not None\n else None,\n \"last_modified\": chart_obj.get(\"changed_on\"),\n \"overview\": chart_obj.get(\"description\")\n or (\n form_data.get(\"viz_type\")\n if isinstance(form_data, dict)\n else None\n )\n or \"Chart\",\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard charts: %s\",\n charts_response,\n )\n if not isinstance(datasets_response, Exception):\n datasets_payload = (\n datasets_response.get(\"result\", [])\n if isinstance(datasets_response, dict)\n else []\n )\n for dataset_obj in datasets_payload:\n if not isinstance(dataset_obj, dict):\n continue\n dataset_id = dataset_obj.get(\"id\")\n if dataset_id is None:\n continue\n db_payload = dataset_obj.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_obj.get(\"table_name\")\n or dataset_obj.get(\"datasource_name\")\n or dataset_obj.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_obj.get(\"schema\")\n fq_name = f\"{schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_obj.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_obj.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n else:\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to fetch dashboard datasets: %s\",\n datasets_response,\n )\n if not charts:\n raw_position_json = dashboard_data.get(\"position_json\")\n chart_ids_from_position = set()\n if isinstance(raw_position_json, str) and raw_position_json:\n try:\n parsed_position = json.loads(raw_position_json)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_position)\n )\n except Exception:\n app_logger.debug(\"Could not parse position JSON for dashboard %s\", dashboard_ref)\n elif isinstance(raw_position_json, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_position_json)\n )\n raw_json_metadata = dashboard_data.get(\"json_metadata\")\n if isinstance(raw_json_metadata, str) and raw_json_metadata:\n try:\n parsed_metadata = json.loads(raw_json_metadata)\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(parsed_metadata)\n )\n except Exception:\n app_logger.debug(\"Could not parse json_metadata for dashboard %s\", dashboard_ref)\n elif isinstance(raw_json_metadata, dict):\n chart_ids_from_position.update(\n self._extract_chart_ids_from_layout(raw_json_metadata)\n )\n fallback_chart_tasks = [\n self.get_chart_async(int(chart_id))\n for chart_id in sorted(chart_ids_from_position)\n ]\n fallback_chart_responses = await asyncio.gather(\n *fallback_chart_tasks,\n return_exceptions=True,\n )\n for chart_id, chart_response in zip(\n sorted(chart_ids_from_position), fallback_chart_responses\n ):\n if isinstance(chart_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to resolve fallback chart %s: %s\",\n chart_id,\n chart_response,\n )\n continue\n chart_data = chart_response.get(\"result\", chart_response)\n charts.append(\n {\n \"id\": int(chart_id),\n \"title\": chart_data.get(\"slice_name\")\n or chart_data.get(\"name\")\n or f\"Chart {chart_id}\",\n \"viz_type\": chart_data.get(\"viz_type\"),\n \"dataset_id\": chart_data.get(\"datasource_id\"),\n \"last_modified\": chart_data.get(\"changed_on\"),\n \"overview\": chart_data.get(\"description\")\n or chart_data.get(\"viz_type\")\n or \"Chart\",\n }\n )\n dataset_ids_from_charts = {\n c.get(\"dataset_id\") for c in charts if c.get(\"dataset_id\") is not None\n }\n known_dataset_ids = {\n d.get(\"id\") for d in datasets if d.get(\"id\") is not None\n }\n missing_dataset_ids = sorted(\n int(item)\n for item in dataset_ids_from_charts\n if item not in known_dataset_ids\n )\n if missing_dataset_ids:\n dataset_fetch_tasks = [\n self.network.request(\n method=\"GET\", endpoint=f\"/dataset/{dataset_id}\"\n )\n for dataset_id in missing_dataset_ids\n ]\n dataset_fetch_responses = await asyncio.gather(\n *dataset_fetch_tasks,\n return_exceptions=True,\n )\n for dataset_id, dataset_response in zip(\n missing_dataset_ids, dataset_fetch_responses\n ):\n if isinstance(dataset_response, Exception):\n app_logger.warning(\n \"[get_dashboard_detail_async][Warning] Failed to backfill dataset %s: %s\",\n dataset_id,\n dataset_response,\n )\n continue\n dataset_data = (\n dataset_response.get(\"result\", dataset_response)\n if isinstance(dataset_response, dict)\n else {}\n )\n db_payload = dataset_data.get(\"database\")\n db_name = (\n db_payload.get(\"database_name\")\n if isinstance(db_payload, dict)\n else None\n )\n table_name = (\n dataset_data.get(\"table_name\")\n or dataset_data.get(\"datasource_name\")\n or dataset_data.get(\"name\")\n or f\"Dataset {dataset_id}\"\n )\n schema = dataset_data.get(\"schema\")\n fq_name = f\" {schema}.{table_name}\" if schema else table_name\n datasets.append(\n {\n \"id\": int(dataset_id),\n \"table_name\": table_name,\n \"schema\": schema,\n \"database\": db_name\n or dataset_data.get(\"database_name\")\n or \"Unknown\",\n \"last_modified\": dataset_data.get(\"changed_on\"),\n \"overview\": fq_name,\n }\n )\n return {\n \"id\": int(dashboard_data.get(\"id\") or dashboard_id),\n \"title\": dashboard_data.get(\"dashboard_title\")\n or dashboard_data.get(\"title\")\n or f\"Dashboard {dashboard_id}\",\n \"slug\": dashboard_data.get(\"slug\"),\n \"url\": dashboard_data.get(\"url\"),\n \"description\": dashboard_data.get(\"description\"),\n \"last_modified\": dashboard_data.get(\"changed_on_utc\")\n or dashboard_data.get(\"changed_on\"),\n \"published\": dashboard_data.get(\"published\"),\n \"charts\": charts,\n \"datasets\": datasets,\n \"chart_count\": len(charts),\n \"dataset_count\": len(datasets),\n }\n # #endregion get_dashboard_detail_async\n # #region get_dashboard_permalink_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored dashboard permalink state asynchronously.\n # @POST Returns dashboard permalink state payload from Superset API.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n async def get_dashboard_permalink_state_async(self, permalink_key: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_dashboard_permalink_state_async\",\n f\"key={permalink_key}\",\n ):\n response = await self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/permalink/{permalink_key}\"\n )\n return cast(dict, response)\n # #endregion get_dashboard_permalink_state_async\n # #region get_native_filter_state_async [TYPE Function] [C:2]\n # @PURPOSE: Fetch stored native filter state asynchronously.\n # @POST Returns native filter state payload from Superset API.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n async def get_native_filter_state_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.get_native_filter_state_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n response = await self.network.request(\n method=\"GET\",\n endpoint=f\"/dashboard/{dashboard_id}/filter_state/{filter_state_key}\",\n )\n return cast(dict, response)\n # #endregion get_native_filter_state_async\n # #region extract_native_filters_from_permalink_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters dataMask from a permalink key asynchronously.\n # @POST Returns extracted dataMask with filter states.\n # @DATA_CONTRACT Input[permalink_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_dashboard_permalink_state_async]\n async def extract_native_filters_from_permalink_async(\n self, permalink_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_permalink_async\",\n f\"key={permalink_key}\",\n ):\n permalink_response = await self.get_dashboard_permalink_state_async(\n permalink_key\n )\n result = permalink_response.get(\"result\", permalink_response)\n state = result.get(\"state\", result)\n data_mask = state.get(\"dataMask\", {})\n extracted_filters = {}\n for filter_id, filter_data in data_mask.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"activeTabs\": state.get(\"activeTabs\", []),\n \"anchor\": state.get(\"anchor\"),\n \"chartStates\": state.get(\"chartStates\", {}),\n \"permalink_key\": permalink_key,\n }\n # #endregion extract_native_filters_from_permalink_async\n # #region extract_native_filters_from_key_async [TYPE Function] [C:3]\n # @PURPOSE: Extract native filters from a native_filters_key URL parameter asynchronously.\n # @POST Returns extracted filter state with extraFormData.\n # @DATA_CONTRACT Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]\n # @RELATION CALLS -> [get_native_filter_state_async]\n async def extract_native_filters_from_key_async(\n self, dashboard_id: int, filter_state_key: str\n ) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.extract_native_filters_from_key_async\",\n f\"dashboard={dashboard_id}, key={filter_state_key}\",\n ):\n filter_response = await self.get_native_filter_state_async(\n dashboard_id, filter_state_key\n )\n result = filter_response.get(\"result\", filter_response)\n value = result.get(\"value\")\n if isinstance(value, str):\n try:\n parsed_value = json.loads(value)\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[extract_native_filters_from_key_async][Warning] Failed to parse filter state JSON: %s\",\n e,\n )\n parsed_value = {}\n elif isinstance(value, dict):\n parsed_value = value\n else:\n parsed_value = {}\n extracted_filters = {}\n if \"id\" in parsed_value and \"extraFormData\" in parsed_value:\n filter_id = parsed_value.get(\"id\", filter_state_key)\n extracted_filters[filter_id] = {\n \"extraFormData\": parsed_value.get(\"extraFormData\", {}),\n \"filterState\": parsed_value.get(\"filterState\", {}),\n \"ownState\": parsed_value.get(\"ownState\", {}),\n }\n else:\n for filter_id, filter_data in parsed_value.items():\n if not isinstance(filter_data, dict):\n continue\n extracted_filters[filter_id] = {\n \"extraFormData\": filter_data.get(\"extraFormData\", {}),\n \"filterState\": filter_data.get(\"filterState\", {}),\n \"ownState\": filter_data.get(\"ownState\", {}),\n }\n return {\n \"dataMask\": extracted_filters,\n \"dashboard_id\": dashboard_id,\n \"filter_state_key\": filter_state_key,\n }\n # #endregion extract_native_filters_from_key_async\n # #region parse_dashboard_url_for_filters_async [TYPE Function] [C:3]\n # @PURPOSE: Parse a Superset dashboard URL and extract native filter state asynchronously.\n # @POST Returns extracted filter state or empty dict if no filters found.\n # @DATA_CONTRACT Input[url: str] -> Output[Dict]\n # @RELATION CALLS -> [extract_native_filters_from_permalink_async]\n # @RELATION CALLS -> [extract_native_filters_from_key_async]\n async def parse_dashboard_url_for_filters_async(self, url: str) -> dict:\n with belief_scope(\n \"AsyncSupersetClient.parse_dashboard_url_for_filters_async\", f\"url={url}\"\n ):\n import urllib.parse\n parsed_url = urllib.parse.urlparse(url)\n query_params = urllib.parse.parse_qs(parsed_url.query)\n path_parts = parsed_url.path.rstrip(\"/\").split(\"/\")\n result = {\n \"url\": url,\n \"dashboard_id\": None,\n \"filter_type\": None,\n \"filters\": {},\n }\n # Check for permalink URL: /dashboard/p/{key}/\n if \"p\" in path_parts:\n try:\n p_index = path_parts.index(\"p\")\n if p_index + 1 < len(path_parts):\n permalink_key = path_parts[p_index + 1]\n filter_data = (\n await self.extract_native_filters_from_permalink_async(\n permalink_key\n )\n )\n result[\"filter_type\"] = \"permalink\"\n result[\"filters\"] = filter_data\n return result\n except ValueError:\n app_logger.debug(\"Permalink key not found in URL for dashboard %s\", dashboard_ref)\n # Check for native_filters_key in query params\n native_filters_key = query_params.get(\"native_filters_key\", [None])[0]\n if native_filters_key:\n dashboard_ref = None\n if \"dashboard\" in path_parts:\n try:\n dash_index = path_parts.index(\"dashboard\")\n if dash_index + 1 < len(path_parts):\n potential_id = path_parts[dash_index + 1]\n if potential_id not in (\"p\", \"list\", \"new\"):\n dashboard_ref = potential_id\n except ValueError:\n app_logger.debug(\"Dashboard not found in path_parts for native_filters_key\")\n if dashboard_ref:\n # Resolve slug to numeric ID — the filter_state API requires a numeric ID\n resolved_id = None\n try:\n resolved_id = int(dashboard_ref)\n except (ValueError, TypeError):\n try:\n dash_resp = await self.get_dashboard_async(dashboard_ref)\n dash_data = (\n dash_resp.get(\"result\", dash_resp)\n if isinstance(dash_resp, dict)\n else {}\n )\n raw_id = dash_data.get(\"id\")\n if raw_id is not None:\n resolved_id = int(raw_id)\n except Exception as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to resolve dashboard slug '%s' to ID: %s\",\n dashboard_ref,\n e,\n )\n if resolved_id is not None:\n filter_data = await self.extract_native_filters_from_key_async(\n resolved_id, native_filters_key\n )\n result[\"filter_type\"] = \"native_filters_key\"\n result[\"dashboard_id\"] = resolved_id\n result[\"filters\"] = filter_data\n return result\n else:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Could not resolve dashboard_id from URL for native_filters_key\"\n )\n return result\n # Check for native_filters in query params (direct filter values)\n native_filters = query_params.get(\"native_filters\", [None])[0]\n if native_filters:\n try:\n parsed_filters = json.loads(native_filters)\n result[\"filter_type\"] = \"native_filters\"\n result[\"filters\"] = {\"dataMask\": parsed_filters}\n return result\n except json.JSONDecodeError as e:\n app_logger.warning(\n \"[parse_dashboard_url_for_filters_async][Warning] Failed to parse native_filters JSON: %s\",\n e,\n )\n return result\n # #endregion parse_dashboard_url_for_filters_async\n# #endregion AsyncSupersetClient\n"
},
{
"contract_id": "AsyncSupersetClientInit",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 21,
- "end_line": 41,
+ "start_line": 20,
+ "end_line": 40,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18175,8 +18205,8 @@
"contract_id": "AsyncSupersetClientClose",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 42,
- "end_line": 49,
+ "start_line": 41,
+ "end_line": 48,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18202,8 +18232,8 @@
"contract_id": "get_dashboards_page_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 50,
- "end_line": 84,
+ "start_line": 49,
+ "end_line": 83,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18229,8 +18259,8 @@
"contract_id": "get_dashboard_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 85,
- "end_line": 98,
+ "start_line": 84,
+ "end_line": 97,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18256,8 +18286,8 @@
"contract_id": "get_chart_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 99,
- "end_line": 110,
+ "start_line": 98,
+ "end_line": 109,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18283,8 +18313,8 @@
"contract_id": "get_dashboard_detail_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 111,
- "end_line": 395,
+ "start_line": 110,
+ "end_line": 394,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18316,8 +18346,8 @@
"contract_id": "get_dashboard_permalink_state_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 396,
- "end_line": 409,
+ "start_line": 395,
+ "end_line": 408,
"tier": "TIER_1",
"complexity": 2,
"metadata": {
@@ -18336,8 +18366,8 @@
"contract_id": "get_native_filter_state_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 410,
- "end_line": 426,
+ "start_line": 409,
+ "end_line": 425,
"tier": "TIER_1",
"complexity": 2,
"metadata": {
@@ -18356,8 +18386,8 @@
"contract_id": "extract_native_filters_from_permalink_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 427,
- "end_line": 461,
+ "start_line": 426,
+ "end_line": 460,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18383,8 +18413,8 @@
"contract_id": "extract_native_filters_from_key_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 462,
- "end_line": 514,
+ "start_line": 461,
+ "end_line": 513,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18410,8 +18440,8 @@
"contract_id": "parse_dashboard_url_for_filters_async",
"contract_type": "Function",
"file_path": "backend/src/core/async_superset_client.py",
- "start_line": 515,
- "end_line": 613,
+ "start_line": 514,
+ "end_line": 612,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -18456,6 +18486,32 @@
"tier_source": "AutoCalculated",
"body": "# #region AuthPackage [TYPE Package] [SEMANTICS auth, package, init]\n# @BRIEF Authentication and authorization package root.\n# #endregion AuthPackage\n"
},
+ {
+ "contract_id": "test_auth",
+ "contract_type": "Module",
+ "file_path": "backend/src/core/auth/__tests__/test_auth.py",
+ "start_line": 1,
+ "end_line": 259,
+ "tier": "TIER_2",
+ "complexity": 3,
+ "metadata": {
+ "BRIEF": "Unit tests for authentication module",
+ "COMPLEXITY": 3,
+ "LAYER": "Domain"
+ },
+ "relations": [
+ {
+ "source_id": "test_auth",
+ "relation_type": "BINDS_TO",
+ "target_id": "AuthPackage",
+ "target_ref": "AuthPackage"
+ }
+ ],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "# #region test_auth [TYPE Module] [C:3] [SEMANTICS test, auth, authentication, unit]\n# @BRIEF Unit tests for authentication module\n# @LAYER Domain\n# @RELATION BINDS_TO -> AuthPackage\nfrom pathlib import Path\nimport sys\n\n# Add src to path\nsys.path.append(str(Path(__file__).parent.parent.parent.parent / \"src\"))\nimport pytest\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom src.core.auth.repository import AuthRepository\nfrom src.core.auth.security import get_password_hash, verify_password\nfrom src.core.database import Base\n\n# Import all models to ensure they are registered with Base before create_all - must import both auth and mapping to ensure Base knows about all tables\nfrom src.models.auth import ADGroupMapping, Permission, Role, User\nfrom src.services.auth_service import AuthService\n\n# Create in-memory SQLite database for testing\nSQLALCHEMY_DATABASE_URL = \"sqlite:///:memory:\"\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n# Create all tables\nBase.metadata.create_all(bind=engine)\n@pytest.fixture\ndef db_session():\n \"\"\"Create a new database session with a transaction, rollback after test\"\"\"\n connection = engine.connect()\n transaction = connection.begin()\n session = TestingSessionLocal(bind=connection)\n yield session\n session.close()\n transaction.rollback()\n connection.close()\n@pytest.fixture\ndef auth_service(db_session):\n return AuthService(db_session)\n@pytest.fixture\ndef auth_repo(db_session):\n return AuthRepository(db_session)\n# #region test_create_user [TYPE Function]\n# @BRIEF Verifies that a persisted user can be retrieved with intact credential hash.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_create_user(auth_repo):\n \"\"\"Test user creation\"\"\"\n user = User(\n username=\"testuser\",\n email=\"test@example.com\",\n password_hash=get_password_hash(\"testpassword123\"),\n auth_source=\"LOCAL\",\n )\n auth_repo.db.add(user)\n auth_repo.db.commit()\n retrieved_user = auth_repo.get_user_by_username(\"testuser\")\n assert retrieved_user is not None\n assert retrieved_user.username == \"testuser\"\n assert retrieved_user.email == \"test@example.com\"\n assert verify_password(\"testpassword123\", retrieved_user.password_hash)\n# #endregion test_create_user\n# #region test_authenticate_user [TYPE Function]\n# @BRIEF Validates authentication outcomes for valid, wrong-password, and unknown-user cases.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_authenticate_user(auth_service, auth_repo):\n \"\"\"Test user authentication with valid and invalid credentials\"\"\"\n user = User(\n username=\"testuser\",\n email=\"test@example.com\",\n password_hash=get_password_hash(\"testpassword123\"),\n auth_source=\"LOCAL\",\n )\n auth_repo.db.add(user)\n auth_repo.db.commit()\n # Test valid credentials\n authenticated_user = auth_service.authenticate_user(\"testuser\", \"testpassword123\")\n assert authenticated_user is not None\n assert authenticated_user.username == \"testuser\"\n # Test invalid password\n invalid_user = auth_service.authenticate_user(\"testuser\", \"wrongpassword\")\n assert invalid_user is None\n # Test invalid username\n invalid_user = auth_service.authenticate_user(\"nonexistent\", \"testpassword123\")\n assert invalid_user is None\n# #endregion test_authenticate_user\n# #region test_create_session [TYPE Function]\n# @BRIEF Ensures session creation returns bearer token payload fields.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_create_session(auth_service, auth_repo):\n \"\"\"Test session token creation\"\"\"\n user = User(\n username=\"testuser\",\n email=\"test@example.com\",\n password_hash=get_password_hash(\"testpassword123\"),\n auth_source=\"LOCAL\",\n )\n auth_repo.db.add(user)\n auth_repo.db.commit()\n session = auth_service.create_session(user)\n assert \"access_token\" in session\n assert \"token_type\" in session\n assert session[\"token_type\"] == \"bearer\"\n assert len(session[\"access_token\"]) > 0\n# #endregion test_create_session\n# #region test_role_permission_association [TYPE Function]\n# @BRIEF Confirms role-permission many-to-many assignments persist and reload correctly.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_role_permission_association(auth_repo):\n \"\"\"Test role and permission association\"\"\"\n role = Role(name=\"Admin\", description=\"System administrator\")\n perm1 = Permission(resource=\"admin:users\", action=\"READ\")\n perm2 = Permission(resource=\"admin:users\", action=\"WRITE\")\n role.permissions.extend([perm1, perm2])\n auth_repo.db.add(role)\n auth_repo.db.commit()\n retrieved_role = auth_repo.get_role_by_name(\"Admin\")\n assert retrieved_role is not None\n assert len(retrieved_role.permissions) == 2\n permissions = [f\"{p.resource}:{p.action}\" for p in retrieved_role.permissions]\n assert \"admin:users:READ\" in permissions\n assert \"admin:users:WRITE\" in permissions\n# #endregion test_role_permission_association\n# #region test_user_role_association [TYPE Function]\n# @BRIEF Confirms user-role assignment persists and is queryable from repository reads.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_user_role_association(auth_repo):\n \"\"\"Test user and role association\"\"\"\n role = Role(name=\"Admin\", description=\"System administrator\")\n user = User(\n username=\"adminuser\",\n email=\"admin@example.com\",\n password_hash=get_password_hash(\"adminpass123\"),\n auth_source=\"LOCAL\",\n )\n user.roles.append(role)\n auth_repo.db.add(role)\n auth_repo.db.add(user)\n auth_repo.db.commit()\n retrieved_user = auth_repo.get_user_by_username(\"adminuser\")\n assert retrieved_user is not None\n assert len(retrieved_user.roles) == 1\n assert retrieved_user.roles[0].name == \"Admin\"\n# #endregion test_user_role_association\n# #region test_ad_group_mapping [TYPE Function]\n# @BRIEF Verifies AD group mapping rows persist and reference the expected role.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_ad_group_mapping(auth_repo):\n \"\"\"Test AD group mapping\"\"\"\n role = Role(name=\"ADFS_Admin\", description=\"ADFS administrators\")\n auth_repo.db.add(role)\n auth_repo.db.commit()\n mapping = ADGroupMapping(ad_group=\"DOMAIN\\\\ADFS_Admins\", role_id=role.id)\n auth_repo.db.add(mapping)\n auth_repo.db.commit()\n retrieved_mapping = (\n auth_repo.db.query(ADGroupMapping)\n .filter_by(ad_group=\"DOMAIN\\\\ADFS_Admins\")\n .first()\n )\n assert retrieved_mapping is not None\n assert retrieved_mapping.role_id == role.id\n# #endregion test_ad_group_mapping\n# #region test_authenticate_user_updates_last_login [TYPE Function]\n# @BRIEF Verifies successful authentication updates last_login audit field.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_authenticate_user_updates_last_login(auth_service, auth_repo):\n \"\"\"@SIDE_EFFECT: authenticate_user updates last_login timestamp on success.\"\"\"\n user = User(\n username=\"loginuser\",\n email=\"login@example.com\",\n password_hash=get_password_hash(\"mypassword\"),\n auth_source=\"LOCAL\",\n )\n auth_repo.db.add(user)\n auth_repo.db.commit()\n assert user.last_login is None\n authenticated = auth_service.authenticate_user(\"loginuser\", \"mypassword\")\n assert authenticated is not None\n assert authenticated.last_login is not None\n# #endregion test_authenticate_user_updates_last_login\n# #region test_authenticate_inactive_user [TYPE Function]\n# @BRIEF Verifies inactive accounts are rejected during password authentication.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_authenticate_inactive_user(auth_service, auth_repo):\n \"\"\"@PRE: User with is_active=False should not authenticate.\"\"\"\n user = User(\n username=\"inactive_user\",\n email=\"inactive@example.com\",\n password_hash=get_password_hash(\"testpass\"),\n auth_source=\"LOCAL\",\n is_active=False,\n )\n auth_repo.db.add(user)\n auth_repo.db.commit()\n result = auth_service.authenticate_user(\"inactive_user\", \"testpass\")\n assert result is None\n# #endregion test_authenticate_inactive_user\n# #region test_verify_password_empty_hash [TYPE Function]\n# @BRIEF Verifies password verification safely rejects empty or null password hashes.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_verify_password_empty_hash():\n \"\"\"@PRE: verify_password with empty/None hash returns False.\"\"\"\n assert verify_password(\"anypassword\", \"\") is False\n assert verify_password(\"anypassword\", None) is False\n# #endregion test_verify_password_empty_hash\n# #region test_provision_adfs_user_new [TYPE Function]\n# @BRIEF Verifies JIT provisioning creates a new ADFS user and maps group-derived roles.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_provision_adfs_user_new(auth_service, auth_repo):\n \"\"\"@POST: provision_adfs_user creates a new ADFS user with correct roles.\"\"\"\n # Set up a role and AD group mapping\n role = Role(name=\"ADFS_Viewer\", description=\"ADFS viewer role\")\n auth_repo.db.add(role)\n auth_repo.db.commit()\n mapping = ADGroupMapping(ad_group=\"DOMAIN\\\\Viewers\", role_id=role.id)\n auth_repo.db.add(mapping)\n auth_repo.db.commit()\n user_info = {\n \"upn\": \"newadfsuser@domain.com\",\n \"email\": \"newadfsuser@domain.com\",\n \"groups\": [\"DOMAIN\\\\Viewers\"],\n }\n user = auth_service.provision_adfs_user(user_info)\n assert user is not None\n assert user.username == \"newadfsuser@domain.com\"\n assert user.auth_source == \"ADFS\"\n assert user.is_active is True\n assert len(user.roles) == 1\n assert user.roles[0].name == \"ADFS_Viewer\"\n# #endregion test_provision_adfs_user_new\n# #region test_provision_adfs_user_existing [TYPE Function]\n# @BRIEF Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_provision_adfs_user_existing(auth_service, auth_repo):\n \"\"\"@POST: provision_adfs_user updates roles for existing user.\"\"\"\n # Create existing user\n existing = User(\n username=\"existingadfs@domain.com\",\n email=\"existingadfs@domain.com\",\n auth_source=\"ADFS\",\n is_active=True,\n )\n auth_repo.db.add(existing)\n auth_repo.db.commit()\n user_info = {\n \"upn\": \"existingadfs@domain.com\",\n \"email\": \"existingadfs@domain.com\",\n \"groups\": [],\n }\n user = auth_service.provision_adfs_user(user_info)\n assert user is not None\n assert user.username == \"existingadfs@domain.com\"\n assert len(user.roles) == 0 # No matching group mappings\n# #endregion test_provision_adfs_user_existing\n# #endregion test_auth\n"
+ },
{
"contract_id": "test_create_user",
"contract_type": "Function",
@@ -18701,7 +18757,7 @@
"contract_type": "Function",
"file_path": "backend/src/core/auth/__tests__/test_auth.py",
"start_line": 235,
- "end_line": 259,
+ "end_line": 258,
"tier": "TIER_1",
"complexity": 2,
"metadata": {
@@ -18718,7 +18774,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region test_provision_adfs_user_existing [TYPE Function]\n# @BRIEF Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_provision_adfs_user_existing(auth_service, auth_repo):\n \"\"\"@POST: provision_adfs_user updates roles for existing user.\"\"\"\n # Create existing user\n existing = User(\n username=\"existingadfs@domain.com\",\n email=\"existingadfs@domain.com\",\n auth_source=\"ADFS\",\n is_active=True,\n )\n auth_repo.db.add(existing)\n auth_repo.db.commit()\n user_info = {\n \"upn\": \"existingadfs@domain.com\",\n \"email\": \"existingadfs@domain.com\",\n \"groups\": [],\n }\n user = auth_service.provision_adfs_user(user_info)\n assert user is not None\n assert user.username == \"existingadfs@domain.com\"\n assert len(user.roles) == 0 # No matching group mappings\n# #endregion test_auth\n# #endregion test_provision_adfs_user_existing\n"
+ "body": "# #region test_provision_adfs_user_existing [TYPE Function]\n# @BRIEF Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.\n# @RELATION BINDS_TO -> [test_auth]\ndef test_provision_adfs_user_existing(auth_service, auth_repo):\n \"\"\"@POST: provision_adfs_user updates roles for existing user.\"\"\"\n # Create existing user\n existing = User(\n username=\"existingadfs@domain.com\",\n email=\"existingadfs@domain.com\",\n auth_source=\"ADFS\",\n is_active=True,\n )\n auth_repo.db.add(existing)\n auth_repo.db.commit()\n user_info = {\n \"upn\": \"existingadfs@domain.com\",\n \"email\": \"existingadfs@domain.com\",\n \"groups\": [],\n }\n user = auth_service.provision_adfs_user(user_info)\n assert user is not None\n assert user.username == \"existingadfs@domain.com\"\n assert len(user.roles) == 0 # No matching group mappings\n# #endregion test_provision_adfs_user_existing\n"
},
{
"contract_id": "APIKeyUtilities",
@@ -19951,7 +20007,7 @@
"contract_type": "Module",
"file_path": "backend/src/core/config_models.py",
"start_line": 1,
- "end_line": 143,
+ "end_line": 150,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -19963,27 +20019,63 @@
{
"source_id": "ConfigModels",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:CoreContracts",
- "target_ref": "[EXT:internal:CoreContracts]"
+ "target_id": "CoreContracts",
+ "target_ref": "[CoreContracts]"
},
{
"source_id": "ConfigModels",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:ConnectionContracts",
- "target_ref": "[EXT:internal:ConnectionContracts]"
+ "target_id": "ConnectionContracts",
+ "target_ref": "[ConnectionContracts]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region ConfigModels [C:3] [TYPE Module] [SEMANTICS pydantic, model, schedule]\n# @BRIEF Defines the data models for application configuration using Pydantic.\n# @LAYER Core\n# @RELATION IMPLEMENTS -> [EXT:internal:CoreContracts]\n# @RELATION IMPLEMENTS -> [EXT:internal:ConnectionContracts]\n\n\nfrom pydantic import BaseModel, Field, field_validator\n\nfrom ..models.storage import StorageConfig\nfrom ..services.llm_prompt_templates import (\n DEFAULT_LLM_ASSISTANT_SETTINGS,\n DEFAULT_LLM_PROMPTS,\n DEFAULT_LLM_PROVIDER_BINDINGS,\n)\n\n\n# #region Schedule [TYPE DataClass]\n# @BRIEF Represents a backup schedule configuration.\nclass Schedule(BaseModel):\n enabled: bool = False\n cron_expression: str = \"0 0 * * *\" # Default: daily at midnight\n\n\n# #endregion Schedule\n\n\n# #region Environment [TYPE DataClass]\n# @BRIEF Represents a Superset environment configuration.\nclass Environment(BaseModel):\n id: str\n name: str\n url: str\n username: str\n password: str # Will be masked in UI\n stage: str = Field(default=\"DEV\", pattern=\"^(DEV|PREPROD|PROD)$\")\n verify_ssl: bool = True\n timeout: int = 30\n is_default: bool = False\n is_production: bool = False\n backup_schedule: Schedule = Field(default_factory=Schedule)\n\n\n# #endregion Environment\n\n\n# #region LoggingConfig [TYPE DataClass]\n# @BRIEF Defines the configuration for the application's logging system.\nclass LoggingConfig(BaseModel):\n level: str = \"INFO\"\n task_log_level: str = (\n \"INFO\" # Minimum level for task-specific logs (DEBUG, INFO, WARNING, ERROR)\n )\n file_path: str | None = None\n max_bytes: int = 10 * 1024 * 1024\n backup_count: int = 5\n enable_belief_state: bool = True\n\n\n# #endregion LoggingConfig\n\n\n# #region CleanReleaseConfig [TYPE DataClass]\n# @BRIEF Configuration for clean release compliance subsystem.\nclass CleanReleaseConfig(BaseModel):\n active_policy_id: str | None = None\n active_registry_id: str | None = None\n\n\n# #endregion CleanReleaseConfig\n\n\n# #region FeaturesConfig [C:1] [TYPE DataClass]\n# @BRIEF Top-level feature flags that toggle entire project features on/off.\n# @RATIONALE Features are read from environment variables on bootstrap and persisted in DB.\n# DB is source of truth after initial bootstrap; env vars only seed defaults.\nclass FeaturesConfig(BaseModel):\n dataset_review: bool = True\n health_monitor: bool = True\n\n\n# #endregion FeaturesConfig\n\n\n# #region GlobalSettings [TYPE DataClass]\n# @BRIEF Represents global application settings.\nclass GlobalSettings(BaseModel):\n storage: StorageConfig = Field(default_factory=StorageConfig)\n clean_release: CleanReleaseConfig = Field(default_factory=CleanReleaseConfig)\n default_environment_id: str | None = None\n logging: LoggingConfig = Field(default_factory=LoggingConfig)\n features: FeaturesConfig = Field(default_factory=FeaturesConfig)\n connections: list[dict] = []\n llm: dict = Field(\n default_factory=lambda: {\n \"providers\": [],\n \"default_provider\": \"\",\n \"prompts\": dict(DEFAULT_LLM_PROMPTS),\n \"provider_bindings\": dict(DEFAULT_LLM_PROVIDER_BINDINGS),\n **dict(DEFAULT_LLM_ASSISTANT_SETTINGS),\n }\n )\n\n # Application timezone\n app_timezone: str = \"Europe/Moscow\"\n\n @field_validator(\"app_timezone\")\n @classmethod\n def validate_app_timezone(cls, v: str) -> str:\n from zoneinfo import ZoneInfo\n try:\n ZoneInfo(v)\n except (KeyError, TypeError):\n raise ValueError(f\"Invalid IANA timezone: {v}\") from None\n return v\n\n # Task retention settings\n task_retention_days: int = 30\n task_retention_limit: int = 100\n pagination_limit: int = 10\n\n # Migration sync settings\n migration_sync_cron: str = \"0 2 * * *\"\n\n # Dataset Review Feature Flags\n ff_dataset_auto_review: bool = True\n ff_dataset_clarification: bool = True\n ff_dataset_execution: bool = True\n\n\n# #endregion GlobalSettings\n\n\n# #region AppConfig [TYPE DataClass]\n# @BRIEF The root configuration model containing all application settings.\nclass AppConfig(BaseModel):\n environments: list[Environment] = []\n settings: GlobalSettings\n\n\n# #endregion AppConfig\n\n# #endregion ConfigModels\n"
+ "body": "# #region ConfigModels [C:3] [TYPE Module] [SEMANTICS pydantic, model, schedule]\n# @BRIEF Defines the data models for application configuration using Pydantic.\n# @LAYER Core\n# @RELATION IMPLEMENTS -> [CoreContracts]\n# @RELATION IMPLEMENTS -> [ConnectionContracts]\n#\n# #region CoreContracts [C:2] [TYPE Interface]\n# @BRIEF Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.\n# #endregion CoreContracts\n#\n# #region ConnectionContracts [C:2] [TYPE Interface]\n# @BRIEF Contract for database/environment connection configuration models.\n# #endregion ConnectionContracts\n\nfrom pydantic import BaseModel, Field, field_validator\n\nfrom ..models.storage import StorageConfig\nfrom ..services.llm_prompt_templates import (\n DEFAULT_LLM_ASSISTANT_SETTINGS,\n DEFAULT_LLM_PROMPTS,\n DEFAULT_LLM_PROVIDER_BINDINGS,\n)\n\n\n# #region Schedule [TYPE DataClass]\n# @BRIEF Represents a backup schedule configuration.\nclass Schedule(BaseModel):\n enabled: bool = False\n cron_expression: str = \"0 0 * * *\" # Default: daily at midnight\n\n\n# #endregion Schedule\n\n\n# #region Environment [TYPE DataClass]\n# @BRIEF Represents a Superset environment configuration.\nclass Environment(BaseModel):\n id: str\n name: str\n url: str\n username: str\n password: str # Will be masked in UI\n stage: str = Field(default=\"DEV\", pattern=\"^(DEV|PREPROD|PROD)$\")\n verify_ssl: bool = True\n timeout: int = 30\n is_default: bool = False\n is_production: bool = False\n backup_schedule: Schedule = Field(default_factory=Schedule)\n\n\n# #endregion Environment\n\n\n# #region LoggingConfig [TYPE DataClass]\n# @BRIEF Defines the configuration for the application's logging system.\nclass LoggingConfig(BaseModel):\n level: str = \"INFO\"\n task_log_level: str = (\n \"INFO\" # Minimum level for task-specific logs (DEBUG, INFO, WARNING, ERROR)\n )\n file_path: str | None = None\n max_bytes: int = 10 * 1024 * 1024\n backup_count: int = 5\n enable_belief_state: bool = True\n\n\n# #endregion LoggingConfig\n\n\n# #region CleanReleaseConfig [TYPE DataClass]\n# @BRIEF Configuration for clean release compliance subsystem.\nclass CleanReleaseConfig(BaseModel):\n active_policy_id: str | None = None\n active_registry_id: str | None = None\n\n\n# #endregion CleanReleaseConfig\n\n\n# #region FeaturesConfig [C:1] [TYPE DataClass]\n# @BRIEF Top-level feature flags that toggle entire project features on/off.\n# @RATIONALE Features are read from environment variables on bootstrap and persisted in DB.\n# DB is source of truth after initial bootstrap; env vars only seed defaults.\nclass FeaturesConfig(BaseModel):\n dataset_review: bool = True\n health_monitor: bool = True\n\n\n# #endregion FeaturesConfig\n\n\n# #region GlobalSettings [TYPE DataClass]\n# @BRIEF Represents global application settings.\nclass GlobalSettings(BaseModel):\n storage: StorageConfig = Field(default_factory=StorageConfig)\n clean_release: CleanReleaseConfig = Field(default_factory=CleanReleaseConfig)\n default_environment_id: str | None = None\n logging: LoggingConfig = Field(default_factory=LoggingConfig)\n features: FeaturesConfig = Field(default_factory=FeaturesConfig)\n connections: list[dict] = []\n llm: dict = Field(\n default_factory=lambda: {\n \"providers\": [],\n \"default_provider\": \"\",\n \"prompts\": dict(DEFAULT_LLM_PROMPTS),\n \"provider_bindings\": dict(DEFAULT_LLM_PROVIDER_BINDINGS),\n **dict(DEFAULT_LLM_ASSISTANT_SETTINGS),\n }\n )\n\n # Application timezone\n app_timezone: str = \"Europe/Moscow\"\n\n @field_validator(\"app_timezone\")\n @classmethod\n def validate_app_timezone(cls, v: str) -> str:\n from zoneinfo import ZoneInfo\n try:\n ZoneInfo(v)\n except (KeyError, TypeError):\n raise ValueError(f\"Invalid IANA timezone: {v}\") from None\n return v\n\n # Task retention settings\n task_retention_days: int = 30\n task_retention_limit: int = 100\n pagination_limit: int = 10\n\n # Migration sync settings\n migration_sync_cron: str = \"0 2 * * *\"\n\n # Dataset Review Feature Flags\n ff_dataset_auto_review: bool = True\n ff_dataset_clarification: bool = True\n ff_dataset_execution: bool = True\n\n\n# #endregion GlobalSettings\n\n\n# #region AppConfig [TYPE DataClass]\n# @BRIEF The root configuration model containing all application settings.\nclass AppConfig(BaseModel):\n environments: list[Environment] = []\n settings: GlobalSettings\n\n\n# #endregion AppConfig\n\n# #endregion ConfigModels\n"
+ },
+ {
+ "contract_id": "CoreContracts",
+ "contract_type": "Interface",
+ "file_path": "backend/src/core/config_models.py",
+ "start_line": 7,
+ "end_line": 9,
+ "tier": "TIER_1",
+ "complexity": 2,
+ "metadata": {
+ "BRIEF": "Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.",
+ "COMPLEXITY": 2
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "# #region CoreContracts [C:2] [TYPE Interface]\n# @BRIEF Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.\n# #endregion CoreContracts\n"
+ },
+ {
+ "contract_id": "ConnectionContracts",
+ "contract_type": "Interface",
+ "file_path": "backend/src/core/config_models.py",
+ "start_line": 11,
+ "end_line": 13,
+ "tier": "TIER_1",
+ "complexity": 2,
+ "metadata": {
+ "BRIEF": "Contract for database/environment connection configuration models.",
+ "COMPLEXITY": 2
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "# #region ConnectionContracts [C:2] [TYPE Interface]\n# @BRIEF Contract for database/environment connection configuration models.\n# #endregion ConnectionContracts\n"
},
{
"contract_id": "Schedule",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 18,
- "end_line": 25,
+ "start_line": 25,
+ "end_line": 32,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -19999,8 +20091,8 @@
"contract_id": "Environment",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 28,
- "end_line": 44,
+ "start_line": 35,
+ "end_line": 51,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -20016,8 +20108,8 @@
"contract_id": "LoggingConfig",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 47,
- "end_line": 60,
+ "start_line": 54,
+ "end_line": 67,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -20033,8 +20125,8 @@
"contract_id": "CleanReleaseConfig",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 63,
- "end_line": 70,
+ "start_line": 70,
+ "end_line": 77,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -20050,8 +20142,8 @@
"contract_id": "FeaturesConfig",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 73,
- "end_line": 82,
+ "start_line": 80,
+ "end_line": 89,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -20069,8 +20161,8 @@
"contract_id": "GlobalSettings",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 85,
- "end_line": 131,
+ "start_line": 92,
+ "end_line": 138,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -20086,8 +20178,8 @@
"contract_id": "AppConfig",
"contract_type": "DataClass",
"file_path": "backend/src/core/config_models.py",
- "start_line": 134,
- "end_line": 141,
+ "start_line": 141,
+ "end_line": 148,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -20115,7 +20207,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region CotLoggerModule [C:4] [TYPE Module] [SEMANTICS logging, cot, json, trace, structured]\n# @BRIEF Structured JSON logger implementing the molecular CoT (Chain-of-Thought) logging protocol.\n# Uses ContextVar for trace_id and span_id propagation across async contexts.\n# Provides log(), MarkerLogger, seed_trace_id(), push_span(), pop_span().\n# @LAYER Core\n# @RELATION CALLED_BY -> [TraceContextMiddleware]\n# @RELATION CALLED_BY -> [EXT:internal:All C4+ service and route modules]\n# @PRE Python 3.7+ (ContextVar available).\n# @POST JSON log records written to the 'cot' logger at appropriate levels.\n# @SIDE_EFFECT Writes structured JSON to the 'cot' Python logger.\n# @DATA_CONTRACT Log call -> Single-line JSON to logging.StreamHandler/file.\n\nfrom contextvars import ContextVar\nimport logging\nfrom typing import Any\nimport uuid\n\n# #region cot_trace_context [C:1] [TYPE Data] [SEMANTICS contextvar, trace_id, span_id, propagation]\n# @BRIEF ContextVars for trace ID and span ID propagation across async boundaries.\n_trace_id: ContextVar[str] = ContextVar(\"_trace_id\", default=\"\")\n_span_id: ContextVar[str] = ContextVar(\"_span_id\", default=\"\")\n# #endregion cot_trace_context\n\n# #region cot_logger_instance [C:1] [TYPE Data] [SEMANTICS logger, instance]\n# @BRIEF Dedicated Python logger for all CoT (molecular) log output.\ncot_logger = logging.getLogger(\"cot\")\n# #endregion cot_logger_instance\n\n__all__ = [\n \"MarkerLogger\",\n \"get_trace_id\",\n \"log\",\n \"pop_span\",\n \"push_span\",\n \"seed_trace_id\",\n \"set_trace_id\",\n]\n\n# #region seed_trace_id [C:1] [TYPE Function] [SEMANTICS trace_id, uuid, contextvar, set]\n# @BRIEF Generate a new UUID4 trace_id, set it in ContextVar, and return it.\ndef seed_trace_id() -> str:\n \"\"\"Generate a new UUID4 trace ID and store it in the thread-local ContextVar.\n\n Returns:\n str: The newly generated trace ID.\n \"\"\"\n trace_id = str(uuid.uuid4())\n _trace_id.set(trace_id)\n return trace_id\n\n\n# #endregion seed_trace_id\n\n# #region set_trace_id [C:1] [TYPE Function] [SEMANTICS trace_id, contextvar, set, public]\n# @BRIEF Set an explicit trace_id into the ContextVar (e.g. from an incoming header).\ndef set_trace_id(trace_id: str) -> None:\n \"\"\"Set a specific trace_id into the ContextVar.\n\n This is used by TraceContextMiddleware when an ``X-Trace-ID`` header\n is present, enabling cross-service trace chaining.\n\n Args:\n trace_id: The trace ID to set.\n \"\"\"\n _trace_id.set(trace_id)\n\n\n# #endregion set_trace_id\n\n# #region get_trace_id [C:1] [TYPE Function] [SEMANTICS trace_id, contextvar, get, public]\n# @BRIEF Get the current trace_id from ContextVar.\ndef get_trace_id() -> str:\n \"\"\"Get the current trace_id from the thread-local ContextVar.\n\n Returns:\n str: The current trace ID, or empty string if none set.\n \"\"\"\n return _trace_id.get()\n\n\n# #endregion get_trace_id\n\n# #region push_span [C:1] [TYPE Function] [SEMANTICS span_id, contextvar, stack]\n# @BRIEF Set a new span_id in ContextVar and return the previous span_id for later restoration.\ndef push_span(span: str) -> str:\n \"\"\"Push a new span ID onto the context and return the previous span ID.\n\n Args:\n span: The new span identifier (e.g. function or operation name).\n\n Returns:\n str: The previous span ID, suitable for passing to pop_span().\n \"\"\"\n prev = _span_id.get()\n _span_id.set(span)\n return prev\n\n\n# #endregion push_span\n\n# #region pop_span [C:1] [TYPE Function] [SEMANTICS span_id, contextvar, restore]\n# @BRIEF Restore a previous span_id into the ContextVar.\ndef pop_span(prev: str) -> None:\n \"\"\"Restore a previous span ID into the ContextVar.\n\n Args:\n prev: The span ID to restore (previously returned by push_span).\n \"\"\"\n _span_id.set(prev)\n\n\n# #endregion pop_span\n\n# #region cot_log_function [C:2] [TYPE Function] [SEMANTICS log, json, structured, marker]\n# @BRIEF Core structured logging function that emits a single-line JSON record.\ndef log(\n src: str,\n marker: str,\n intent: str,\n payload: dict[str, Any] | None = None,\n error: str | None = None,\n level: str | None = None,\n) -> None:\n \"\"\"Emit a single-line structured JSON log record through the 'cot' logger.\n\n Args:\n src: Qualified function or component name (e.g. 'AuthRepository.get_user').\n marker: Protocol marker — one of 'REASON', 'REFLECT', 'EXPLORE'.\n intent: Short one-line description of the intent or action.\n payload: Optional structured data dict to include in the record.\n error: Required for EXPLORE markers; describes the violated assumption.\n level: Log level override. Auto-inferred from marker if omitted\n (REASON/REFLECT -> INFO, EXPLORE -> WARNING).\n\n Side effects:\n Writes a single-line JSON string to the 'cot' Python logger.\n \"\"\"\n if level is None:\n level = \"WARNING\" if marker == \"EXPLORE\" else \"INFO\"\n\n # Build structured extra data for the LogRecord.\n # CotJsonFormatter will read these attributes to produce the final JSON output,\n # consistent with the main superset_tools_app logger.\n extra: dict[str, Any] = {\n \"marker\": marker,\n \"intent\": intent,\n \"src\": src,\n }\n\n if payload is not None:\n extra[\"payload\"] = payload\n\n if error is not None:\n extra[\"error\"] = error\n\n log_func = {\n \"WARNING\": cot_logger.warning,\n \"ERROR\": cot_logger.error,\n \"DEBUG\": cot_logger.debug,\n }.get(level, cot_logger.info)\n\n log_func(intent, extra=extra)\n\n\n# #endregion cot_log_function\n\n# #region MarkerLogger [C:2] [TYPE Class] [SEMANTICS logger, proxy, marker, syntactic-sugar]\n# @BRIEF Thin proxy class providing .reason(), .reflect(), .explore() convenience methods.\nclass MarkerLogger:\n \"\"\"Thin proxy over the cot_logger.log() function.\n\n Usage::\n\n log = MarkerLogger(\"AuthService\")\n log.reason(\"Validating credentials\", payload={\"user_id\": \"...\"})\n log.reflect(\"Validation complete\", payload={\"result\": \"ok\"})\n log.explore(\"Token expired\", error=\"JWT expired, attempting refresh\")\n\n Each method delegates to :func:`log` with the corresponding marker.\n \"\"\"\n\n # #region MarkerLogger.__init__ [TYPE Function]\n # @BRIEF Store the module/component name used as the 'src' field in all log calls.\n def __init__(self, module_name: str) -> None:\n \"\"\"Initialise the MarkerLogger with a module or component name.\n\n Args:\n module_name: The value used for the 'src' field (e.g. 'AuthService').\n \"\"\"\n self._module_name = module_name\n\n # #endregion MarkerLogger.__init__\n\n # #region MarkerLogger.reason [TYPE Function]\n # @BRIEF Log a REASON marker — strict deduction, core logic.\n def reason(\n self, intent: str, *, payload: dict[str, Any] | None = None\n ) -> None:\n \"\"\"Log a REASON marker (INFO level).\"\"\"\n log(self._module_name, \"REASON\", intent, payload=payload)\n\n # #endregion MarkerLogger.reason\n\n # #region MarkerLogger.reflect [TYPE Function]\n # @BRIEF Log a REFLECT marker — self-check, structural validation.\n def reflect(\n self, intent: str, *, payload: dict[str, Any] | None = None\n ) -> None:\n \"\"\"Log a REFLECT marker (INFO level).\"\"\"\n log(self._module_name, \"REFLECT\", intent, payload=payload)\n\n # #endregion MarkerLogger.reflect\n\n # #region MarkerLogger.explore [TYPE Function]\n # @BRIEF Log an EXPLORE marker — searching, alternatives, violated assumptions.\n def explore(\n self,\n intent: str,\n *,\n payload: dict[str, Any] | None = None,\n error: str | None = None,\n ) -> None:\n \"\"\"Log an EXPLORE marker (WARNING level).\n\n Args:\n intent: Short description of what was being attempted.\n payload: Optional structured data.\n error: Describes the violated assumption or error context.\n \"\"\"\n log(self._module_name, \"EXPLORE\", intent, payload=payload, error=error)\n\n # #endregion MarkerLogger.explore\n\n\n# #endregion MarkerLogger\n# #endregion CotLoggerModule\n"
+ "body": "# #region CotLoggerModule [C:4] [TYPE Module] [SEMANTICS logging, cot, json, trace, structured]\n# @BRIEF Structured JSON logger implementing the molecular CoT (Chain-of-Thought) logging protocol.\n# Uses ContextVar for trace_id and span_id propagation across async contexts.\n# Provides log(), MarkerLogger, seed_trace_id(), push_span(), pop_span().\n# @LAYER Core\n# @RELATION CALLED_BY -> [TraceContextMiddleware]\n# @RELATION CALLED_BY -> [CotLoggerModule]\n# @PRE Python 3.7+ (ContextVar available).\n# @POST JSON log records written to the 'cot' logger at appropriate levels.\n# @SIDE_EFFECT Writes structured JSON to the 'cot' Python logger.\n# @DATA_CONTRACT Log call -> Single-line JSON to logging.StreamHandler/file.\n\nfrom contextvars import ContextVar\nimport logging\nfrom typing import Any\nimport uuid\n\n# #region cot_trace_context [C:1] [TYPE Data] [SEMANTICS contextvar, trace_id, span_id, propagation]\n# @BRIEF ContextVars for trace ID and span ID propagation across async boundaries.\n_trace_id: ContextVar[str] = ContextVar(\"_trace_id\", default=\"\")\n_span_id: ContextVar[str] = ContextVar(\"_span_id\", default=\"\")\n# #endregion cot_trace_context\n\n# #region cot_logger_instance [C:1] [TYPE Data] [SEMANTICS logger, instance]\n# @BRIEF Dedicated Python logger for all CoT (molecular) log output.\ncot_logger = logging.getLogger(\"cot\")\n# #endregion cot_logger_instance\n\n__all__ = [\n \"MarkerLogger\",\n \"get_trace_id\",\n \"log\",\n \"pop_span\",\n \"push_span\",\n \"seed_trace_id\",\n \"set_trace_id\",\n]\n\n# #region seed_trace_id [C:1] [TYPE Function] [SEMANTICS trace_id, uuid, contextvar, set]\n# @BRIEF Generate a new UUID4 trace_id, set it in ContextVar, and return it.\ndef seed_trace_id() -> str:\n \"\"\"Generate a new UUID4 trace ID and store it in the thread-local ContextVar.\n\n Returns:\n str: The newly generated trace ID.\n \"\"\"\n trace_id = str(uuid.uuid4())\n _trace_id.set(trace_id)\n return trace_id\n\n\n# #endregion seed_trace_id\n\n# #region set_trace_id [C:1] [TYPE Function] [SEMANTICS trace_id, contextvar, set, public]\n# @BRIEF Set an explicit trace_id into the ContextVar (e.g. from an incoming header).\ndef set_trace_id(trace_id: str) -> None:\n \"\"\"Set a specific trace_id into the ContextVar.\n\n This is used by TraceContextMiddleware when an ``X-Trace-ID`` header\n is present, enabling cross-service trace chaining.\n\n Args:\n trace_id: The trace ID to set.\n \"\"\"\n _trace_id.set(trace_id)\n\n\n# #endregion set_trace_id\n\n# #region get_trace_id [C:1] [TYPE Function] [SEMANTICS trace_id, contextvar, get, public]\n# @BRIEF Get the current trace_id from ContextVar.\ndef get_trace_id() -> str:\n \"\"\"Get the current trace_id from the thread-local ContextVar.\n\n Returns:\n str: The current trace ID, or empty string if none set.\n \"\"\"\n return _trace_id.get()\n\n\n# #endregion get_trace_id\n\n# #region push_span [C:1] [TYPE Function] [SEMANTICS span_id, contextvar, stack]\n# @BRIEF Set a new span_id in ContextVar and return the previous span_id for later restoration.\ndef push_span(span: str) -> str:\n \"\"\"Push a new span ID onto the context and return the previous span ID.\n\n Args:\n span: The new span identifier (e.g. function or operation name).\n\n Returns:\n str: The previous span ID, suitable for passing to pop_span().\n \"\"\"\n prev = _span_id.get()\n _span_id.set(span)\n return prev\n\n\n# #endregion push_span\n\n# #region pop_span [C:1] [TYPE Function] [SEMANTICS span_id, contextvar, restore]\n# @BRIEF Restore a previous span_id into the ContextVar.\ndef pop_span(prev: str) -> None:\n \"\"\"Restore a previous span ID into the ContextVar.\n\n Args:\n prev: The span ID to restore (previously returned by push_span).\n \"\"\"\n _span_id.set(prev)\n\n\n# #endregion pop_span\n\n# #region cot_log_function [C:2] [TYPE Function] [SEMANTICS log, json, structured, marker]\n# @BRIEF Core structured logging function that emits a single-line JSON record.\ndef log(\n src: str,\n marker: str,\n intent: str,\n payload: dict[str, Any] | None = None,\n error: str | None = None,\n level: str | None = None,\n) -> None:\n \"\"\"Emit a single-line structured JSON log record through the 'cot' logger.\n\n Args:\n src: Qualified function or component name (e.g. 'AuthRepository.get_user').\n marker: Protocol marker — one of 'REASON', 'REFLECT', 'EXPLORE'.\n intent: Short one-line description of the intent or action.\n payload: Optional structured data dict to include in the record.\n error: Required for EXPLORE markers; describes the violated assumption.\n level: Log level override. Auto-inferred from marker if omitted\n (REASON/REFLECT -> INFO, EXPLORE -> WARNING).\n\n Side effects:\n Writes a single-line JSON string to the 'cot' Python logger.\n \"\"\"\n if level is None:\n level = \"WARNING\" if marker == \"EXPLORE\" else \"INFO\"\n\n # Build structured extra data for the LogRecord.\n # CotJsonFormatter will read these attributes to produce the final JSON output,\n # consistent with the main superset_tools_app logger.\n extra: dict[str, Any] = {\n \"marker\": marker,\n \"intent\": intent,\n \"src\": src,\n }\n\n if payload is not None:\n extra[\"payload\"] = payload\n\n if error is not None:\n extra[\"error\"] = error\n\n log_func = {\n \"WARNING\": cot_logger.warning,\n \"ERROR\": cot_logger.error,\n \"DEBUG\": cot_logger.debug,\n }.get(level, cot_logger.info)\n\n log_func(intent, extra=extra)\n\n\n# #endregion cot_log_function\n\n# #region MarkerLogger [C:2] [TYPE Class] [SEMANTICS logger, proxy, marker, syntactic-sugar]\n# @BRIEF Thin proxy class providing .reason(), .reflect(), .explore() convenience methods.\nclass MarkerLogger:\n \"\"\"Thin proxy over the cot_logger.log() function.\n\n Usage::\n\n log = MarkerLogger(\"AuthService\")\n log.reason(\"Validating credentials\", payload={\"user_id\": \"...\"})\n log.reflect(\"Validation complete\", payload={\"result\": \"ok\"})\n log.explore(\"Token expired\", error=\"JWT expired, attempting refresh\")\n\n Each method delegates to :func:`log` with the corresponding marker.\n \"\"\"\n\n # #region MarkerLogger.__init__ [TYPE Function]\n # @BRIEF Store the module/component name used as the 'src' field in all log calls.\n def __init__(self, module_name: str) -> None:\n \"\"\"Initialise the MarkerLogger with a module or component name.\n\n Args:\n module_name: The value used for the 'src' field (e.g. 'AuthService').\n \"\"\"\n self._module_name = module_name\n\n # #endregion MarkerLogger.__init__\n\n # #region MarkerLogger.reason [TYPE Function]\n # @BRIEF Log a REASON marker — strict deduction, core logic.\n def reason(\n self, intent: str, *, payload: dict[str, Any] | None = None\n ) -> None:\n \"\"\"Log a REASON marker (INFO level).\"\"\"\n log(self._module_name, \"REASON\", intent, payload=payload)\n\n # #endregion MarkerLogger.reason\n\n # #region MarkerLogger.reflect [TYPE Function]\n # @BRIEF Log a REFLECT marker — self-check, structural validation.\n def reflect(\n self, intent: str, *, payload: dict[str, Any] | None = None\n ) -> None:\n \"\"\"Log a REFLECT marker (INFO level).\"\"\"\n log(self._module_name, \"REFLECT\", intent, payload=payload)\n\n # #endregion MarkerLogger.reflect\n\n # #region MarkerLogger.explore [TYPE Function]\n # @BRIEF Log an EXPLORE marker — searching, alternatives, violated assumptions.\n def explore(\n self,\n intent: str,\n *,\n payload: dict[str, Any] | None = None,\n error: str | None = None,\n ) -> None:\n \"\"\"Log an EXPLORE marker (WARNING level).\n\n Args:\n intent: Short description of what was being attempted.\n payload: Optional structured data.\n error: Describes the violated assumption or error context.\n \"\"\"\n log(self._module_name, \"EXPLORE\", intent, payload=payload, error=error)\n\n # #endregion MarkerLogger.explore\n\n\n# #endregion MarkerLogger\n# #endregion CotLoggerModule\n"
},
{
"contract_id": "cot_trace_context",
@@ -21007,8 +21099,8 @@
{
"source_id": "LoggerModule",
"relation_type": "CALLED_BY",
- "target_id": "EXT:internal:All application modules",
- "target_ref": "[EXT:internal:All application modules]"
+ "target_id": "LoggerModule",
+ "target_ref": "[LoggerModule]"
},
{
"source_id": "LoggerModule",
@@ -21026,7 +21118,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region LoggerModule [C:5] [TYPE Module] [SEMANTICS pydantic, logging, json, formatter, structured]\n# @BRIEF Application logging system with CotJsonFormatter producing molecular CoT JSON output.\n# @LAYER Core\n# @RELATION CALLED_BY -> [EXT:internal:All application modules]\n# @RELATION DEPENDS_ON -> [CotLoggerModule]\n# @RELATION DEPENDS_ON -> [WebSocketLogHandler]\n# @PRE Python 3.7+ with cot_logger ContextVars available.\n# @POST All log output is single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.\n# @SIDE_EFFECT Configures global logger handlers and formatters; seeds global _enable_belief_state and _task_log_level; writes JSON to console/files.\n# @RATIONALE Replaced BeliefFormatter text-based [Entry]/[Exit]/[Action] logging with CotJsonFormatter JSON output. Old format was not machine-parseable and mixed presentation with intent. CotJsonFormatter produces structured JSON consistent with cot_logger.py MarkerLogger protocol.\n# @REJECTED Keeping both formatters side-by-side was rejected (two inconsistent output formats would confuse log consumers).\n# @DATA_CONTRACT All log records conform to molecular CoT JSON schema: {ts, level, trace_id, src, marker, intent, span_id?, payload?, error?}\n# @INVARIANT CotJsonFormatter.format() always returns valid single-line JSON string.\nfrom contextlib import contextmanager\nfrom datetime import UTC, datetime\nimport json\nimport logging\nfrom logging.handlers import RotatingFileHandler\nimport threading\nimport types\nfrom typing import Any\n\nfrom pydantic import BaseModel, Field\n\nfrom .cot_logger import _span_id, _trace_id, log as cot_log\nfrom .ws_log_handler import WebSocketLogHandler\n\n# Thread-local storage for belief state\n_belief_state = threading.local()\n\n# Global flag for belief state logging\n_enable_belief_state = True\n\n# Global task log level filter\n_task_log_level = \"INFO\"\n\n\n# #region CotJsonFormatter [C:3] [TYPE Class] [SEMANTICS logging,formatter,json,cot,protocol]\n# @BRIEF JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.\n# @RELATION IMPLEMENTS -> [EXT:internal:CotJsonFormat]\nclass CotJsonFormatter(logging.Formatter):\n \"\"\"JSON formatter implementing the molecular CoT logging protocol.\n\n Reads structured data from the LogRecord's extra attributes (marker, intent, payload,\n error, src) set via the ``extra`` kwarg. Falls back to plain message wrapping when no\n structured extra is present.\n\n Output format (single-line JSON)::\n\n {\n \"ts\": \"2026-05-12T10:30:00.123\",\n \"level\": \"INFO\",\n \"trace_id\": \"uuid-or-no-trace\",\n \"src\": \"module.name\",\n \"marker\": \"REASON|REFLECT|EXPLORE\",\n \"intent\": \"human-readable intent\",\n \"span_id\": \"optional-span\",\n \"payload\": { ... }, # optional\n \"error\": \"...\" # optional\n }\n \"\"\"\n\n # #region CotJsonFormatter.format [C:2] [TYPE Function] [SEMANTICS format,json,record]\n # @BRIEF Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.\n # @INVARIANT Output is always valid single-line JSON.\n def format(self, record):\n # Try to extract structured data from extra kwargs on the record\n marker = getattr(record, 'marker', None)\n intent = getattr(record, 'intent', None)\n payload = getattr(record, 'payload', None)\n error = getattr(record, 'error', None)\n src = getattr(record, 'src', None) or record.name\n\n # Default marker for plain messages\n if not marker:\n marker = \"REASON\"\n if not intent:\n intent = record.getMessage()\n\n log_obj = {\n \"ts\": datetime.now(UTC).isoformat(timespec=\"milliseconds\"),\n \"level\": record.levelname,\n \"trace_id\": _trace_id.get() or \"no-trace\",\n \"src\": src,\n \"marker\": marker,\n \"intent\": intent,\n }\n\n span_id = _span_id.get()\n if span_id:\n log_obj[\"span_id\"] = span_id\n if payload:\n log_obj[\"payload\"] = payload\n if error:\n log_obj[\"error\"] = error\n\n return json.dumps(log_obj, ensure_ascii=False, default=str)\n # #endregion CotJsonFormatter.format\n# #endregion CotJsonFormatter\n\n\n# #region BeliefFormatter [C:2] [TYPE Class] [SEMANTICS logging,formatter,legacy,text]\n# @BRIEF Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.\n# @RATIONALE Kept for backward compatibility; may be used by external consumers of this module.\nclass BeliefFormatter(logging.Formatter):\n \"\"\"Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.\"\"\"\n def format(self, record):\n anchor_id = getattr(_belief_state, 'anchor_id', None)\n if anchor_id:\n msg = str(record.msg)\n markers = (\"[EXPLORE]\", \"[REASON]\", \"[REFLECT]\")\n\n if msg.startswith(f\"[{anchor_id}]\"):\n pass\n elif any(msg.startswith(m) for m in markers):\n record.msg = f\"[{anchor_id}]{msg}\"\n else:\n record.msg = f\"[{anchor_id}][REASON] {msg}\"\n\n return super().format(record)\n# #endregion BeliefFormatter\n\n\n# #region LogEntry [C:1] [TYPE Class] [SEMANTICS log,entry,record,pydantic]\n# @BRIEF A Pydantic model representing a single, structured log entry.\nclass LogEntry(BaseModel):\n timestamp: datetime = Field(default_factory=datetime.utcnow)\n level: str\n message: str\n context: dict[str, Any] | None = None\n# #endregion LogEntry\n\n\n# #region belief_scope [C:3] [TYPE Function] [SEMANTICS logging,context,belief_state,cot]\n# @BRIEF Context manager for Molecular CoT structured logging. Uses cot_logger.log() for JSON output.\n# @PRE anchor_id must be provided.\n# @POST Thread-local belief state is updated; REASON/REFLECT/EXPLORE markers emitted via structured JSON logger.\n@contextmanager\ndef belief_scope(anchor_id: str, message: str = \"\"):\n old_anchor = getattr(_belief_state, 'anchor_id', None)\n _belief_state.anchor_id = anchor_id\n\n try:\n # Log entry as REASON (gated by _enable_belief_state)\n if _enable_belief_state:\n intent_msg = message or f\"Entering {anchor_id}\"\n cot_log(anchor_id, \"REASON\", intent_msg, level=\"DEBUG\")\n yield\n # Log success as REFLECT (always logged)\n cot_log(anchor_id, \"REFLECT\", \"Coherence OK\", level=\"DEBUG\")\n except Exception as e:\n # Log exception as EXPLORE (always logged)\n cot_log(anchor_id, \"EXPLORE\", \"Assumption violated\", error=str(e), level=\"WARNING\")\n raise\n finally:\n _belief_state.anchor_id = old_anchor\n# #endregion belief_scope\n\n\n# #region configure_logger [C:4] [TYPE Function] [SEMANTICS logging,configuration,initialization,cot]\n# @BRIEF Configures the main logger and the CoT logger with CotJsonFormatter, file handlers, and global flags.\n# @RELATION CALLS -> [CotJsonFormatter]\n# @RELATION CALLS -> [CotLoggerModule]\n# @PRE config is a valid LoggingConfig instance.\n# @POST Logger levels, handlers, formatters, belief state flag, and task log level are updated.\n# @SIDE_EFFECT Mutates global _enable_belief_state, _task_log_level; adds/removes handlers on both logger and cot_logger; creates file directories.\ndef configure_logger(config):\n global _enable_belief_state, _task_log_level\n _enable_belief_state = config.enable_belief_state\n _task_log_level = config.task_log_level.upper()\n\n # Set logger level\n level = getattr(logging, config.level.upper(), logging.INFO)\n logger.setLevel(level)\n\n # Remove existing file handlers\n handlers_to_remove = [h for h in logger.handlers if isinstance(h, RotatingFileHandler)]\n for h in handlers_to_remove:\n logger.removeHandler(h)\n h.close()\n\n # Add file handler if file_path is set\n if config.file_path:\n from pathlib import Path\n log_file = Path(config.file_path)\n log_file.parent.mkdir(parents=True, exist_ok=True)\n\n file_handler = RotatingFileHandler(\n config.file_path,\n maxBytes=config.max_bytes,\n backupCount=config.backup_count\n )\n file_handler.setFormatter(CotJsonFormatter())\n logger.addHandler(file_handler)\n\n # Update existing handlers' formatters to CotJsonFormatter\n for handler in logger.handlers:\n if not isinstance(handler, RotatingFileHandler):\n handler.setFormatter(CotJsonFormatter())\n\n # Configure the 'cot' logger for consistent JSON output\n from .cot_logger import cot_logger\n cot_logger.setLevel(level)\n if not cot_logger.handlers:\n cot_handler = logging.StreamHandler()\n cot_handler.setFormatter(CotJsonFormatter())\n cot_logger.addHandler(cot_handler)\n# #endregion configure_logger\n\n\n# #region get_task_log_level [C:1] [TYPE Function] [SEMANTICS logging,configuration,getter]\n# @BRIEF Returns the current task log level filter.\ndef get_task_log_level() -> str:\n return _task_log_level\n# #endregion get_task_log_level\n\n\n# #region should_log_task_level [C:1] [TYPE Function] [SEMANTICS logging,filter,level]\n# @BRIEF Checks if a log level should be recorded based on task_log_level setting.\ndef should_log_task_level(level: str) -> bool:\n level_order = {\"DEBUG\": 0, \"INFO\": 1, \"WARNING\": 2, \"ERROR\": 3}\n current_level = _task_log_level.upper()\n check_level = level.upper()\n\n current_order = level_order.get(current_level, 1)\n check_order = level_order.get(check_level, 1)\n\n return check_order >= current_order\n# #endregion should_log_task_level\n\n\n# #region Logger [C:2] [TYPE Global] [SEMANTICS logger,global,instance]\n# @BRIEF The global application logger instance configured with CotJsonFormatter, console handler, and WebSocketLogHandler.\nlogger = logging.getLogger(\"superset_tools_app\")\n\n# #region believed [C:2] [TYPE Function] [SEMANTICS decorator,belief,scope]\n# @BRIEF A decorator that wraps a function in a belief scope.\ndef believed(anchor_id: str):\n def decorator(func):\n def wrapper(*args, **kwargs):\n with belief_scope(anchor_id):\n return func(*args, **kwargs)\n return wrapper\n return decorator\n# #endregion believed\nlogger.setLevel(logging.INFO)\n\n# Create CotJsonFormatter\n_formatter = CotJsonFormatter()\n\n# Add console handler\nconsole_handler = logging.StreamHandler()\nconsole_handler.setFormatter(_formatter)\nlogger.addHandler(console_handler)\n\n# Add WebSocket log handler\nwebsocket_log_handler = WebSocketLogHandler()\nwebsocket_log_handler.setFormatter(_formatter)\nlogger.addHandler(websocket_log_handler)\n\n# Example usage:\n# logger.info(\"Application started\", extra={\"context_key\": \"context_value\"})\n# logger.error(\"An error occurred\", exc_info=True)\n\n\n# #region explore [C:2] [TYPE Function] [SEMANTICS log,explore,marker,warning]\n# @BRIEF Logs an EXPLORE marker (WARNING level) with structured extra data for CotJsonFormatter.\ndef explore(self, msg, *args, **kwargs):\n \"\"\"Log an EXPLORE marker — searching, alternatives, violated assumptions.\n\n Passes structured ``extra`` data so CotJsonFormatter produces proper JSON.\n \"\"\"\n user_extra = kwargs.pop('extra', {})\n error_val = kwargs.pop('error', None)\n extra = {'marker': 'EXPLORE', 'intent': msg}\n if error_val is not None:\n extra['error'] = error_val\n extra.update(user_extra)\n self.warning(msg, *args, extra=extra, **kwargs)\n# #endregion explore\n\n\n# #region reason [C:2] [TYPE Function] [SEMANTICS log,reason,marker,debug]\n# @BRIEF Logs a REASON marker (DEBUG level) with structured extra data for CotJsonFormatter.\ndef reason(self, msg, *args, **kwargs):\n \"\"\"Log a REASON marker — strict deduction, core logic.\n\n Passes structured ``extra`` data so CotJsonFormatter produces proper JSON.\n \"\"\"\n user_extra = kwargs.pop('extra', {})\n error_val = kwargs.pop('error', None)\n extra = {'marker': 'REASON', 'intent': msg}\n if error_val is not None:\n extra['error'] = error_val\n extra.update(user_extra)\n self.debug(msg, *args, extra=extra, **kwargs)\n# #endregion reason\n\n\n# #region reflect [C:2] [TYPE Function] [SEMANTICS log,reflect,marker,debug]\n# @BRIEF Logs a REFLECT marker (DEBUG level) with structured extra data for CotJsonFormatter.\ndef reflect(self, msg, *args, **kwargs):\n \"\"\"Log a REFLECT marker — self-check, structural validation.\n\n Passes structured ``extra`` data so CotJsonFormatter produces proper JSON.\n \"\"\"\n user_extra = kwargs.pop('extra', {})\n error_val = kwargs.pop('error', None)\n extra = {'marker': 'REFLECT', 'intent': msg}\n if error_val is not None:\n extra['error'] = error_val\n extra.update(user_extra)\n self.debug(msg, *args, extra=extra, **kwargs)\n# #endregion reflect\n\nlogger.explore = types.MethodType(explore, logger)\nlogger.reason = types.MethodType(reason, logger)\nlogger.reflect = types.MethodType(reflect, logger)\n\n# #endregion Logger\n# #endregion LoggerModule\n"
+ "body": "# #region LoggerModule [C:5] [TYPE Module] [SEMANTICS pydantic, logging, json, formatter, structured]\n# @BRIEF Application logging system with CotJsonFormatter producing molecular CoT JSON output.\n# @LAYER Core\n# @RELATION CALLED_BY -> [LoggerModule]\n# @RELATION DEPENDS_ON -> [CotLoggerModule]\n# @RELATION DEPENDS_ON -> [WebSocketLogHandler]\n# @PRE Python 3.7+ with cot_logger ContextVars available.\n# @POST All log output is single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.\n# @SIDE_EFFECT Configures global logger handlers and formatters; seeds global _enable_belief_state and _task_log_level; writes JSON to console/files.\n# @RATIONALE Replaced BeliefFormatter text-based [Entry]/[Exit]/[Action] logging with CotJsonFormatter JSON output. Old format was not machine-parseable and mixed presentation with intent. CotJsonFormatter produces structured JSON consistent with cot_logger.py MarkerLogger protocol.\n# @REJECTED Keeping both formatters side-by-side was rejected (two inconsistent output formats would confuse log consumers).\n# @DATA_CONTRACT All log records conform to molecular CoT JSON schema: {ts, level, trace_id, src, marker, intent, span_id?, payload?, error?}\n# @INVARIANT CotJsonFormatter.format() always returns valid single-line JSON string.\nfrom contextlib import contextmanager\nfrom datetime import UTC, datetime\nimport json\nimport logging\nfrom logging.handlers import RotatingFileHandler\nimport threading\nimport types\nfrom typing import Any\n\nfrom pydantic import BaseModel, Field\n\nfrom .cot_logger import _span_id, _trace_id, log as cot_log\nfrom .ws_log_handler import WebSocketLogHandler\n\n# Thread-local storage for belief state\n_belief_state = threading.local()\n\n# Global flag for belief state logging\n_enable_belief_state = True\n\n# Global task log level filter\n_task_log_level = \"INFO\"\n\n\n# #region CotJsonFormatter [C:3] [TYPE Class] [SEMANTICS logging,formatter,json,cot,protocol]\n# @BRIEF JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.\n# @RELATION IMPLEMENTS -> [CotJsonFormatter]\nclass CotJsonFormatter(logging.Formatter):\n \"\"\"JSON formatter implementing the molecular CoT logging protocol.\n\n Reads structured data from the LogRecord's extra attributes (marker, intent, payload,\n error, src) set via the ``extra`` kwarg. Falls back to plain message wrapping when no\n structured extra is present.\n\n Output format (single-line JSON)::\n\n {\n \"ts\": \"2026-05-12T10:30:00.123\",\n \"level\": \"INFO\",\n \"trace_id\": \"uuid-or-no-trace\",\n \"src\": \"module.name\",\n \"marker\": \"REASON|REFLECT|EXPLORE\",\n \"intent\": \"human-readable intent\",\n \"span_id\": \"optional-span\",\n \"payload\": { ... }, # optional\n \"error\": \"...\" # optional\n }\n \"\"\"\n\n # #region CotJsonFormatter.format [C:2] [TYPE Function] [SEMANTICS format,json,record]\n # @BRIEF Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.\n # @INVARIANT Output is always valid single-line JSON.\n def format(self, record):\n # Try to extract structured data from extra kwargs on the record\n marker = getattr(record, 'marker', None)\n intent = getattr(record, 'intent', None)\n payload = getattr(record, 'payload', None)\n error = getattr(record, 'error', None)\n src = getattr(record, 'src', None) or record.name\n\n # Default marker for plain messages\n if not marker:\n marker = \"REASON\"\n if not intent:\n intent = record.getMessage()\n\n log_obj = {\n \"ts\": datetime.now(UTC).isoformat(timespec=\"milliseconds\"),\n \"level\": record.levelname,\n \"trace_id\": _trace_id.get() or \"no-trace\",\n \"src\": src,\n \"marker\": marker,\n \"intent\": intent,\n }\n\n span_id = _span_id.get()\n if span_id:\n log_obj[\"span_id\"] = span_id\n if payload:\n log_obj[\"payload\"] = payload\n if error:\n log_obj[\"error\"] = error\n\n return json.dumps(log_obj, ensure_ascii=False, default=str)\n # #endregion CotJsonFormatter.format\n# #endregion CotJsonFormatter\n\n\n# #region BeliefFormatter [C:2] [TYPE Class] [SEMANTICS logging,formatter,legacy,text]\n# @BRIEF Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.\n# @RATIONALE Kept for backward compatibility; may be used by external consumers of this module.\nclass BeliefFormatter(logging.Formatter):\n \"\"\"Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.\"\"\"\n def format(self, record):\n anchor_id = getattr(_belief_state, 'anchor_id', None)\n if anchor_id:\n msg = str(record.msg)\n markers = (\"[EXPLORE]\", \"[REASON]\", \"[REFLECT]\")\n\n if msg.startswith(f\"[{anchor_id}]\"):\n pass\n elif any(msg.startswith(m) for m in markers):\n record.msg = f\"[{anchor_id}]{msg}\"\n else:\n record.msg = f\"[{anchor_id}][REASON] {msg}\"\n\n return super().format(record)\n# #endregion BeliefFormatter\n\n\n# #region LogEntry [C:1] [TYPE Class] [SEMANTICS log,entry,record,pydantic]\n# @BRIEF A Pydantic model representing a single, structured log entry.\nclass LogEntry(BaseModel):\n timestamp: datetime = Field(default_factory=datetime.utcnow)\n level: str\n message: str\n context: dict[str, Any] | None = None\n# #endregion LogEntry\n\n\n# #region belief_scope [C:3] [TYPE Function] [SEMANTICS logging,context,belief_state,cot]\n# @BRIEF Context manager for Molecular CoT structured logging. Uses cot_logger.log() for JSON output.\n# @PRE anchor_id must be provided.\n# @POST Thread-local belief state is updated; REASON/REFLECT/EXPLORE markers emitted via structured JSON logger.\n@contextmanager\ndef belief_scope(anchor_id: str, message: str = \"\"):\n old_anchor = getattr(_belief_state, 'anchor_id', None)\n _belief_state.anchor_id = anchor_id\n\n try:\n # Log entry as REASON (gated by _enable_belief_state)\n if _enable_belief_state:\n intent_msg = message or f\"Entering {anchor_id}\"\n cot_log(anchor_id, \"REASON\", intent_msg, level=\"DEBUG\")\n yield\n # Log success as REFLECT (always logged)\n cot_log(anchor_id, \"REFLECT\", \"Coherence OK\", level=\"DEBUG\")\n except Exception as e:\n # Log exception as EXPLORE (always logged)\n cot_log(anchor_id, \"EXPLORE\", \"Assumption violated\", error=str(e), level=\"WARNING\")\n raise\n finally:\n _belief_state.anchor_id = old_anchor\n# #endregion belief_scope\n\n\n# #region configure_logger [C:4] [TYPE Function] [SEMANTICS logging,configuration,initialization,cot]\n# @BRIEF Configures the main logger and the CoT logger with CotJsonFormatter, file handlers, and global flags.\n# @RELATION CALLS -> [CotJsonFormatter]\n# @RELATION CALLS -> [CotLoggerModule]\n# @PRE config is a valid LoggingConfig instance.\n# @POST Logger levels, handlers, formatters, belief state flag, and task log level are updated.\n# @SIDE_EFFECT Mutates global _enable_belief_state, _task_log_level; adds/removes handlers on both logger and cot_logger; creates file directories.\ndef configure_logger(config):\n global _enable_belief_state, _task_log_level\n _enable_belief_state = config.enable_belief_state\n _task_log_level = config.task_log_level.upper()\n\n # Set logger level\n level = getattr(logging, config.level.upper(), logging.INFO)\n logger.setLevel(level)\n\n # Remove existing file handlers\n handlers_to_remove = [h for h in logger.handlers if isinstance(h, RotatingFileHandler)]\n for h in handlers_to_remove:\n logger.removeHandler(h)\n h.close()\n\n # Add file handler if file_path is set\n if config.file_path:\n from pathlib import Path\n log_file = Path(config.file_path)\n log_file.parent.mkdir(parents=True, exist_ok=True)\n\n file_handler = RotatingFileHandler(\n config.file_path,\n maxBytes=config.max_bytes,\n backupCount=config.backup_count\n )\n file_handler.setFormatter(CotJsonFormatter())\n logger.addHandler(file_handler)\n\n # Update existing handlers' formatters to CotJsonFormatter\n for handler in logger.handlers:\n if not isinstance(handler, RotatingFileHandler):\n handler.setFormatter(CotJsonFormatter())\n\n # Configure the 'cot' logger for consistent JSON output\n from .cot_logger import cot_logger\n cot_logger.setLevel(level)\n if not cot_logger.handlers:\n cot_handler = logging.StreamHandler()\n cot_handler.setFormatter(CotJsonFormatter())\n cot_logger.addHandler(cot_handler)\n# #endregion configure_logger\n\n\n# #region get_task_log_level [C:1] [TYPE Function] [SEMANTICS logging,configuration,getter]\n# @BRIEF Returns the current task log level filter.\ndef get_task_log_level() -> str:\n return _task_log_level\n# #endregion get_task_log_level\n\n\n# #region should_log_task_level [C:1] [TYPE Function] [SEMANTICS logging,filter,level]\n# @BRIEF Checks if a log level should be recorded based on task_log_level setting.\ndef should_log_task_level(level: str) -> bool:\n level_order = {\"DEBUG\": 0, \"INFO\": 1, \"WARNING\": 2, \"ERROR\": 3}\n current_level = _task_log_level.upper()\n check_level = level.upper()\n\n current_order = level_order.get(current_level, 1)\n check_order = level_order.get(check_level, 1)\n\n return check_order >= current_order\n# #endregion should_log_task_level\n\n\n# #region Logger [C:2] [TYPE Global] [SEMANTICS logger,global,instance]\n# @BRIEF The global application logger instance configured with CotJsonFormatter, console handler, and WebSocketLogHandler.\nlogger = logging.getLogger(\"superset_tools_app\")\n\n# #region believed [C:2] [TYPE Function] [SEMANTICS decorator,belief,scope]\n# @BRIEF A decorator that wraps a function in a belief scope.\ndef believed(anchor_id: str):\n def decorator(func):\n def wrapper(*args, **kwargs):\n with belief_scope(anchor_id):\n return func(*args, **kwargs)\n return wrapper\n return decorator\n# #endregion believed\nlogger.setLevel(logging.INFO)\n\n# Create CotJsonFormatter\n_formatter = CotJsonFormatter()\n\n# Add console handler\nconsole_handler = logging.StreamHandler()\nconsole_handler.setFormatter(_formatter)\nlogger.addHandler(console_handler)\n\n# Add WebSocket log handler\nwebsocket_log_handler = WebSocketLogHandler()\nwebsocket_log_handler.setFormatter(_formatter)\nlogger.addHandler(websocket_log_handler)\n\n# Example usage:\n# logger.info(\"Application started\", extra={\"context_key\": \"context_value\"})\n# logger.error(\"An error occurred\", exc_info=True)\n\n\n# #region explore [C:2] [TYPE Function] [SEMANTICS log,explore,marker,warning]\n# @BRIEF Logs an EXPLORE marker (WARNING level) with structured extra data for CotJsonFormatter.\ndef explore(self, msg, *args, **kwargs):\n \"\"\"Log an EXPLORE marker — searching, alternatives, violated assumptions.\n\n Passes structured ``extra`` data so CotJsonFormatter produces proper JSON.\n \"\"\"\n user_extra = kwargs.pop('extra', {})\n error_val = kwargs.pop('error', None)\n extra = {'marker': 'EXPLORE', 'intent': msg}\n if error_val is not None:\n extra['error'] = error_val\n extra.update(user_extra)\n self.warning(msg, *args, extra=extra, **kwargs)\n# #endregion explore\n\n\n# #region reason [C:2] [TYPE Function] [SEMANTICS log,reason,marker,debug]\n# @BRIEF Logs a REASON marker (DEBUG level) with structured extra data for CotJsonFormatter.\ndef reason(self, msg, *args, **kwargs):\n \"\"\"Log a REASON marker — strict deduction, core logic.\n\n Passes structured ``extra`` data so CotJsonFormatter produces proper JSON.\n \"\"\"\n user_extra = kwargs.pop('extra', {})\n error_val = kwargs.pop('error', None)\n extra = {'marker': 'REASON', 'intent': msg}\n if error_val is not None:\n extra['error'] = error_val\n extra.update(user_extra)\n self.debug(msg, *args, extra=extra, **kwargs)\n# #endregion reason\n\n\n# #region reflect [C:2] [TYPE Function] [SEMANTICS log,reflect,marker,debug]\n# @BRIEF Logs a REFLECT marker (DEBUG level) with structured extra data for CotJsonFormatter.\ndef reflect(self, msg, *args, **kwargs):\n \"\"\"Log a REFLECT marker — self-check, structural validation.\n\n Passes structured ``extra`` data so CotJsonFormatter produces proper JSON.\n \"\"\"\n user_extra = kwargs.pop('extra', {})\n error_val = kwargs.pop('error', None)\n extra = {'marker': 'REFLECT', 'intent': msg}\n if error_val is not None:\n extra['error'] = error_val\n extra.update(user_extra)\n self.debug(msg, *args, extra=extra, **kwargs)\n# #endregion reflect\n\nlogger.explore = types.MethodType(explore, logger)\nlogger.reason = types.MethodType(reason, logger)\nlogger.reflect = types.MethodType(reflect, logger)\n\n# #endregion Logger\n# #endregion LoggerModule\n"
},
{
"contract_id": "CotJsonFormatter",
@@ -21044,14 +21136,14 @@
{
"source_id": "CotJsonFormatter",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:CotJsonFormat",
- "target_ref": "[EXT:internal:CotJsonFormat]"
+ "target_id": "CotJsonFormatter",
+ "target_ref": "[CotJsonFormatter]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region CotJsonFormatter [C:3] [TYPE Class] [SEMANTICS logging,formatter,json,cot,protocol]\n# @BRIEF JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.\n# @RELATION IMPLEMENTS -> [EXT:internal:CotJsonFormat]\nclass CotJsonFormatter(logging.Formatter):\n \"\"\"JSON formatter implementing the molecular CoT logging protocol.\n\n Reads structured data from the LogRecord's extra attributes (marker, intent, payload,\n error, src) set via the ``extra`` kwarg. Falls back to plain message wrapping when no\n structured extra is present.\n\n Output format (single-line JSON)::\n\n {\n \"ts\": \"2026-05-12T10:30:00.123\",\n \"level\": \"INFO\",\n \"trace_id\": \"uuid-or-no-trace\",\n \"src\": \"module.name\",\n \"marker\": \"REASON|REFLECT|EXPLORE\",\n \"intent\": \"human-readable intent\",\n \"span_id\": \"optional-span\",\n \"payload\": { ... }, # optional\n \"error\": \"...\" # optional\n }\n \"\"\"\n\n # #region CotJsonFormatter.format [C:2] [TYPE Function] [SEMANTICS format,json,record]\n # @BRIEF Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.\n # @INVARIANT Output is always valid single-line JSON.\n def format(self, record):\n # Try to extract structured data from extra kwargs on the record\n marker = getattr(record, 'marker', None)\n intent = getattr(record, 'intent', None)\n payload = getattr(record, 'payload', None)\n error = getattr(record, 'error', None)\n src = getattr(record, 'src', None) or record.name\n\n # Default marker for plain messages\n if not marker:\n marker = \"REASON\"\n if not intent:\n intent = record.getMessage()\n\n log_obj = {\n \"ts\": datetime.now(UTC).isoformat(timespec=\"milliseconds\"),\n \"level\": record.levelname,\n \"trace_id\": _trace_id.get() or \"no-trace\",\n \"src\": src,\n \"marker\": marker,\n \"intent\": intent,\n }\n\n span_id = _span_id.get()\n if span_id:\n log_obj[\"span_id\"] = span_id\n if payload:\n log_obj[\"payload\"] = payload\n if error:\n log_obj[\"error\"] = error\n\n return json.dumps(log_obj, ensure_ascii=False, default=str)\n # #endregion CotJsonFormatter.format\n# #endregion CotJsonFormatter\n"
+ "body": "# #region CotJsonFormatter [C:3] [TYPE Class] [SEMANTICS logging,formatter,json,cot,protocol]\n# @BRIEF JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.\n# @RELATION IMPLEMENTS -> [CotJsonFormatter]\nclass CotJsonFormatter(logging.Formatter):\n \"\"\"JSON formatter implementing the molecular CoT logging protocol.\n\n Reads structured data from the LogRecord's extra attributes (marker, intent, payload,\n error, src) set via the ``extra`` kwarg. Falls back to plain message wrapping when no\n structured extra is present.\n\n Output format (single-line JSON)::\n\n {\n \"ts\": \"2026-05-12T10:30:00.123\",\n \"level\": \"INFO\",\n \"trace_id\": \"uuid-or-no-trace\",\n \"src\": \"module.name\",\n \"marker\": \"REASON|REFLECT|EXPLORE\",\n \"intent\": \"human-readable intent\",\n \"span_id\": \"optional-span\",\n \"payload\": { ... }, # optional\n \"error\": \"...\" # optional\n }\n \"\"\"\n\n # #region CotJsonFormatter.format [C:2] [TYPE Function] [SEMANTICS format,json,record]\n # @BRIEF Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.\n # @INVARIANT Output is always valid single-line JSON.\n def format(self, record):\n # Try to extract structured data from extra kwargs on the record\n marker = getattr(record, 'marker', None)\n intent = getattr(record, 'intent', None)\n payload = getattr(record, 'payload', None)\n error = getattr(record, 'error', None)\n src = getattr(record, 'src', None) or record.name\n\n # Default marker for plain messages\n if not marker:\n marker = \"REASON\"\n if not intent:\n intent = record.getMessage()\n\n log_obj = {\n \"ts\": datetime.now(UTC).isoformat(timespec=\"milliseconds\"),\n \"level\": record.levelname,\n \"trace_id\": _trace_id.get() or \"no-trace\",\n \"src\": src,\n \"marker\": marker,\n \"intent\": intent,\n }\n\n span_id = _span_id.get()\n if span_id:\n log_obj[\"span_id\"] = span_id\n if payload:\n log_obj[\"payload\"] = payload\n if error:\n log_obj[\"error\"] = error\n\n return json.dumps(log_obj, ensure_ascii=False, default=str)\n # #endregion CotJsonFormatter.format\n# #endregion CotJsonFormatter\n"
},
{
"contract_id": "CotJsonFormatter.format",
@@ -21306,14 +21398,14 @@
{
"source_id": "test_logger",
"relation_type": "BINDS_TO",
- "target_id": "EXT:path:src.core.logger",
- "target_ref": "[EXT:path:src.core.logger]"
+ "target_id": "LoggerModule",
+ "target_ref": "[LoggerModule]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region test_logger [TYPE Module] [C:3] [SEMANTICS test, logger, logging, unit]\n# @BRIEF Unit tests for logger module\n# @LAYER Infrastructure\n# @RELATION BINDS_TO -> [EXT:path:src.core.logger]\nfrom pathlib import Path\nimport sys\n\n# Add src to path\nsys.path.append(str(Path(__file__).parent.parent.parent.parent / \"src\"))\nimport logging\nimport pytest\n\nfrom src.core.config_models import LoggingConfig\nfrom src.core.logger import belief_scope, configure_logger, get_task_log_level, logger, should_log_task_level\n\n\n@pytest.fixture(autouse=True)\ndef reset_logger_state():\n \"\"\"Reset logger state before each test to avoid cross-test contamination.\"\"\"\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n # Also reset the logger level for caplog to work correctly\n logging.getLogger(\"superset_tools_app\").setLevel(logging.DEBUG)\n yield\n # Reset after test too\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n# #region test_belief_scope_logs_reason_reflect_at_debug [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.\n# @PRE belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST Logs are verified to contain REASON and REFLECT markers at DEBUG level.\ndef test_belief_scope_logs_reason_reflect_at_debug(caplog):\n \"\"\"Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n with belief_scope(\"TestFunction\"):\n logger.info(\"Doing something important\")\n # Check that the logs contain the expected patterns\n log_messages = [record.message for record in caplog.records]\n assert any(\"[REASON]\" in msg and \"TestFunction\" in msg for msg in log_messages), \"REASON log not found\"\n assert any(\"Doing something important\" in msg for msg in log_messages), \"Inline info log not found\"\n assert any(\"[REFLECT]\" in msg and \"TestFunction\" in msg for msg in log_messages), \"REFLECT log not found\"\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_logs_reason_reflect_at_debug\n# #region test_belief_scope_error_handling [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope logs EXPLORE on exception.\n# @PRE belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST Logs are verified to contain EXPLORE marker.\ndef test_belief_scope_error_handling(caplog):\n \"\"\"Test that belief_scope logs EXPLORE on exception.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n with pytest.raises(ValueError), belief_scope(\"FailingFunction\"):\n raise ValueError(\"Something went wrong\")\n log_messages = [record.message for record in caplog.records]\n assert any(\"[REASON]\" in msg and \"FailingFunction\" in msg for msg in log_messages), \"REASON log not found\"\n assert any(\"[EXPLORE]\" in msg and \"FailingFunction\" in msg and \"Something went wrong\" in msg\n for msg in log_messages), \"EXPLORE log not found\"\n # REFLECT should not be logged on failure\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_error_handling\n# #region test_belief_scope_success_reflect [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope logs REFLECT on success.\n# @PRE belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST Logs are verified to contain REFLECT marker.\ndef test_belief_scope_success_reflect(caplog):\n \"\"\"Test that belief_scope logs REFLECT on success.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n with belief_scope(\"SuccessFunction\"):\n pass\n log_messages = [record.message for record in caplog.records]\n assert any(\"[REFLECT]\" in msg and \"SuccessFunction\" in msg for msg in log_messages), \"REFLECT log not found\"\n\n# #endregion test_belief_scope_success_reflect\n# #region test_belief_scope_not_visible_at_info [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope REFLECT logs are NOT visible at INFO level.\n# @PRE belief_scope is available. caplog fixture is used.\n# @POST REASON is visible at INFO (uses info()); REFLECT is not (uses debug()).\ndef test_belief_scope_not_visible_at_info(caplog):\n \"\"\"Test that belief_scope REFLECT logs are NOT visible at INFO level.\"\"\"\n caplog.set_level(\"INFO\")\n with belief_scope(\"InfoLevelFunction\"):\n logger.info(\"Doing something important\")\n log_messages = [record.message for record in caplog.records]\n # Inline INFO log should be visible\n assert any(\"Doing something important\" in msg for msg in log_messages), \"INFO log not found\"\n # REASON uses info() → visible at INFO level\n assert any(\"[REASON]\" in msg and \"InfoLevelFunction\" in msg for msg in log_messages), \"REASON log should be visible at INFO\"\n # REFLECT uses debug() → NOT visible at INFO level\n assert not any(\"[REFLECT]\" in msg for msg in log_messages), \"REFLECT log should not be visible at INFO\"\n# #endregion test_belief_scope_not_visible_at_info\n# #region test_task_log_level_default [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that default task log level is INFO.\n# @PRE None.\n# @POST Default level is INFO.\ndef test_task_log_level_default():\n \"\"\"Test that default task log level is INFO (after reset fixture).\"\"\"\n level = get_task_log_level()\n assert level == \"INFO\"\n# #endregion test_task_log_level_default\n# #region test_should_log_task_level [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that should_log_task_level correctly filters log levels.\n# @PRE None.\n# @POST Filtering works correctly for all level combinations.\ndef test_should_log_task_level():\n \"\"\"Test that should_log_task_level correctly filters log levels.\"\"\"\n # Default level is INFO\n assert should_log_task_level(\"ERROR\") is True, \"ERROR should be logged at INFO threshold\"\n assert should_log_task_level(\"WARNING\") is True, \"WARNING should be logged at INFO threshold\"\n assert should_log_task_level(\"INFO\") is True, \"INFO should be logged at INFO threshold\"\n assert should_log_task_level(\"DEBUG\") is False, \"DEBUG should NOT be logged at INFO threshold\"\n# #endregion test_should_log_task_level\n# #region test_configure_logger_task_log_level [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that configure_logger updates task_log_level.\n# @PRE LoggingConfig is available.\n# @POST task_log_level is updated correctly.\ndef test_configure_logger_task_log_level():\n \"\"\"Test that configure_logger updates task_log_level.\"\"\"\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n assert get_task_log_level() == \"DEBUG\", \"task_log_level should be DEBUG\"\n assert should_log_task_level(\"DEBUG\") is True, \"DEBUG should be logged at DEBUG threshold\"\n# #endregion test_configure_logger_task_log_level\n# #region test_enable_belief_state_flag [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that enable_belief_state flag controls belief_scope logging.\n# @PRE LoggingConfig is available. caplog fixture is used.\n# @POST belief_scope explicit REASON logs are controlled by the flag; REFLECT always logged.\ndef test_enable_belief_state_flag(caplog):\n \"\"\"Test that enable_belief_state flag controls belief_scope REASON entry logging.\"\"\"\n # Disable belief state\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=False\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"DisabledFunction\"):\n logger.info(\"Doing something\")\n\n log_messages = [record.message for record in caplog.records]\n\n # \"Entering DisabledFunction\" (explicit logger.reason()) should NOT be logged when disabled\n assert not any(\"Entering\" in msg for msg in log_messages), \"REASON entry should not be logged when disabled\"\n # REFLECT should still be logged (internal tracking, not gated by _enable_belief_state)\n assert any(\"[REFLECT]\" in msg for msg in log_messages), \"REFLECT should still be logged\"\n# #endregion test_enable_belief_state_flag\n# #region test_belief_scope_missing_anchor [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test @PRE condition: anchor_id must be provided\ndef test_belief_scope_missing_anchor():\n \"\"\"Test that belief_scope enforces anchor_id to be provided.\"\"\"\n import pytest\n\n from src.core.logger import belief_scope\n with pytest.raises(TypeError):\n # Missing required positional argument 'anchor_id'\n with belief_scope():\n pass\n# #endregion test_belief_scope_missing_anchor\n# #region test_configure_logger_post_conditions [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test @POST condition: Logger level, handlers, belief state flag, and task log level are updated.\ndef test_configure_logger_post_conditions(tmp_path):\n \"\"\"Test that configure_logger satisfies all @POST conditions.\"\"\"\n import logging\n from logging.handlers import RotatingFileHandler\n\n from src.core.config_models import LoggingConfig\n import src.core.logger as logger_module\n from src.core.logger import BeliefFormatter, configure_logger, get_task_log_level, logger\n log_file = tmp_path / \"test.log\"\n config = LoggingConfig(\n level=\"WARNING\",\n task_log_level=\"DEBUG\",\n enable_belief_state=False,\n file_path=str(log_file)\n )\n\n configure_logger(config)\n\n # 1. Logger level is updated\n assert logger.level == logging.WARNING\n\n # 2. Handlers are updated (file handler removed old ones, added new one)\n file_handlers = [h for h in logger.handlers if isinstance(h, RotatingFileHandler)]\n assert len(file_handlers) == 1\n import pathlib\n assert pathlib.Path(file_handlers[0].baseFilename) == log_file.resolve()\n\n # 3. Formatter is set to BeliefFormatter\n for handler in logger.handlers:\n assert isinstance(handler.formatter, BeliefFormatter)\n\n # 4. Global states\n assert logger_module._enable_belief_state is False\n assert get_task_log_level() == \"DEBUG\"\n# #endregion test_configure_logger_post_conditions\n# #endregion test_logger\n"
+ "body": "# #region test_logger [TYPE Module] [C:3] [SEMANTICS test, logger, logging, unit]\n# @BRIEF Unit tests for logger module\n# @LAYER Infrastructure\n# @RELATION BINDS_TO -> [LoggerModule]\nfrom pathlib import Path\nimport sys\n\n# Add src to path\nsys.path.append(str(Path(__file__).parent.parent.parent.parent / \"src\"))\nimport logging\nimport pytest\n\nfrom src.core.config_models import LoggingConfig\nfrom src.core.logger import belief_scope, configure_logger, get_task_log_level, logger, should_log_task_level\n\n\n@pytest.fixture(autouse=True)\ndef reset_logger_state():\n \"\"\"Reset logger state before each test to avoid cross-test contamination.\"\"\"\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n # Also reset the logger level for caplog to work correctly\n logging.getLogger(\"superset_tools_app\").setLevel(logging.DEBUG)\n yield\n # Reset after test too\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n# #region test_belief_scope_logs_reason_reflect_at_debug [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.\n# @PRE belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST Logs are verified to contain REASON and REFLECT markers at DEBUG level.\ndef test_belief_scope_logs_reason_reflect_at_debug(caplog):\n \"\"\"Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n with belief_scope(\"TestFunction\"):\n logger.info(\"Doing something important\")\n # Check that the logs contain the expected patterns\n log_messages = [record.message for record in caplog.records]\n assert any(\"[REASON]\" in msg and \"TestFunction\" in msg for msg in log_messages), \"REASON log not found\"\n assert any(\"Doing something important\" in msg for msg in log_messages), \"Inline info log not found\"\n assert any(\"[REFLECT]\" in msg and \"TestFunction\" in msg for msg in log_messages), \"REFLECT log not found\"\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_logs_reason_reflect_at_debug\n# #region test_belief_scope_error_handling [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope logs EXPLORE on exception.\n# @PRE belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST Logs are verified to contain EXPLORE marker.\ndef test_belief_scope_error_handling(caplog):\n \"\"\"Test that belief_scope logs EXPLORE on exception.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n with pytest.raises(ValueError), belief_scope(\"FailingFunction\"):\n raise ValueError(\"Something went wrong\")\n log_messages = [record.message for record in caplog.records]\n assert any(\"[REASON]\" in msg and \"FailingFunction\" in msg for msg in log_messages), \"REASON log not found\"\n assert any(\"[EXPLORE]\" in msg and \"FailingFunction\" in msg and \"Something went wrong\" in msg\n for msg in log_messages), \"EXPLORE log not found\"\n # REFLECT should not be logged on failure\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_error_handling\n# #region test_belief_scope_success_reflect [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope logs REFLECT on success.\n# @PRE belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST Logs are verified to contain REFLECT marker.\ndef test_belief_scope_success_reflect(caplog):\n \"\"\"Test that belief_scope logs REFLECT on success.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n with belief_scope(\"SuccessFunction\"):\n pass\n log_messages = [record.message for record in caplog.records]\n assert any(\"[REFLECT]\" in msg and \"SuccessFunction\" in msg for msg in log_messages), \"REFLECT log not found\"\n\n# #endregion test_belief_scope_success_reflect\n# #region test_belief_scope_not_visible_at_info [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that belief_scope REFLECT logs are NOT visible at INFO level.\n# @PRE belief_scope is available. caplog fixture is used.\n# @POST REASON is visible at INFO (uses info()); REFLECT is not (uses debug()).\ndef test_belief_scope_not_visible_at_info(caplog):\n \"\"\"Test that belief_scope REFLECT logs are NOT visible at INFO level.\"\"\"\n caplog.set_level(\"INFO\")\n with belief_scope(\"InfoLevelFunction\"):\n logger.info(\"Doing something important\")\n log_messages = [record.message for record in caplog.records]\n # Inline INFO log should be visible\n assert any(\"Doing something important\" in msg for msg in log_messages), \"INFO log not found\"\n # REASON uses info() → visible at INFO level\n assert any(\"[REASON]\" in msg and \"InfoLevelFunction\" in msg for msg in log_messages), \"REASON log should be visible at INFO\"\n # REFLECT uses debug() → NOT visible at INFO level\n assert not any(\"[REFLECT]\" in msg for msg in log_messages), \"REFLECT log should not be visible at INFO\"\n# #endregion test_belief_scope_not_visible_at_info\n# #region test_task_log_level_default [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that default task log level is INFO.\n# @PRE None.\n# @POST Default level is INFO.\ndef test_task_log_level_default():\n \"\"\"Test that default task log level is INFO (after reset fixture).\"\"\"\n level = get_task_log_level()\n assert level == \"INFO\"\n# #endregion test_task_log_level_default\n# #region test_should_log_task_level [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that should_log_task_level correctly filters log levels.\n# @PRE None.\n# @POST Filtering works correctly for all level combinations.\ndef test_should_log_task_level():\n \"\"\"Test that should_log_task_level correctly filters log levels.\"\"\"\n # Default level is INFO\n assert should_log_task_level(\"ERROR\") is True, \"ERROR should be logged at INFO threshold\"\n assert should_log_task_level(\"WARNING\") is True, \"WARNING should be logged at INFO threshold\"\n assert should_log_task_level(\"INFO\") is True, \"INFO should be logged at INFO threshold\"\n assert should_log_task_level(\"DEBUG\") is False, \"DEBUG should NOT be logged at INFO threshold\"\n# #endregion test_should_log_task_level\n# #region test_configure_logger_task_log_level [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that configure_logger updates task_log_level.\n# @PRE LoggingConfig is available.\n# @POST task_log_level is updated correctly.\ndef test_configure_logger_task_log_level():\n \"\"\"Test that configure_logger updates task_log_level.\"\"\"\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n assert get_task_log_level() == \"DEBUG\", \"task_log_level should be DEBUG\"\n assert should_log_task_level(\"DEBUG\") is True, \"DEBUG should be logged at DEBUG threshold\"\n# #endregion test_configure_logger_task_log_level\n# #region test_enable_belief_state_flag [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test that enable_belief_state flag controls belief_scope logging.\n# @PRE LoggingConfig is available. caplog fixture is used.\n# @POST belief_scope explicit REASON logs are controlled by the flag; REFLECT always logged.\ndef test_enable_belief_state_flag(caplog):\n \"\"\"Test that enable_belief_state flag controls belief_scope REASON entry logging.\"\"\"\n # Disable belief state\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=False\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"DisabledFunction\"):\n logger.info(\"Doing something\")\n\n log_messages = [record.message for record in caplog.records]\n\n # \"Entering DisabledFunction\" (explicit logger.reason()) should NOT be logged when disabled\n assert not any(\"Entering\" in msg for msg in log_messages), \"REASON entry should not be logged when disabled\"\n # REFLECT should still be logged (internal tracking, not gated by _enable_belief_state)\n assert any(\"[REFLECT]\" in msg for msg in log_messages), \"REFLECT should still be logged\"\n# #endregion test_enable_belief_state_flag\n# #region test_belief_scope_missing_anchor [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test @PRE condition: anchor_id must be provided\ndef test_belief_scope_missing_anchor():\n \"\"\"Test that belief_scope enforces anchor_id to be provided.\"\"\"\n import pytest\n\n from src.core.logger import belief_scope\n with pytest.raises(TypeError):\n # Missing required positional argument 'anchor_id'\n with belief_scope():\n pass\n# #endregion test_belief_scope_missing_anchor\n# #region test_configure_logger_post_conditions [TYPE Function]\n# @RELATION BINDS_TO -> [test_logger]\n# @BRIEF Test @POST condition: Logger level, handlers, belief state flag, and task log level are updated.\ndef test_configure_logger_post_conditions(tmp_path):\n \"\"\"Test that configure_logger satisfies all @POST conditions.\"\"\"\n import logging\n from logging.handlers import RotatingFileHandler\n\n from src.core.config_models import LoggingConfig\n import src.core.logger as logger_module\n from src.core.logger import BeliefFormatter, configure_logger, get_task_log_level, logger\n log_file = tmp_path / \"test.log\"\n config = LoggingConfig(\n level=\"WARNING\",\n task_log_level=\"DEBUG\",\n enable_belief_state=False,\n file_path=str(log_file)\n )\n\n configure_logger(config)\n\n # 1. Logger level is updated\n assert logger.level == logging.WARNING\n\n # 2. Handlers are updated (file handler removed old ones, added new one)\n file_handlers = [h for h in logger.handlers if isinstance(h, RotatingFileHandler)]\n assert len(file_handlers) == 1\n import pathlib\n assert pathlib.Path(file_handlers[0].baseFilename) == log_file.resolve()\n\n # 3. Formatter is set to BeliefFormatter\n for handler in logger.handlers:\n assert isinstance(handler.formatter, BeliefFormatter)\n\n # 4. Global states\n assert logger_module._enable_belief_state is False\n assert get_task_log_level() == \"DEBUG\"\n# #endregion test_configure_logger_post_conditions\n# #endregion test_logger\n"
},
{
"contract_id": "test_belief_scope_logs_reason_reflect_at_debug",
@@ -22447,7 +22539,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region MigrationEngineModule [C:5] [TYPE Module] [SEMANTICS migration, superset, archive, migration-engine]\n#\n# @BRIEF Transforms Superset export ZIP archives while preserving archive integrity and patching mapped identifiers.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [LoggerModule]\n# @RELATION DEPENDS_ON -> [IdMappingService]\n# @RELATION DEPENDS_ON -> [ResourceType]\n# @RELATION DEPENDS_ON -> [EXT:Library:yaml]\n# @PRE Input archives are readable Superset exports and optional mapping collaborators expose remote id lookup APIs.\n# @POST Migration engine contracts preserve ZIP integrity while exposing transformation entrypoints for import pipelines.\n# @SIDE_EFFECT Reads and writes temporary archive contents during transformation workflows and emits structured belief-state logs.\n# @DATA_CONTRACT Input[zip_path, output_path, db_mapping, target_env_id?, fix_cross_filters?] -> Output[Transformed Superset archive]\n# @INVARIANT ZIP structure and non-targeted metadata must remain valid after transformation.\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport tempfile\nimport zipfile\n\nimport yaml\n\nfrom src.core.mapping_service import IdMappingService\nfrom src.models.mapping import ResourceType\n\nfrom .logger import belief_scope, logger\n\n\n# #region MigrationEngine [TYPE Class]\n# @BRIEF Engine for transforming Superset export ZIPs.\n# @RELATION DEPENDS_ON -> [[EXT:list:MigrationEngine_internal_methods]]\nclass MigrationEngine:\n # #region __init__ [TYPE Function]\n # @PURPOSE: Initializes migration orchestration dependencies for ZIP/YAML metadata transformations.\n # @PRE mapping_service is None or implements batch remote ID lookup for ResourceType.CHART.\n # @POST self.mapping_service is assigned and available for optional cross-filter patching flows.\n # @SIDE_EFFECT Mutates in-memory engine state by storing dependency reference.\n # @DATA_CONTRACT Input[Optional[IdMappingService]] -> Output[MigrationEngine]\n # @PARAM mapping_service (Optional[IdMappingService]) - Used for resolving target environment integer IDs.\n def __init__(self, mapping_service: IdMappingService | None = None):\n with belief_scope(\"MigrationEngine.__init__\"):\n logger.reason(\"Initializing MigrationEngine\")\n self.mapping_service = mapping_service\n logger.reflect(\"MigrationEngine initialized\")\n # #endregion __init__\n # #region transform_zip [TYPE Function]\n # @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.\n # @RELATION DEPENDS_ON -> [[EXT:list:MigrateEngine_transform_methods]]\n # @PARAM zip_path (str) - Path to the source ZIP file.\n # @PARAM output_path (str) - Path where the transformed ZIP will be saved.\n # @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.\n # @PARAM strip_databases (bool) - Whether to remove the databases directory from the archive.\n # @PARAM target_env_id (Optional[str]) - Used if fix_cross_filters is True to know which environment map to use.\n # @PARAM fix_cross_filters (bool) - Whether to patch dashboard json_metadata.\n # @PRE zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.\n # @POST Returns True only when extraction, transformation, and packaging complete without exception.\n # @SIDE_EFFECT Reads/writes filesystem archives, creates temporary directory, emits structured logs.\n # @DATA_CONTRACT Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]\n # @RETURN bool - True if successful.\n def transform_zip(\n self,\n zip_path: str,\n output_path: str,\n db_mapping: dict[str, str],\n strip_databases: bool = True,\n target_env_id: str | None = None,\n fix_cross_filters: bool = False,\n ) -> bool:\n \"\"\"\n Transform a Superset export ZIP by replacing database UUIDs and optionally fixing cross-filters.\n \"\"\"\n with belief_scope(\"MigrationEngine.transform_zip\"):\n logger.reason(f\"Starting ZIP transformation: {zip_path} -> {output_path}\")\n with tempfile.TemporaryDirectory() as temp_dir_str:\n temp_dir = Path(temp_dir_str)\n try:\n # 1. Extract\n logger.reason(f\"Extracting source archive to {temp_dir}\")\n with zipfile.ZipFile(zip_path, \"r\") as zf:\n zf.extractall(temp_dir)\n # 2. Transform YAMLs (Databases)\n dataset_files = list(temp_dir.glob(\"**/datasets/**/*.yaml\")) + list(\n temp_dir.glob(\"**/datasets/*.yaml\")\n )\n dataset_files = list(set(dataset_files))\n logger.reason(\n f\"Transforming {len(dataset_files)} dataset YAML files\"\n )\n for ds_file in dataset_files:\n self._transform_yaml(ds_file, db_mapping)\n # 2.5 Patch Cross-Filters (Dashboards)\n if fix_cross_filters:\n if self.mapping_service and target_env_id:\n dash_files = list(\n temp_dir.glob(\"**/dashboards/**/*.yaml\")\n ) + list(temp_dir.glob(\"**/dashboards/*.yaml\"))\n dash_files = list(set(dash_files))\n logger.reason(\n f\"Patching cross-filters for {len(dash_files)} dashboards\"\n )\n # Gather all source UUID-to-ID mappings from the archive first\n source_id_to_uuid_map = (\n self._extract_chart_uuids_from_archive(temp_dir)\n )\n for dash_file in dash_files:\n self._patch_dashboard_metadata(\n dash_file, target_env_id, source_id_to_uuid_map\n )\n else:\n logger.explore(\n \"Cross-filter patching requested but mapping service or target_env_id is missing\"\n )\n # 3. Re-package\n logger.reason(\n f\"Re-packaging transformed archive (strip_databases={strip_databases})\"\n )\n with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(temp_dir):\n rel_root = Path(root).relative_to(temp_dir)\n if strip_databases and \"databases\" in rel_root.parts:\n continue\n for file in files:\n file_path = Path(root) / file\n arcname = file_path.relative_to(temp_dir)\n zf.write(file_path, arcname)\n logger.reflect(\"ZIP transformation completed successfully\")\n return True\n except Exception as e:\n logger.explore(f\"Error transforming ZIP: {e}\")\n return False\n # #endregion transform_zip\n # #region _transform_yaml [TYPE Function]\n # @PURPOSE: Replaces database_uuid in a single YAML file.\n # @PARAM file_path (Path) - Path to the YAML file.\n # @PARAM db_mapping (Dict[str, str]) - UUID mapping dictionary.\n # @PRE file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.\n # @POST database_uuid is replaced in-place only when source UUID is present in db_mapping.\n # @SIDE_EFFECT Reads and conditionally rewrites YAML file on disk.\n # @DATA_CONTRACT Input[(Path file_path, Dict[str,str] db_mapping)] -> Output[None]\n def _transform_yaml(self, file_path: Path, db_mapping: dict[str, str]):\n with belief_scope(\"MigrationEngine._transform_yaml\"):\n if not file_path.exists():\n logger.explore(f\"YAML file not found: {file_path}\")\n raise FileNotFoundError(str(file_path))\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data:\n return\n source_uuid = data.get(\"database_uuid\")\n if source_uuid in db_mapping:\n logger.reason(f\"Replacing database UUID in {file_path.name}\")\n data[\"database_uuid\"] = db_mapping[source_uuid]\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(f\"Database UUID patched in {file_path.name}\")\n # #endregion _transform_yaml\n # #region _extract_chart_uuids_from_archive [TYPE Function]\n # @PURPOSE: Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.\n # @PRE temp_dir exists and points to extracted archive root with optional chart YAML resources.\n # @POST Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.\n # @SIDE_EFFECT Reads chart YAML files from filesystem; suppresses per-file parsing failures.\n # @DATA_CONTRACT Input[Path] -> Output[Dict[int,str]]\n # @PARAM temp_dir (Path) - Root dir of unpacked archive.\n # @RETURN Dict[int, str] - Mapping of source Integer ID to UUID.\n def _extract_chart_uuids_from_archive(self, temp_dir: Path) -> dict[int, str]:\n with belief_scope(\"MigrationEngine._extract_chart_uuids_from_archive\"):\n # Implementation Note: This is a placeholder for the logic that extracts\n # actual Source IDs. In a real scenario, this involves parsing chart YAMLs\n # or manifesting the export metadata structure where source IDs are stored.\n # For simplicity in US1 MVP, we assume it's read from chart files if present.\n mapping = {}\n chart_files = list(temp_dir.glob(\"**/charts/**/*.yaml\")) + list(\n temp_dir.glob(\"**/charts/*.yaml\")\n )\n for cf in set(chart_files):\n try:\n with open(cf) as f:\n cdata = yaml.safe_load(f)\n if cdata and \"id\" in cdata and \"uuid\" in cdata:\n mapping[cdata[\"id\"]] = cdata[\"uuid\"]\n except Exception:\n logger.debug(\"Could not parse chart YAML file %s\", cf)\n return mapping\n # #endregion _extract_chart_uuids_from_archive\n # #region _patch_dashboard_metadata [TYPE Function]\n # @PURPOSE: Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.\n # @PRE file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.\n # @POST json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.\n # @SIDE_EFFECT Reads/writes YAML file, performs mapping lookup via mapping_service, emits logs for recoverable/terminal failures.\n # @DATA_CONTRACT Input[(Path file_path, str target_env_id, Dict[int,str] source_map)] -> Output[None]\n # @PARAM file_path (Path)\n # @PARAM target_env_id (str)\n # @PARAM source_map (Dict[int, str])\n def _patch_dashboard_metadata(\n self, file_path: Path, target_env_id: str, source_map: dict[int, str]\n ):\n with belief_scope(\"MigrationEngine._patch_dashboard_metadata\"):\n try:\n if not file_path.exists():\n return\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data or \"json_metadata\" not in data:\n return\n metadata_str = data[\"json_metadata\"]\n if not metadata_str:\n return\n # Fetch target UUIDs for everything we know:\n uuids_needed = list(source_map.values())\n logger.reason(\n f\"Resolving {len(uuids_needed)} remote IDs for dashboard metadata patching\"\n )\n target_ids = self.mapping_service.get_remote_ids_batch(\n target_env_id, ResourceType.CHART, uuids_needed\n )\n if not target_ids:\n logger.reflect(\n \"No remote target IDs found in mapping database for this dashboard.\"\n )\n return\n # Map Source Int -> Target Int\n source_to_target = {}\n missing_targets = []\n for s_id, s_uuid in source_map.items():\n if s_uuid in target_ids:\n source_to_target[s_id] = target_ids[s_uuid]\n else:\n missing_targets.append(s_id)\n if missing_targets:\n logger.explore(\n f\"Missing target IDs for source IDs: {missing_targets}. Cross-filters might break.\"\n )\n if not source_to_target:\n logger.reflect(\"No source IDs matched remotely. Skipping patch.\")\n return\n logger.reason(\n f\"Patching {len(source_to_target)} ID references in json_metadata\"\n )\n new_metadata_str = metadata_str\n for s_id, t_id in source_to_target.items():\n new_metadata_str = re.sub(\n r'(\"datasetId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n new_metadata_str = re.sub(\n r'(\"chartId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n # Re-parse to validate valid JSON\n data[\"json_metadata\"] = json.dumps(json.loads(new_metadata_str))\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(\n f\"Dashboard metadata patched and saved: {file_path.name}\"\n )\n except Exception as e:\n logger.explore(f\"Metadata patch failed for {file_path.name}: {e}\")\n # #endregion _patch_dashboard_metadata\n# #endregion MigrationEngine\n# #endregion MigrationEngineModule\n"
+ "body": "# #region MigrationEngineModule [C:5] [TYPE Module] [SEMANTICS migration, superset, archive, migration-engine]\n#\n# @BRIEF Transforms Superset export ZIP archives while preserving archive integrity and patching mapped identifiers.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [LoggerModule]\n# @RELATION DEPENDS_ON -> [IdMappingService]\n# @RELATION DEPENDS_ON -> [ResourceType]\n# @RELATION DEPENDS_ON -> [EXT:Library:yaml]\n# @PRE Input archives are readable Superset exports and optional mapping collaborators expose remote id lookup APIs.\n# @POST Migration engine contracts preserve ZIP integrity while exposing transformation entrypoints for import pipelines.\n# @SIDE_EFFECT Reads and writes temporary archive contents during transformation workflows and emits structured belief-state logs.\n# @DATA_CONTRACT Input[zip_path, output_path, db_mapping, target_env_id?, fix_cross_filters?] -> Output[Transformed Superset archive]\n# @INVARIANT ZIP structure and non-targeted metadata must remain valid after transformation.\nimport json\nimport os\nfrom pathlib import Path\nimport re\nimport tempfile\nimport zipfile\n\nimport yaml\n\nfrom src.core.mapping_service import IdMappingService\nfrom src.models.mapping import ResourceType\n\nfrom .logger import belief_scope, logger\n\n\n# #region MigrationEngine [TYPE Class]\n# @BRIEF Engine for transforming Superset export ZIPs.\n# @RELATION DEPENDS_ON -> [MigrationEngine]\nclass MigrationEngine:\n # #region __init__ [TYPE Function]\n # @PURPOSE: Initializes migration orchestration dependencies for ZIP/YAML metadata transformations.\n # @PRE mapping_service is None or implements batch remote ID lookup for ResourceType.CHART.\n # @POST self.mapping_service is assigned and available for optional cross-filter patching flows.\n # @SIDE_EFFECT Mutates in-memory engine state by storing dependency reference.\n # @DATA_CONTRACT Input[Optional[IdMappingService]] -> Output[MigrationEngine]\n # @PARAM mapping_service (Optional[IdMappingService]) - Used for resolving target environment integer IDs.\n def __init__(self, mapping_service: IdMappingService | None = None):\n with belief_scope(\"MigrationEngine.__init__\"):\n logger.reason(\"Initializing MigrationEngine\")\n self.mapping_service = mapping_service\n logger.reflect(\"MigrationEngine initialized\")\n # #endregion __init__\n # #region transform_zip [TYPE Function]\n # @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.\n # @RELATION DEPENDS_ON -> [MigrationEngine]\n # @PARAM zip_path (str) - Path to the source ZIP file.\n # @PARAM output_path (str) - Path where the transformed ZIP will be saved.\n # @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.\n # @PARAM strip_databases (bool) - Whether to remove the databases directory from the archive.\n # @PARAM target_env_id (Optional[str]) - Used if fix_cross_filters is True to know which environment map to use.\n # @PARAM fix_cross_filters (bool) - Whether to patch dashboard json_metadata.\n # @PRE zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.\n # @POST Returns True only when extraction, transformation, and packaging complete without exception.\n # @SIDE_EFFECT Reads/writes filesystem archives, creates temporary directory, emits structured logs.\n # @DATA_CONTRACT Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]\n # @RETURN bool - True if successful.\n def transform_zip(\n self,\n zip_path: str,\n output_path: str,\n db_mapping: dict[str, str],\n strip_databases: bool = True,\n target_env_id: str | None = None,\n fix_cross_filters: bool = False,\n ) -> bool:\n \"\"\"\n Transform a Superset export ZIP by replacing database UUIDs and optionally fixing cross-filters.\n \"\"\"\n with belief_scope(\"MigrationEngine.transform_zip\"):\n logger.reason(f\"Starting ZIP transformation: {zip_path} -> {output_path}\")\n with tempfile.TemporaryDirectory() as temp_dir_str:\n temp_dir = Path(temp_dir_str)\n try:\n # 1. Extract\n logger.reason(f\"Extracting source archive to {temp_dir}\")\n with zipfile.ZipFile(zip_path, \"r\") as zf:\n zf.extractall(temp_dir)\n # 2. Transform YAMLs (Databases)\n dataset_files = list(temp_dir.glob(\"**/datasets/**/*.yaml\")) + list(\n temp_dir.glob(\"**/datasets/*.yaml\")\n )\n dataset_files = list(set(dataset_files))\n logger.reason(\n f\"Transforming {len(dataset_files)} dataset YAML files\"\n )\n for ds_file in dataset_files:\n self._transform_yaml(ds_file, db_mapping)\n # 2.5 Patch Cross-Filters (Dashboards)\n if fix_cross_filters:\n if self.mapping_service and target_env_id:\n dash_files = list(\n temp_dir.glob(\"**/dashboards/**/*.yaml\")\n ) + list(temp_dir.glob(\"**/dashboards/*.yaml\"))\n dash_files = list(set(dash_files))\n logger.reason(\n f\"Patching cross-filters for {len(dash_files)} dashboards\"\n )\n # Gather all source UUID-to-ID mappings from the archive first\n source_id_to_uuid_map = (\n self._extract_chart_uuids_from_archive(temp_dir)\n )\n for dash_file in dash_files:\n self._patch_dashboard_metadata(\n dash_file, target_env_id, source_id_to_uuid_map\n )\n else:\n logger.explore(\n \"Cross-filter patching requested but mapping service or target_env_id is missing\"\n )\n # 3. Re-package\n logger.reason(\n f\"Re-packaging transformed archive (strip_databases={strip_databases})\"\n )\n with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(temp_dir):\n rel_root = Path(root).relative_to(temp_dir)\n if strip_databases and \"databases\" in rel_root.parts:\n continue\n for file in files:\n file_path = Path(root) / file\n arcname = file_path.relative_to(temp_dir)\n zf.write(file_path, arcname)\n logger.reflect(\"ZIP transformation completed successfully\")\n return True\n except Exception as e:\n logger.explore(f\"Error transforming ZIP: {e}\")\n return False\n # #endregion transform_zip\n # #region _transform_yaml [TYPE Function]\n # @PURPOSE: Replaces database_uuid in a single YAML file.\n # @PARAM file_path (Path) - Path to the YAML file.\n # @PARAM db_mapping (Dict[str, str]) - UUID mapping dictionary.\n # @PRE file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.\n # @POST database_uuid is replaced in-place only when source UUID is present in db_mapping.\n # @SIDE_EFFECT Reads and conditionally rewrites YAML file on disk.\n # @DATA_CONTRACT Input[(Path file_path, Dict[str,str] db_mapping)] -> Output[None]\n def _transform_yaml(self, file_path: Path, db_mapping: dict[str, str]):\n with belief_scope(\"MigrationEngine._transform_yaml\"):\n if not file_path.exists():\n logger.explore(f\"YAML file not found: {file_path}\")\n raise FileNotFoundError(str(file_path))\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data:\n return\n source_uuid = data.get(\"database_uuid\")\n if source_uuid in db_mapping:\n logger.reason(f\"Replacing database UUID in {file_path.name}\")\n data[\"database_uuid\"] = db_mapping[source_uuid]\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(f\"Database UUID patched in {file_path.name}\")\n # #endregion _transform_yaml\n # #region _extract_chart_uuids_from_archive [TYPE Function]\n # @PURPOSE: Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.\n # @PRE temp_dir exists and points to extracted archive root with optional chart YAML resources.\n # @POST Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.\n # @SIDE_EFFECT Reads chart YAML files from filesystem; suppresses per-file parsing failures.\n # @DATA_CONTRACT Input[Path] -> Output[Dict[int,str]]\n # @PARAM temp_dir (Path) - Root dir of unpacked archive.\n # @RETURN Dict[int, str] - Mapping of source Integer ID to UUID.\n def _extract_chart_uuids_from_archive(self, temp_dir: Path) -> dict[int, str]:\n with belief_scope(\"MigrationEngine._extract_chart_uuids_from_archive\"):\n # Implementation Note: This is a placeholder for the logic that extracts\n # actual Source IDs. In a real scenario, this involves parsing chart YAMLs\n # or manifesting the export metadata structure where source IDs are stored.\n # For simplicity in US1 MVP, we assume it's read from chart files if present.\n mapping = {}\n chart_files = list(temp_dir.glob(\"**/charts/**/*.yaml\")) + list(\n temp_dir.glob(\"**/charts/*.yaml\")\n )\n for cf in set(chart_files):\n try:\n with open(cf) as f:\n cdata = yaml.safe_load(f)\n if cdata and \"id\" in cdata and \"uuid\" in cdata:\n mapping[cdata[\"id\"]] = cdata[\"uuid\"]\n except Exception:\n logger.debug(\"Could not parse chart YAML file %s\", cf)\n return mapping\n # #endregion _extract_chart_uuids_from_archive\n # #region _patch_dashboard_metadata [TYPE Function]\n # @PURPOSE: Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.\n # @PRE file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.\n # @POST json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.\n # @SIDE_EFFECT Reads/writes YAML file, performs mapping lookup via mapping_service, emits logs for recoverable/terminal failures.\n # @DATA_CONTRACT Input[(Path file_path, str target_env_id, Dict[int,str] source_map)] -> Output[None]\n # @PARAM file_path (Path)\n # @PARAM target_env_id (str)\n # @PARAM source_map (Dict[int, str])\n def _patch_dashboard_metadata(\n self, file_path: Path, target_env_id: str, source_map: dict[int, str]\n ):\n with belief_scope(\"MigrationEngine._patch_dashboard_metadata\"):\n try:\n if not file_path.exists():\n return\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data or \"json_metadata\" not in data:\n return\n metadata_str = data[\"json_metadata\"]\n if not metadata_str:\n return\n # Fetch target UUIDs for everything we know:\n uuids_needed = list(source_map.values())\n logger.reason(\n f\"Resolving {len(uuids_needed)} remote IDs for dashboard metadata patching\"\n )\n target_ids = self.mapping_service.get_remote_ids_batch(\n target_env_id, ResourceType.CHART, uuids_needed\n )\n if not target_ids:\n logger.reflect(\n \"No remote target IDs found in mapping database for this dashboard.\"\n )\n return\n # Map Source Int -> Target Int\n source_to_target = {}\n missing_targets = []\n for s_id, s_uuid in source_map.items():\n if s_uuid in target_ids:\n source_to_target[s_id] = target_ids[s_uuid]\n else:\n missing_targets.append(s_id)\n if missing_targets:\n logger.explore(\n f\"Missing target IDs for source IDs: {missing_targets}. Cross-filters might break.\"\n )\n if not source_to_target:\n logger.reflect(\"No source IDs matched remotely. Skipping patch.\")\n return\n logger.reason(\n f\"Patching {len(source_to_target)} ID references in json_metadata\"\n )\n new_metadata_str = metadata_str\n for s_id, t_id in source_to_target.items():\n new_metadata_str = re.sub(\n r'(\"datasetId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n new_metadata_str = re.sub(\n r'(\"chartId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n # Re-parse to validate valid JSON\n data[\"json_metadata\"] = json.dumps(json.loads(new_metadata_str))\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(\n f\"Dashboard metadata patched and saved: {file_path.name}\"\n )\n except Exception as e:\n logger.explore(f\"Metadata patch failed for {file_path.name}: {e}\")\n # #endregion _patch_dashboard_metadata\n# #endregion MigrationEngine\n# #endregion MigrationEngineModule\n"
},
{
"contract_id": "MigrationEngine",
@@ -22464,14 +22556,14 @@
{
"source_id": "MigrationEngine",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:list:MigrationEngine_internal_methods]",
- "target_ref": "[[EXT:list:MigrationEngine_internal_methods]]"
+ "target_id": "MigrationEngine",
+ "target_ref": "[MigrationEngine]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region MigrationEngine [TYPE Class]\n# @BRIEF Engine for transforming Superset export ZIPs.\n# @RELATION DEPENDS_ON -> [[EXT:list:MigrationEngine_internal_methods]]\nclass MigrationEngine:\n # #region __init__ [TYPE Function]\n # @PURPOSE: Initializes migration orchestration dependencies for ZIP/YAML metadata transformations.\n # @PRE mapping_service is None or implements batch remote ID lookup for ResourceType.CHART.\n # @POST self.mapping_service is assigned and available for optional cross-filter patching flows.\n # @SIDE_EFFECT Mutates in-memory engine state by storing dependency reference.\n # @DATA_CONTRACT Input[Optional[IdMappingService]] -> Output[MigrationEngine]\n # @PARAM mapping_service (Optional[IdMappingService]) - Used for resolving target environment integer IDs.\n def __init__(self, mapping_service: IdMappingService | None = None):\n with belief_scope(\"MigrationEngine.__init__\"):\n logger.reason(\"Initializing MigrationEngine\")\n self.mapping_service = mapping_service\n logger.reflect(\"MigrationEngine initialized\")\n # #endregion __init__\n # #region transform_zip [TYPE Function]\n # @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.\n # @RELATION DEPENDS_ON -> [[EXT:list:MigrateEngine_transform_methods]]\n # @PARAM zip_path (str) - Path to the source ZIP file.\n # @PARAM output_path (str) - Path where the transformed ZIP will be saved.\n # @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.\n # @PARAM strip_databases (bool) - Whether to remove the databases directory from the archive.\n # @PARAM target_env_id (Optional[str]) - Used if fix_cross_filters is True to know which environment map to use.\n # @PARAM fix_cross_filters (bool) - Whether to patch dashboard json_metadata.\n # @PRE zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.\n # @POST Returns True only when extraction, transformation, and packaging complete without exception.\n # @SIDE_EFFECT Reads/writes filesystem archives, creates temporary directory, emits structured logs.\n # @DATA_CONTRACT Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]\n # @RETURN bool - True if successful.\n def transform_zip(\n self,\n zip_path: str,\n output_path: str,\n db_mapping: dict[str, str],\n strip_databases: bool = True,\n target_env_id: str | None = None,\n fix_cross_filters: bool = False,\n ) -> bool:\n \"\"\"\n Transform a Superset export ZIP by replacing database UUIDs and optionally fixing cross-filters.\n \"\"\"\n with belief_scope(\"MigrationEngine.transform_zip\"):\n logger.reason(f\"Starting ZIP transformation: {zip_path} -> {output_path}\")\n with tempfile.TemporaryDirectory() as temp_dir_str:\n temp_dir = Path(temp_dir_str)\n try:\n # 1. Extract\n logger.reason(f\"Extracting source archive to {temp_dir}\")\n with zipfile.ZipFile(zip_path, \"r\") as zf:\n zf.extractall(temp_dir)\n # 2. Transform YAMLs (Databases)\n dataset_files = list(temp_dir.glob(\"**/datasets/**/*.yaml\")) + list(\n temp_dir.glob(\"**/datasets/*.yaml\")\n )\n dataset_files = list(set(dataset_files))\n logger.reason(\n f\"Transforming {len(dataset_files)} dataset YAML files\"\n )\n for ds_file in dataset_files:\n self._transform_yaml(ds_file, db_mapping)\n # 2.5 Patch Cross-Filters (Dashboards)\n if fix_cross_filters:\n if self.mapping_service and target_env_id:\n dash_files = list(\n temp_dir.glob(\"**/dashboards/**/*.yaml\")\n ) + list(temp_dir.glob(\"**/dashboards/*.yaml\"))\n dash_files = list(set(dash_files))\n logger.reason(\n f\"Patching cross-filters for {len(dash_files)} dashboards\"\n )\n # Gather all source UUID-to-ID mappings from the archive first\n source_id_to_uuid_map = (\n self._extract_chart_uuids_from_archive(temp_dir)\n )\n for dash_file in dash_files:\n self._patch_dashboard_metadata(\n dash_file, target_env_id, source_id_to_uuid_map\n )\n else:\n logger.explore(\n \"Cross-filter patching requested but mapping service or target_env_id is missing\"\n )\n # 3. Re-package\n logger.reason(\n f\"Re-packaging transformed archive (strip_databases={strip_databases})\"\n )\n with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(temp_dir):\n rel_root = Path(root).relative_to(temp_dir)\n if strip_databases and \"databases\" in rel_root.parts:\n continue\n for file in files:\n file_path = Path(root) / file\n arcname = file_path.relative_to(temp_dir)\n zf.write(file_path, arcname)\n logger.reflect(\"ZIP transformation completed successfully\")\n return True\n except Exception as e:\n logger.explore(f\"Error transforming ZIP: {e}\")\n return False\n # #endregion transform_zip\n # #region _transform_yaml [TYPE Function]\n # @PURPOSE: Replaces database_uuid in a single YAML file.\n # @PARAM file_path (Path) - Path to the YAML file.\n # @PARAM db_mapping (Dict[str, str]) - UUID mapping dictionary.\n # @PRE file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.\n # @POST database_uuid is replaced in-place only when source UUID is present in db_mapping.\n # @SIDE_EFFECT Reads and conditionally rewrites YAML file on disk.\n # @DATA_CONTRACT Input[(Path file_path, Dict[str,str] db_mapping)] -> Output[None]\n def _transform_yaml(self, file_path: Path, db_mapping: dict[str, str]):\n with belief_scope(\"MigrationEngine._transform_yaml\"):\n if not file_path.exists():\n logger.explore(f\"YAML file not found: {file_path}\")\n raise FileNotFoundError(str(file_path))\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data:\n return\n source_uuid = data.get(\"database_uuid\")\n if source_uuid in db_mapping:\n logger.reason(f\"Replacing database UUID in {file_path.name}\")\n data[\"database_uuid\"] = db_mapping[source_uuid]\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(f\"Database UUID patched in {file_path.name}\")\n # #endregion _transform_yaml\n # #region _extract_chart_uuids_from_archive [TYPE Function]\n # @PURPOSE: Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.\n # @PRE temp_dir exists and points to extracted archive root with optional chart YAML resources.\n # @POST Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.\n # @SIDE_EFFECT Reads chart YAML files from filesystem; suppresses per-file parsing failures.\n # @DATA_CONTRACT Input[Path] -> Output[Dict[int,str]]\n # @PARAM temp_dir (Path) - Root dir of unpacked archive.\n # @RETURN Dict[int, str] - Mapping of source Integer ID to UUID.\n def _extract_chart_uuids_from_archive(self, temp_dir: Path) -> dict[int, str]:\n with belief_scope(\"MigrationEngine._extract_chart_uuids_from_archive\"):\n # Implementation Note: This is a placeholder for the logic that extracts\n # actual Source IDs. In a real scenario, this involves parsing chart YAMLs\n # or manifesting the export metadata structure where source IDs are stored.\n # For simplicity in US1 MVP, we assume it's read from chart files if present.\n mapping = {}\n chart_files = list(temp_dir.glob(\"**/charts/**/*.yaml\")) + list(\n temp_dir.glob(\"**/charts/*.yaml\")\n )\n for cf in set(chart_files):\n try:\n with open(cf) as f:\n cdata = yaml.safe_load(f)\n if cdata and \"id\" in cdata and \"uuid\" in cdata:\n mapping[cdata[\"id\"]] = cdata[\"uuid\"]\n except Exception:\n logger.debug(\"Could not parse chart YAML file %s\", cf)\n return mapping\n # #endregion _extract_chart_uuids_from_archive\n # #region _patch_dashboard_metadata [TYPE Function]\n # @PURPOSE: Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.\n # @PRE file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.\n # @POST json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.\n # @SIDE_EFFECT Reads/writes YAML file, performs mapping lookup via mapping_service, emits logs for recoverable/terminal failures.\n # @DATA_CONTRACT Input[(Path file_path, str target_env_id, Dict[int,str] source_map)] -> Output[None]\n # @PARAM file_path (Path)\n # @PARAM target_env_id (str)\n # @PARAM source_map (Dict[int, str])\n def _patch_dashboard_metadata(\n self, file_path: Path, target_env_id: str, source_map: dict[int, str]\n ):\n with belief_scope(\"MigrationEngine._patch_dashboard_metadata\"):\n try:\n if not file_path.exists():\n return\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data or \"json_metadata\" not in data:\n return\n metadata_str = data[\"json_metadata\"]\n if not metadata_str:\n return\n # Fetch target UUIDs for everything we know:\n uuids_needed = list(source_map.values())\n logger.reason(\n f\"Resolving {len(uuids_needed)} remote IDs for dashboard metadata patching\"\n )\n target_ids = self.mapping_service.get_remote_ids_batch(\n target_env_id, ResourceType.CHART, uuids_needed\n )\n if not target_ids:\n logger.reflect(\n \"No remote target IDs found in mapping database for this dashboard.\"\n )\n return\n # Map Source Int -> Target Int\n source_to_target = {}\n missing_targets = []\n for s_id, s_uuid in source_map.items():\n if s_uuid in target_ids:\n source_to_target[s_id] = target_ids[s_uuid]\n else:\n missing_targets.append(s_id)\n if missing_targets:\n logger.explore(\n f\"Missing target IDs for source IDs: {missing_targets}. Cross-filters might break.\"\n )\n if not source_to_target:\n logger.reflect(\"No source IDs matched remotely. Skipping patch.\")\n return\n logger.reason(\n f\"Patching {len(source_to_target)} ID references in json_metadata\"\n )\n new_metadata_str = metadata_str\n for s_id, t_id in source_to_target.items():\n new_metadata_str = re.sub(\n r'(\"datasetId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n new_metadata_str = re.sub(\n r'(\"chartId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n # Re-parse to validate valid JSON\n data[\"json_metadata\"] = json.dumps(json.loads(new_metadata_str))\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(\n f\"Dashboard metadata patched and saved: {file_path.name}\"\n )\n except Exception as e:\n logger.explore(f\"Metadata patch failed for {file_path.name}: {e}\")\n # #endregion _patch_dashboard_metadata\n# #endregion MigrationEngine\n"
+ "body": "# #region MigrationEngine [TYPE Class]\n# @BRIEF Engine for transforming Superset export ZIPs.\n# @RELATION DEPENDS_ON -> [MigrationEngine]\nclass MigrationEngine:\n # #region __init__ [TYPE Function]\n # @PURPOSE: Initializes migration orchestration dependencies for ZIP/YAML metadata transformations.\n # @PRE mapping_service is None or implements batch remote ID lookup for ResourceType.CHART.\n # @POST self.mapping_service is assigned and available for optional cross-filter patching flows.\n # @SIDE_EFFECT Mutates in-memory engine state by storing dependency reference.\n # @DATA_CONTRACT Input[Optional[IdMappingService]] -> Output[MigrationEngine]\n # @PARAM mapping_service (Optional[IdMappingService]) - Used for resolving target environment integer IDs.\n def __init__(self, mapping_service: IdMappingService | None = None):\n with belief_scope(\"MigrationEngine.__init__\"):\n logger.reason(\"Initializing MigrationEngine\")\n self.mapping_service = mapping_service\n logger.reflect(\"MigrationEngine initialized\")\n # #endregion __init__\n # #region transform_zip [TYPE Function]\n # @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.\n # @RELATION DEPENDS_ON -> [MigrationEngine]\n # @PARAM zip_path (str) - Path to the source ZIP file.\n # @PARAM output_path (str) - Path where the transformed ZIP will be saved.\n # @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.\n # @PARAM strip_databases (bool) - Whether to remove the databases directory from the archive.\n # @PARAM target_env_id (Optional[str]) - Used if fix_cross_filters is True to know which environment map to use.\n # @PARAM fix_cross_filters (bool) - Whether to patch dashboard json_metadata.\n # @PRE zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.\n # @POST Returns True only when extraction, transformation, and packaging complete without exception.\n # @SIDE_EFFECT Reads/writes filesystem archives, creates temporary directory, emits structured logs.\n # @DATA_CONTRACT Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]\n # @RETURN bool - True if successful.\n def transform_zip(\n self,\n zip_path: str,\n output_path: str,\n db_mapping: dict[str, str],\n strip_databases: bool = True,\n target_env_id: str | None = None,\n fix_cross_filters: bool = False,\n ) -> bool:\n \"\"\"\n Transform a Superset export ZIP by replacing database UUIDs and optionally fixing cross-filters.\n \"\"\"\n with belief_scope(\"MigrationEngine.transform_zip\"):\n logger.reason(f\"Starting ZIP transformation: {zip_path} -> {output_path}\")\n with tempfile.TemporaryDirectory() as temp_dir_str:\n temp_dir = Path(temp_dir_str)\n try:\n # 1. Extract\n logger.reason(f\"Extracting source archive to {temp_dir}\")\n with zipfile.ZipFile(zip_path, \"r\") as zf:\n zf.extractall(temp_dir)\n # 2. Transform YAMLs (Databases)\n dataset_files = list(temp_dir.glob(\"**/datasets/**/*.yaml\")) + list(\n temp_dir.glob(\"**/datasets/*.yaml\")\n )\n dataset_files = list(set(dataset_files))\n logger.reason(\n f\"Transforming {len(dataset_files)} dataset YAML files\"\n )\n for ds_file in dataset_files:\n self._transform_yaml(ds_file, db_mapping)\n # 2.5 Patch Cross-Filters (Dashboards)\n if fix_cross_filters:\n if self.mapping_service and target_env_id:\n dash_files = list(\n temp_dir.glob(\"**/dashboards/**/*.yaml\")\n ) + list(temp_dir.glob(\"**/dashboards/*.yaml\"))\n dash_files = list(set(dash_files))\n logger.reason(\n f\"Patching cross-filters for {len(dash_files)} dashboards\"\n )\n # Gather all source UUID-to-ID mappings from the archive first\n source_id_to_uuid_map = (\n self._extract_chart_uuids_from_archive(temp_dir)\n )\n for dash_file in dash_files:\n self._patch_dashboard_metadata(\n dash_file, target_env_id, source_id_to_uuid_map\n )\n else:\n logger.explore(\n \"Cross-filter patching requested but mapping service or target_env_id is missing\"\n )\n # 3. Re-package\n logger.reason(\n f\"Re-packaging transformed archive (strip_databases={strip_databases})\"\n )\n with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(temp_dir):\n rel_root = Path(root).relative_to(temp_dir)\n if strip_databases and \"databases\" in rel_root.parts:\n continue\n for file in files:\n file_path = Path(root) / file\n arcname = file_path.relative_to(temp_dir)\n zf.write(file_path, arcname)\n logger.reflect(\"ZIP transformation completed successfully\")\n return True\n except Exception as e:\n logger.explore(f\"Error transforming ZIP: {e}\")\n return False\n # #endregion transform_zip\n # #region _transform_yaml [TYPE Function]\n # @PURPOSE: Replaces database_uuid in a single YAML file.\n # @PARAM file_path (Path) - Path to the YAML file.\n # @PARAM db_mapping (Dict[str, str]) - UUID mapping dictionary.\n # @PRE file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.\n # @POST database_uuid is replaced in-place only when source UUID is present in db_mapping.\n # @SIDE_EFFECT Reads and conditionally rewrites YAML file on disk.\n # @DATA_CONTRACT Input[(Path file_path, Dict[str,str] db_mapping)] -> Output[None]\n def _transform_yaml(self, file_path: Path, db_mapping: dict[str, str]):\n with belief_scope(\"MigrationEngine._transform_yaml\"):\n if not file_path.exists():\n logger.explore(f\"YAML file not found: {file_path}\")\n raise FileNotFoundError(str(file_path))\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data:\n return\n source_uuid = data.get(\"database_uuid\")\n if source_uuid in db_mapping:\n logger.reason(f\"Replacing database UUID in {file_path.name}\")\n data[\"database_uuid\"] = db_mapping[source_uuid]\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(f\"Database UUID patched in {file_path.name}\")\n # #endregion _transform_yaml\n # #region _extract_chart_uuids_from_archive [TYPE Function]\n # @PURPOSE: Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.\n # @PRE temp_dir exists and points to extracted archive root with optional chart YAML resources.\n # @POST Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.\n # @SIDE_EFFECT Reads chart YAML files from filesystem; suppresses per-file parsing failures.\n # @DATA_CONTRACT Input[Path] -> Output[Dict[int,str]]\n # @PARAM temp_dir (Path) - Root dir of unpacked archive.\n # @RETURN Dict[int, str] - Mapping of source Integer ID to UUID.\n def _extract_chart_uuids_from_archive(self, temp_dir: Path) -> dict[int, str]:\n with belief_scope(\"MigrationEngine._extract_chart_uuids_from_archive\"):\n # Implementation Note: This is a placeholder for the logic that extracts\n # actual Source IDs. In a real scenario, this involves parsing chart YAMLs\n # or manifesting the export metadata structure where source IDs are stored.\n # For simplicity in US1 MVP, we assume it's read from chart files if present.\n mapping = {}\n chart_files = list(temp_dir.glob(\"**/charts/**/*.yaml\")) + list(\n temp_dir.glob(\"**/charts/*.yaml\")\n )\n for cf in set(chart_files):\n try:\n with open(cf) as f:\n cdata = yaml.safe_load(f)\n if cdata and \"id\" in cdata and \"uuid\" in cdata:\n mapping[cdata[\"id\"]] = cdata[\"uuid\"]\n except Exception:\n logger.debug(\"Could not parse chart YAML file %s\", cf)\n return mapping\n # #endregion _extract_chart_uuids_from_archive\n # #region _patch_dashboard_metadata [TYPE Function]\n # @PURPOSE: Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.\n # @PRE file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.\n # @POST json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.\n # @SIDE_EFFECT Reads/writes YAML file, performs mapping lookup via mapping_service, emits logs for recoverable/terminal failures.\n # @DATA_CONTRACT Input[(Path file_path, str target_env_id, Dict[int,str] source_map)] -> Output[None]\n # @PARAM file_path (Path)\n # @PARAM target_env_id (str)\n # @PARAM source_map (Dict[int, str])\n def _patch_dashboard_metadata(\n self, file_path: Path, target_env_id: str, source_map: dict[int, str]\n ):\n with belief_scope(\"MigrationEngine._patch_dashboard_metadata\"):\n try:\n if not file_path.exists():\n return\n with open(file_path) as f:\n data = yaml.safe_load(f)\n if not data or \"json_metadata\" not in data:\n return\n metadata_str = data[\"json_metadata\"]\n if not metadata_str:\n return\n # Fetch target UUIDs for everything we know:\n uuids_needed = list(source_map.values())\n logger.reason(\n f\"Resolving {len(uuids_needed)} remote IDs for dashboard metadata patching\"\n )\n target_ids = self.mapping_service.get_remote_ids_batch(\n target_env_id, ResourceType.CHART, uuids_needed\n )\n if not target_ids:\n logger.reflect(\n \"No remote target IDs found in mapping database for this dashboard.\"\n )\n return\n # Map Source Int -> Target Int\n source_to_target = {}\n missing_targets = []\n for s_id, s_uuid in source_map.items():\n if s_uuid in target_ids:\n source_to_target[s_id] = target_ids[s_uuid]\n else:\n missing_targets.append(s_id)\n if missing_targets:\n logger.explore(\n f\"Missing target IDs for source IDs: {missing_targets}. Cross-filters might break.\"\n )\n if not source_to_target:\n logger.reflect(\"No source IDs matched remotely. Skipping patch.\")\n return\n logger.reason(\n f\"Patching {len(source_to_target)} ID references in json_metadata\"\n )\n new_metadata_str = metadata_str\n for s_id, t_id in source_to_target.items():\n new_metadata_str = re.sub(\n r'(\"datasetId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n new_metadata_str = re.sub(\n r'(\"chartId\"\\s*:\\s*)' + str(s_id) + r\"(\\b)\",\n r\"\\g<1>\" + str(t_id) + r\"\\g<2>\",\n new_metadata_str,\n )\n # Re-parse to validate valid JSON\n data[\"json_metadata\"] = json.dumps(json.loads(new_metadata_str))\n with open(file_path, \"w\") as f:\n yaml.dump(data, f)\n logger.reflect(\n f\"Dashboard metadata patched and saved: {file_path.name}\"\n )\n except Exception as e:\n logger.explore(f\"Metadata patch failed for {file_path.name}: {e}\")\n # #endregion _patch_dashboard_metadata\n# #endregion MigrationEngine\n"
},
{
"contract_id": "transform_zip",
@@ -22494,14 +22586,14 @@
{
"source_id": "transform_zip",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:list:MigrateEngine_transform_methods]",
- "target_ref": "[[EXT:list:MigrateEngine_transform_methods]]"
+ "target_id": "MigrationEngine",
+ "target_ref": "[MigrationEngine]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": " # #region transform_zip [TYPE Function]\n # @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.\n # @RELATION DEPENDS_ON -> [[EXT:list:MigrateEngine_transform_methods]]\n # @PARAM zip_path (str) - Path to the source ZIP file.\n # @PARAM output_path (str) - Path where the transformed ZIP will be saved.\n # @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.\n # @PARAM strip_databases (bool) - Whether to remove the databases directory from the archive.\n # @PARAM target_env_id (Optional[str]) - Used if fix_cross_filters is True to know which environment map to use.\n # @PARAM fix_cross_filters (bool) - Whether to patch dashboard json_metadata.\n # @PRE zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.\n # @POST Returns True only when extraction, transformation, and packaging complete without exception.\n # @SIDE_EFFECT Reads/writes filesystem archives, creates temporary directory, emits structured logs.\n # @DATA_CONTRACT Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]\n # @RETURN bool - True if successful.\n def transform_zip(\n self,\n zip_path: str,\n output_path: str,\n db_mapping: dict[str, str],\n strip_databases: bool = True,\n target_env_id: str | None = None,\n fix_cross_filters: bool = False,\n ) -> bool:\n \"\"\"\n Transform a Superset export ZIP by replacing database UUIDs and optionally fixing cross-filters.\n \"\"\"\n with belief_scope(\"MigrationEngine.transform_zip\"):\n logger.reason(f\"Starting ZIP transformation: {zip_path} -> {output_path}\")\n with tempfile.TemporaryDirectory() as temp_dir_str:\n temp_dir = Path(temp_dir_str)\n try:\n # 1. Extract\n logger.reason(f\"Extracting source archive to {temp_dir}\")\n with zipfile.ZipFile(zip_path, \"r\") as zf:\n zf.extractall(temp_dir)\n # 2. Transform YAMLs (Databases)\n dataset_files = list(temp_dir.glob(\"**/datasets/**/*.yaml\")) + list(\n temp_dir.glob(\"**/datasets/*.yaml\")\n )\n dataset_files = list(set(dataset_files))\n logger.reason(\n f\"Transforming {len(dataset_files)} dataset YAML files\"\n )\n for ds_file in dataset_files:\n self._transform_yaml(ds_file, db_mapping)\n # 2.5 Patch Cross-Filters (Dashboards)\n if fix_cross_filters:\n if self.mapping_service and target_env_id:\n dash_files = list(\n temp_dir.glob(\"**/dashboards/**/*.yaml\")\n ) + list(temp_dir.glob(\"**/dashboards/*.yaml\"))\n dash_files = list(set(dash_files))\n logger.reason(\n f\"Patching cross-filters for {len(dash_files)} dashboards\"\n )\n # Gather all source UUID-to-ID mappings from the archive first\n source_id_to_uuid_map = (\n self._extract_chart_uuids_from_archive(temp_dir)\n )\n for dash_file in dash_files:\n self._patch_dashboard_metadata(\n dash_file, target_env_id, source_id_to_uuid_map\n )\n else:\n logger.explore(\n \"Cross-filter patching requested but mapping service or target_env_id is missing\"\n )\n # 3. Re-package\n logger.reason(\n f\"Re-packaging transformed archive (strip_databases={strip_databases})\"\n )\n with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(temp_dir):\n rel_root = Path(root).relative_to(temp_dir)\n if strip_databases and \"databases\" in rel_root.parts:\n continue\n for file in files:\n file_path = Path(root) / file\n arcname = file_path.relative_to(temp_dir)\n zf.write(file_path, arcname)\n logger.reflect(\"ZIP transformation completed successfully\")\n return True\n except Exception as e:\n logger.explore(f\"Error transforming ZIP: {e}\")\n return False\n # #endregion transform_zip\n"
+ "body": " # #region transform_zip [TYPE Function]\n # @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.\n # @RELATION DEPENDS_ON -> [MigrationEngine]\n # @PARAM zip_path (str) - Path to the source ZIP file.\n # @PARAM output_path (str) - Path where the transformed ZIP will be saved.\n # @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.\n # @PARAM strip_databases (bool) - Whether to remove the databases directory from the archive.\n # @PARAM target_env_id (Optional[str]) - Used if fix_cross_filters is True to know which environment map to use.\n # @PARAM fix_cross_filters (bool) - Whether to patch dashboard json_metadata.\n # @PRE zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.\n # @POST Returns True only when extraction, transformation, and packaging complete without exception.\n # @SIDE_EFFECT Reads/writes filesystem archives, creates temporary directory, emits structured logs.\n # @DATA_CONTRACT Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]\n # @RETURN bool - True if successful.\n def transform_zip(\n self,\n zip_path: str,\n output_path: str,\n db_mapping: dict[str, str],\n strip_databases: bool = True,\n target_env_id: str | None = None,\n fix_cross_filters: bool = False,\n ) -> bool:\n \"\"\"\n Transform a Superset export ZIP by replacing database UUIDs and optionally fixing cross-filters.\n \"\"\"\n with belief_scope(\"MigrationEngine.transform_zip\"):\n logger.reason(f\"Starting ZIP transformation: {zip_path} -> {output_path}\")\n with tempfile.TemporaryDirectory() as temp_dir_str:\n temp_dir = Path(temp_dir_str)\n try:\n # 1. Extract\n logger.reason(f\"Extracting source archive to {temp_dir}\")\n with zipfile.ZipFile(zip_path, \"r\") as zf:\n zf.extractall(temp_dir)\n # 2. Transform YAMLs (Databases)\n dataset_files = list(temp_dir.glob(\"**/datasets/**/*.yaml\")) + list(\n temp_dir.glob(\"**/datasets/*.yaml\")\n )\n dataset_files = list(set(dataset_files))\n logger.reason(\n f\"Transforming {len(dataset_files)} dataset YAML files\"\n )\n for ds_file in dataset_files:\n self._transform_yaml(ds_file, db_mapping)\n # 2.5 Patch Cross-Filters (Dashboards)\n if fix_cross_filters:\n if self.mapping_service and target_env_id:\n dash_files = list(\n temp_dir.glob(\"**/dashboards/**/*.yaml\")\n ) + list(temp_dir.glob(\"**/dashboards/*.yaml\"))\n dash_files = list(set(dash_files))\n logger.reason(\n f\"Patching cross-filters for {len(dash_files)} dashboards\"\n )\n # Gather all source UUID-to-ID mappings from the archive first\n source_id_to_uuid_map = (\n self._extract_chart_uuids_from_archive(temp_dir)\n )\n for dash_file in dash_files:\n self._patch_dashboard_metadata(\n dash_file, target_env_id, source_id_to_uuid_map\n )\n else:\n logger.explore(\n \"Cross-filter patching requested but mapping service or target_env_id is missing\"\n )\n # 3. Re-package\n logger.reason(\n f\"Re-packaging transformed archive (strip_databases={strip_databases})\"\n )\n with zipfile.ZipFile(output_path, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(temp_dir):\n rel_root = Path(root).relative_to(temp_dir)\n if strip_databases and \"databases\" in rel_root.parts:\n continue\n for file in files:\n file_path = Path(root) / file\n arcname = file_path.relative_to(temp_dir)\n zf.write(file_path, arcname)\n logger.reflect(\"ZIP transformation completed successfully\")\n return True\n except Exception as e:\n logger.explore(f\"Error transforming ZIP: {e}\")\n return False\n # #endregion transform_zip\n"
},
{
"contract_id": "_transform_yaml",
@@ -24343,7 +24435,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region SupersetDashboardsWriteMixin [C:4] [TYPE Module] [SEMANTICS superset, dashboard, chart, write, maintenance, banner]\n# @BRIEF Dashboard write mixin for SupersetClient — markdown chart CRUD and layout manipulation for maintenance banners.\n# @LAYER Infrastructure\n# @RELATION DEPENDS_ON -> [SupersetClientBase]\n# @RELATION DEPENDS_ON -> [SupersetChartsMixin]\n# @RELATION DEPENDS_ON -> [LayoutUtils]\n# @SIDE_EFFECT Creates, updates, deletes markdown charts & modifies dashboard layout via Superset API.\n# @DATA_CONTRACT Input: dashboard_id / chart_id / markdown_text → Output: API response dict or chart_id int\n# @INVARIANT All network operations use self.network.request()\n# @RATIONALE Extracted from monolithic superset_client to satisfy INV_7.\n# Uses belief_scope with REASON/REFLECT/EXPLORE markers for all C4 operations per Std.Semantics.Python.\n\nimport json\nfrom typing import Any, cast\n\nfrom ..logger import belief_scope, logger as app_logger\nfrom ._layout[EXT:internal:_utils] import (\n insert_banner_markdown_at_top,\n parse_position_json,\n remove_banner_from_position,\n update_banner_markdown_content,\n)\n\napp_logger = cast(Any, app_logger)\n\n\n# #region SupersetDashboardsWriteMixin [C:4] [TYPE Class]\n# @BRIEF Mixin providing markdown chart CRUD and dashboard layout manipulation for maintenance banners.\n# @RELATION DEPENDS_ON -> [SupersetClientBase]\n# @RELATION DEPENDS_ON -> [SupersetChartsMixin]\nclass SupersetDashboardsWriteMixin:\n \"\"\"Mixin for creating/updating/deleting markdown charts and manipulating dashboard layouts.\"\"\"\n\n # #region create_markdown_chart [C:3] [TYPE Function]\n # @BRIEF Create a markdown chart and return the new chart ID.\n # @PRE dashboard_id exists in Superset. markdown_text not empty.\n # @POST Returns chart_id (int). Chart is NOT yet placed in dashboard layout.\n # @SIDE_EFFECT Creates a new chart resource in Superset.\n # @RELATION CALLS -> [EXT:method:self.network.request]\n def create_markdown_chart(self, dashboard_id: int, markdown_text: str) -> int:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.create_markdown_chart\",\n f\"dashboard_id={dashboard_id}\",\n ):\n app_logger.reason(\n \"Creating markdown chart\",\n extra={\"dashboard_id\": dashboard_id, \"len\": len(markdown_text)},\n )\n datasource_id = self._resolve_markdown_datasource(dashboard_id)\n payload = {\n \"dashboards\": [dashboard_id],\n \"datasource_id\": datasource_id,\n \"datasource_type\": \"table\",\n \"slice_name\": \"Maintenance Banner\",\n \"viz_type\": \"markdown\",\n \"params\": json.dumps({\n \"markdown\": markdown_text,\n \"viz_type\": \"markdown\",\n }),\n }\n try:\n response = cast(dict, self.network.request(\n method=\"POST\", endpoint=\"/chart/\", json=payload\n ))\n chart_id = int(response.get(\"id\") or response.get(\"result\", {}).get(\"id\", 0))\n app_logger.reflect(\"Chart created\", extra={\"chart_id\": chart_id})\n return chart_id\n except Exception as e:\n app_logger.explore(\"Create chart failed\", extra={\"dashboard_id\": dashboard_id}, error=str(e))\n raise\n # #endregion create_markdown_chart\n\n # #region update_markdown_chart [C:3] [TYPE Function]\n # @BRIEF Update the markdown text of an existing markdown chart.\n # @PRE chart_id exists and is a markdown chart.\n # @POST Chart markdown content updated.\n # @SIDE_EFFECT Modifies a chart resource in Superset.\n def update_markdown_chart(self, chart_id: int, markdown_text: str) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.update_markdown_chart\",\n f\"chart_id={chart_id}\",\n ):\n app_logger.reason(\"Updating markdown chart\", extra={\"chart_id\": chart_id, \"len\": len(markdown_text)})\n payload = {\"params\": json.dumps({\"markdown\": markdown_text, \"viz_type\": \"markdown\"})}\n try:\n response = cast(dict, self.network.request(method=\"PUT\", endpoint=f\"/chart/{chart_id}\", json=payload))\n app_logger.reflect(\"Chart updated\", extra={\"chart_id\": chart_id})\n return response\n except Exception as e:\n app_logger.explore(\"Update chart failed\", extra={\"chart_id\": chart_id}, error=str(e))\n raise\n # #endregion update_markdown_chart\n\n # #region update_dashboard_layout [C:4] [TYPE Function]\n # @BRIEF Insert a native MARKDOWN element at (0,0) with full width (12 cols),\n # shift existing charts down. Uses native MARKDOWN for reliable rendering.\n # @PRE dashboard_id exists in Superset. chart_id is used for tracking/DB.\n # @POST MARKDOWN element placed at top; existing items shifted down.\n # @SIDE_EFFECT Modifies dashboard layout JSON.\n def update_dashboard_layout(self, dashboard_id: int, chart_id: int) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.update_dashboard_layout\",\n f\"dashboard_id={dashboard_id}, chart_id={chart_id}\",\n ):\n app_logger.reason(\n \"Updating layout with native MARKDOWN\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n try:\n dashboard = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n ))\n result = dashboard.get(\"result\", dashboard)\n position_json = parse_position_json(result.get(\"position_json\", \"{}\"))\n\n # Use native MARKDOWN element inside a ROW, connected to GRID_ID\n placeholder = \"*Maintenance banner*\"\n insert_banner_markdown_at_top(position_json, chart_id, placeholder)\n\n response = cast(dict, self.network.request(\n method=\"PUT\", endpoint=f\"/dashboard/{dashboard_id}\",\n json={\"position_json\": json.dumps(position_json)},\n ))\n app_logger.reflect(\n \"Layout updated with native MARKDOWN\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n return response\n except Exception as e:\n app_logger.explore(\n \"Layout update failed\",\n extra={\"dashboard_id\": dashboard_id},\n error=str(e),\n )\n raise\n # #endregion update_dashboard_layout\n\n # #region remove_chart_from_layout [C:3] [TYPE Function]\n # @BRIEF Remove banner markdown element from dashboard layout without deleting the chart.\n # @PRE dashboard_id exists. chart_id exists in layout as MARKDOWN-banner-{chart_id}.\n # @POST MARKDOWN element removed from position_json; items shifted up.\n # @SIDE_EFFECT Modifies dashboard layout JSON.\n def remove_chart_from_layout(self, dashboard_id: int, chart_id: int) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.remove_chart_from_layout\",\n f\"dashboard_id={dashboard_id}, chart_id={chart_id}\",\n ):\n app_logger.reason(\n \"Removing banner from layout\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n try:\n dashboard = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n ))\n result = dashboard.get(\"result\", dashboard)\n position_json = parse_position_json(result.get(\"position_json\", \"{}\"))\n # Remove new MARKDOWN+ROW pair (old CHART-{id} format no longer created)\n remove_banner_from_position(position_json, chart_id)\n\n response = cast(dict, self.network.request(\n method=\"PUT\", endpoint=f\"/dashboard/{dashboard_id}\",\n json={\"position_json\": json.dumps(position_json)},\n ))\n app_logger.reflect(\n \"Banner removed from layout\",\n extra={\"dashboard_id\": dashboard_id},\n )\n return response\n except Exception as e:\n app_logger.explore(\n \"Remove from layout failed\",\n extra={\"dashboard_id\": dashboard_id},\n error=str(e),\n )\n raise\n # #endregion remove_chart_from_layout\n\n # #region delete_chart [C:3] [TYPE Function]\n # @BRIEF Delete a chart from Superset by ID.\n # @PRE chart_id exists.\n # @POST Chart permanently deleted from Superset.\n # @SIDE_EFFECT Destroys chart resource.\n def delete_chart(self, chart_id: int) -> dict:\n with belief_scope(\"SupersetDashboardsWriteMixin.delete_chart\", f\"chart_id={chart_id}\"):\n app_logger.reason(\"Deleting chart\", extra={\"chart_id\": chart_id})\n try:\n response = cast(dict, self.network.request(method=\"DELETE\", endpoint=f\"/chart/{chart_id}\"))\n app_logger.reflect(\"Chart deleted\", extra={\"chart_id\": chart_id})\n return response\n except Exception as e:\n app_logger.explore(\"Delete chart failed\", extra={\"chart_id\": chart_id}, error=str(e))\n raise\n # #endregion delete_chart\n\n # #region update_banner_on_dashboard [C:3] [TYPE Function]\n # @BRIEF Update the content of a native MARKDOWN banner element on a dashboard.\n # @PRE dashboard_id exists. chart_id used for key lookup.\n # @POST MARKDOWN element content updated on dashboard.\n # @SIDE_EFFECT Modifies dashboard layout JSON in Superset.\n def update_banner_on_dashboard(\n self, dashboard_id: int, chart_id: int, content: str\n ) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.update_banner_on_dashboard\",\n f\"dashboard_id={dashboard_id}, chart_id={chart_id}\",\n ):\n app_logger.reason(\n \"Updating banner content on dashboard\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id, \"len\": len(content)},\n )\n try:\n dashboard = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n ))\n result = dashboard.get(\"result\", dashboard)\n position_json = parse_position_json(result.get(\"position_json\", \"{}\"))\n markdown_key = f\"MARKDOWN-banner-{chart_id}\"\n update_banner_markdown_content(position_json, markdown_key, content)\n response = cast(dict, self.network.request(\n method=\"PUT\", endpoint=f\"/dashboard/{dashboard_id}\",\n json={\"position_json\": json.dumps(position_json)},\n ))\n app_logger.reflect(\n \"Banner content updated on dashboard\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n return response\n except Exception as e:\n app_logger.explore(\n \"Update banner content failed\",\n extra={\"dashboard_id\": dashboard_id},\n error=str(e),\n )\n raise\n # #endregion update_banner_on_dashboard\n\n\n # #region get_dashboard_layout [C:3] [TYPE Function]\n # @BRIEF Fetch the position_json layout of a dashboard.\n # @PRE dashboard_id exists.\n # @POST Returns the dashboard layout dict.\n def get_dashboard_layout(self, dashboard_id: int) -> dict:\n with belief_scope(\"SupersetDashboardsWriteMixin.get_dashboard_layout\", f\"dashboard_id={dashboard_id}\"):\n app_logger.reason(\"Fetching layout\", extra={\"dashboard_id\": dashboard_id})\n try:\n dashboard = cast(dict, self.network.request(method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"))\n result = dashboard.get(\"result\", dashboard)\n layout = parse_position_json(result.get(\"position_json\", \"{}\"))\n app_logger.reflect(\"Layout fetched\", extra={\"dashboard_id\": dashboard_id, \"items\": len(layout)})\n return layout\n except Exception as e:\n app_logger.explore(\"Fetch layout failed\", extra={\"dashboard_id\": dashboard_id}, error=str(e))\n raise\n # #endregion get_dashboard_layout\n\n # #region _resolve_markdown_datasource [C:2] [TYPE Function]\n # @BRIEF Find a valid datasource_id for markdown chart creation.\n # @PRE dashboard_id exists.\n # @POST Returns an integer datasource_id.\n def _resolve_markdown_datasource(self, dashboard_id: int) -> int:\n with belief_scope(\"_resolve_markdown_datasource\", f\"dashboard_id={dashboard_id}\"):\n try:\n datasets_response = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}/datasets\"\n ))\n datasets = datasets_response.get(\"result\", [])\n if datasets:\n ds_id = datasets[0].get(\"id\")\n if ds_id:\n return int(ds_id)\n except Exception:\n app_logger.explore(\"Dashboard datasets fetch failed, falling back\",\n extra={\"dashboard_id\": dashboard_id}, error=\"Dashboard datasets endpoint failed\")\n try:\n all_ds = cast(dict, self.network.request(\n method=\"GET\", endpoint=\"/dataset/\",\n params={\"q\": json.dumps({\"columns\": [\"id\"], \"page_size\": 1, \"page\": 0})},\n ))\n ds_list = all_ds.get(\"result\", [])\n if ds_list:\n ds_id = ds_list[0].get(\"id\")\n if ds_id:\n return int(ds_id)\n except Exception:\n app_logger.explore(\"No datasets available\", extra={}, error=\"Global dataset list failed\")\n raise RuntimeError(\"Cannot create markdown chart: no datasets available in Superset.\")\n # #endregion _resolve_markdown_datasource\n\n# #endregion SupersetDashboardsWriteMixin\n# #endregion SupersetDashboardsWriteMixin\n"
+ "body": "# #region SupersetDashboardsWriteMixin [C:4] [TYPE Module] [SEMANTICS superset, dashboard, chart, write, maintenance, banner]\n# @BRIEF Dashboard write mixin for SupersetClient — markdown chart CRUD and layout manipulation for maintenance banners.\n# @LAYER Infrastructure\n# @RELATION DEPENDS_ON -> [SupersetClientBase]\n# @RELATION DEPENDS_ON -> [SupersetChartsMixin]\n# @RELATION DEPENDS_ON -> [LayoutUtils]\n# @SIDE_EFFECT Creates, updates, deletes markdown charts & modifies dashboard layout via Superset API.\n# @DATA_CONTRACT Input: dashboard_id / chart_id / markdown_text → Output: API response dict or chart_id int\n# @INVARIANT All network operations use self.network.request()\n# @RATIONALE Extracted from monolithic superset_client to satisfy INV_7.\n# Uses belief_scope with REASON/REFLECT/EXPLORE markers for all C4 operations per Std.Semantics.Python.\n\nimport json\nfrom typing import Any, cast\n\nfrom ..logger import belief_scope, logger as app_logger\nfrom ._layout_utils import (\n insert_banner_markdown_at_top,\n parse_position_json,\n remove_banner_from_position,\n update_banner_markdown_content,\n)\n\napp_logger = cast(Any, app_logger)\n\n\n# #region SupersetDashboardsWriteMixin [C:4] [TYPE Class]\n# @BRIEF Mixin providing markdown chart CRUD and dashboard layout manipulation for maintenance banners.\n# @RELATION DEPENDS_ON -> [SupersetClientBase]\n# @RELATION DEPENDS_ON -> [SupersetChartsMixin]\nclass SupersetDashboardsWriteMixin:\n \"\"\"Mixin for creating/updating/deleting markdown charts and manipulating dashboard layouts.\"\"\"\n\n # #region create_markdown_chart [C:3] [TYPE Function]\n # @BRIEF Create a markdown chart and return the new chart ID.\n # @PRE dashboard_id exists in Superset. markdown_text not empty.\n # @POST Returns chart_id (int). Chart is NOT yet placed in dashboard layout.\n # @SIDE_EFFECT Creates a new chart resource in Superset.\n # @RELATION CALLS -> [EXT:method:self.network.request]\n def create_markdown_chart(self, dashboard_id: int, markdown_text: str) -> int:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.create_markdown_chart\",\n f\"dashboard_id={dashboard_id}\",\n ):\n app_logger.reason(\n \"Creating markdown chart\",\n extra={\"dashboard_id\": dashboard_id, \"len\": len(markdown_text)},\n )\n datasource_id = self._resolve_markdown_datasource(dashboard_id)\n payload = {\n \"dashboards\": [dashboard_id],\n \"datasource_id\": datasource_id,\n \"datasource_type\": \"table\",\n \"slice_name\": \"Maintenance Banner\",\n \"viz_type\": \"markdown\",\n \"params\": json.dumps({\n \"markdown\": markdown_text,\n \"viz_type\": \"markdown\",\n }),\n }\n try:\n response = cast(dict, self.network.request(\n method=\"POST\", endpoint=\"/chart/\", json=payload\n ))\n chart_id = int(response.get(\"id\") or response.get(\"result\", {}).get(\"id\", 0))\n app_logger.reflect(\"Chart created\", extra={\"chart_id\": chart_id})\n return chart_id\n except Exception as e:\n app_logger.explore(\"Create chart failed\", extra={\"dashboard_id\": dashboard_id}, error=str(e))\n raise\n # #endregion create_markdown_chart\n\n # #region update_markdown_chart [C:3] [TYPE Function]\n # @BRIEF Update the markdown text of an existing markdown chart.\n # @PRE chart_id exists and is a markdown chart.\n # @POST Chart markdown content updated.\n # @SIDE_EFFECT Modifies a chart resource in Superset.\n def update_markdown_chart(self, chart_id: int, markdown_text: str) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.update_markdown_chart\",\n f\"chart_id={chart_id}\",\n ):\n app_logger.reason(\"Updating markdown chart\", extra={\"chart_id\": chart_id, \"len\": len(markdown_text)})\n payload = {\"params\": json.dumps({\"markdown\": markdown_text, \"viz_type\": \"markdown\"})}\n try:\n response = cast(dict, self.network.request(method=\"PUT\", endpoint=f\"/chart/{chart_id}\", json=payload))\n app_logger.reflect(\"Chart updated\", extra={\"chart_id\": chart_id})\n return response\n except Exception as e:\n app_logger.explore(\"Update chart failed\", extra={\"chart_id\": chart_id}, error=str(e))\n raise\n # #endregion update_markdown_chart\n\n # #region update_dashboard_layout [C:4] [TYPE Function]\n # @BRIEF Insert a native MARKDOWN element at (0,0) with full width (12 cols),\n # shift existing charts down. Uses native MARKDOWN for reliable rendering.\n # @PRE dashboard_id exists in Superset. chart_id is used for tracking/DB.\n # @POST MARKDOWN element placed at top; existing items shifted down.\n # @SIDE_EFFECT Modifies dashboard layout JSON.\n def update_dashboard_layout(self, dashboard_id: int, chart_id: int) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.update_dashboard_layout\",\n f\"dashboard_id={dashboard_id}, chart_id={chart_id}\",\n ):\n app_logger.reason(\n \"Updating layout with native MARKDOWN\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n try:\n dashboard = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n ))\n result = dashboard.get(\"result\", dashboard)\n position_json = parse_position_json(result.get(\"position_json\", \"{}\"))\n\n # Use native MARKDOWN element inside a ROW, connected to GRID_ID\n placeholder = \"*Maintenance banner*\"\n insert_banner_markdown_at_top(position_json, chart_id, placeholder)\n\n response = cast(dict, self.network.request(\n method=\"PUT\", endpoint=f\"/dashboard/{dashboard_id}\",\n json={\"position_json\": json.dumps(position_json)},\n ))\n app_logger.reflect(\n \"Layout updated with native MARKDOWN\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n return response\n except Exception as e:\n app_logger.explore(\n \"Layout update failed\",\n extra={\"dashboard_id\": dashboard_id},\n error=str(e),\n )\n raise\n # #endregion update_dashboard_layout\n\n # #region remove_chart_from_layout [C:3] [TYPE Function]\n # @BRIEF Remove banner markdown element from dashboard layout without deleting the chart.\n # @PRE dashboard_id exists. chart_id exists in layout as MARKDOWN-banner-{chart_id}.\n # @POST MARKDOWN element removed from position_json; items shifted up.\n # @SIDE_EFFECT Modifies dashboard layout JSON.\n def remove_chart_from_layout(self, dashboard_id: int, chart_id: int) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.remove_chart_from_layout\",\n f\"dashboard_id={dashboard_id}, chart_id={chart_id}\",\n ):\n app_logger.reason(\n \"Removing banner from layout\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n try:\n dashboard = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n ))\n result = dashboard.get(\"result\", dashboard)\n position_json = parse_position_json(result.get(\"position_json\", \"{}\"))\n # Remove new MARKDOWN+ROW pair (old CHART-{id} format no longer created)\n remove_banner_from_position(position_json, chart_id)\n\n response = cast(dict, self.network.request(\n method=\"PUT\", endpoint=f\"/dashboard/{dashboard_id}\",\n json={\"position_json\": json.dumps(position_json)},\n ))\n app_logger.reflect(\n \"Banner removed from layout\",\n extra={\"dashboard_id\": dashboard_id},\n )\n return response\n except Exception as e:\n app_logger.explore(\n \"Remove from layout failed\",\n extra={\"dashboard_id\": dashboard_id},\n error=str(e),\n )\n raise\n # #endregion remove_chart_from_layout\n\n # #region delete_chart [C:3] [TYPE Function]\n # @BRIEF Delete a chart from Superset by ID.\n # @PRE chart_id exists.\n # @POST Chart permanently deleted from Superset.\n # @SIDE_EFFECT Destroys chart resource.\n def delete_chart(self, chart_id: int) -> dict:\n with belief_scope(\"SupersetDashboardsWriteMixin.delete_chart\", f\"chart_id={chart_id}\"):\n app_logger.reason(\"Deleting chart\", extra={\"chart_id\": chart_id})\n try:\n response = cast(dict, self.network.request(method=\"DELETE\", endpoint=f\"/chart/{chart_id}\"))\n app_logger.reflect(\"Chart deleted\", extra={\"chart_id\": chart_id})\n return response\n except Exception as e:\n app_logger.explore(\"Delete chart failed\", extra={\"chart_id\": chart_id}, error=str(e))\n raise\n # #endregion delete_chart\n\n # #region update_banner_on_dashboard [C:3] [TYPE Function]\n # @BRIEF Update the content of a native MARKDOWN banner element on a dashboard.\n # @PRE dashboard_id exists. chart_id used for key lookup.\n # @POST MARKDOWN element content updated on dashboard.\n # @SIDE_EFFECT Modifies dashboard layout JSON in Superset.\n def update_banner_on_dashboard(\n self, dashboard_id: int, chart_id: int, content: str\n ) -> dict:\n with belief_scope(\n \"SupersetDashboardsWriteMixin.update_banner_on_dashboard\",\n f\"dashboard_id={dashboard_id}, chart_id={chart_id}\",\n ):\n app_logger.reason(\n \"Updating banner content on dashboard\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id, \"len\": len(content)},\n )\n try:\n dashboard = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"\n ))\n result = dashboard.get(\"result\", dashboard)\n position_json = parse_position_json(result.get(\"position_json\", \"{}\"))\n markdown_key = f\"MARKDOWN-banner-{chart_id}\"\n update_banner_markdown_content(position_json, markdown_key, content)\n response = cast(dict, self.network.request(\n method=\"PUT\", endpoint=f\"/dashboard/{dashboard_id}\",\n json={\"position_json\": json.dumps(position_json)},\n ))\n app_logger.reflect(\n \"Banner content updated on dashboard\",\n extra={\"dashboard_id\": dashboard_id, \"chart_id\": chart_id},\n )\n return response\n except Exception as e:\n app_logger.explore(\n \"Update banner content failed\",\n extra={\"dashboard_id\": dashboard_id},\n error=str(e),\n )\n raise\n # #endregion update_banner_on_dashboard\n\n\n # #region get_dashboard_layout [C:3] [TYPE Function]\n # @BRIEF Fetch the position_json layout of a dashboard.\n # @PRE dashboard_id exists.\n # @POST Returns the dashboard layout dict.\n def get_dashboard_layout(self, dashboard_id: int) -> dict:\n with belief_scope(\"SupersetDashboardsWriteMixin.get_dashboard_layout\", f\"dashboard_id={dashboard_id}\"):\n app_logger.reason(\"Fetching layout\", extra={\"dashboard_id\": dashboard_id})\n try:\n dashboard = cast(dict, self.network.request(method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}\"))\n result = dashboard.get(\"result\", dashboard)\n layout = parse_position_json(result.get(\"position_json\", \"{}\"))\n app_logger.reflect(\"Layout fetched\", extra={\"dashboard_id\": dashboard_id, \"items\": len(layout)})\n return layout\n except Exception as e:\n app_logger.explore(\"Fetch layout failed\", extra={\"dashboard_id\": dashboard_id}, error=str(e))\n raise\n # #endregion get_dashboard_layout\n\n # #region _resolve_markdown_datasource [C:2] [TYPE Function]\n # @BRIEF Find a valid datasource_id for markdown chart creation.\n # @PRE dashboard_id exists.\n # @POST Returns an integer datasource_id.\n def _resolve_markdown_datasource(self, dashboard_id: int) -> int:\n with belief_scope(\"_resolve_markdown_datasource\", f\"dashboard_id={dashboard_id}\"):\n try:\n datasets_response = cast(dict, self.network.request(\n method=\"GET\", endpoint=f\"/dashboard/{dashboard_id}/datasets\"\n ))\n datasets = datasets_response.get(\"result\", [])\n if datasets:\n ds_id = datasets[0].get(\"id\")\n if ds_id:\n return int(ds_id)\n except Exception:\n app_logger.explore(\"Dashboard datasets fetch failed, falling back\",\n extra={\"dashboard_id\": dashboard_id}, error=\"Dashboard datasets endpoint failed\")\n try:\n all_ds = cast(dict, self.network.request(\n method=\"GET\", endpoint=\"/dataset/\",\n params={\"q\": json.dumps({\"columns\": [\"id\"], \"page_size\": 1, \"page\": 0})},\n ))\n ds_list = all_ds.get(\"result\", [])\n if ds_list:\n ds_id = ds_list[0].get(\"id\")\n if ds_id:\n return int(ds_id)\n except Exception:\n app_logger.explore(\"No datasets available\", extra={}, error=\"Global dataset list failed\")\n raise RuntimeError(\"Cannot create markdown chart: no datasets available in Superset.\")\n # #endregion _resolve_markdown_datasource\n\n# #endregion SupersetDashboardsWriteMixin\n# #endregion SupersetDashboardsWriteMixin\n"
},
{
"contract_id": "create_markdown_chart",
@@ -25461,14 +25553,14 @@
{
"source_id": "__tests__/test_task_logger",
"relation_type": "BINDS_TO",
- "target_id": "../task_logger.py",
- "target_ref": "../task_logger.py"
+ "target_id": "EXT:path:task_logger",
+ "target_ref": "[EXT:path:task_logger]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region __tests__/test_task_logger [TYPE Module] [SEMANTICS test, task, logger, contract]\n# @RELATION BINDS_TO -> ../task_logger.py\n# @BRIEF Contract testing for TaskLogger\n# #endregion __tests__/test_task_logger\n"
+ "body": "# #region __tests__/test_task_logger [TYPE Module] [SEMANTICS test, task, logger, contract]\n# @RELATION BINDS_TO -> [EXT:path:task_logger]\n# @BRIEF Contract testing for TaskLogger\n# #endregion __tests__/test_task_logger\n"
},
{
"contract_id": "test_task_logger_initialization",
@@ -33707,13 +33799,13 @@
"source_id": "LlmModels",
"relation_type": "INHERITS",
"target_id": "MappingModels",
- "target_ref": "MappingModels:Base"
+ "target_ref": "[MappingModels]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region LlmModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, llm, model, schema, validate, provider]\n# @BRIEF SQLAlchemy models for LLM provider configuration and validation results.\n# @LAYER Domain\n# @RELATION INHERITS -> MappingModels:Base\n\nfrom datetime import datetime\nimport uuid\n\nfrom sqlalchemy import JSON, Boolean, Column, DateTime, String, Text, Time\n\nfrom .mapping import Base\n\n\ndef generate_uuid():\n return str(uuid.uuid4())\n\n# #region ValidationPolicy [TYPE Class]\n# @BRIEF Defines a scheduled rule for validating a group of dashboards within an execution window.\n# @RELATION DEPENDS_ON -> [LLMProvider]\nclass ValidationPolicy(Base):\n __tablename__ = \"validation_policies\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n name = Column(String, nullable=False)\n environment_id = Column(String, nullable=False)\n is_active = Column(Boolean, default=True)\n dashboard_ids = Column(JSON, nullable=False) # Array of dashboard IDs\n provider_id = Column(String, nullable=True) # Reference to LLMProvider.id\n schedule_days = Column(JSON, nullable=False) # Array of integers (0-6)\n window_start = Column(Time, nullable=False)\n window_end = Column(Time, nullable=False)\n notify_owners = Column(Boolean, default=True)\n custom_channels = Column(JSON, nullable=True) # List of external channels\n alert_condition = Column(String, default=\"FAIL_ONLY\") # FAIL_ONLY, WARN_AND_FAIL, ALWAYS\n created_at = Column(DateTime, default=datetime.utcnow)\n updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)\n# #endregion ValidationPolicy\n\n# #region LLMProvider [TYPE Class]\n# @BRIEF SQLAlchemy model for LLM provider configuration.\nclass LLMProvider(Base):\n __tablename__ = \"llm_providers\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n provider_type = Column(String, nullable=False) # openai, openrouter, kilo\n name = Column(String, nullable=False)\n base_url = Column(String, nullable=False)\n api_key = Column(String, nullable=False) # Should be encrypted\n default_model = Column(String, nullable=False)\n is_active = Column(Boolean, default=True)\n is_multimodal = Column(Boolean, default=False)\n created_at = Column(DateTime, default=datetime.utcnow)\n# #endregion LLMProvider\n\n# #region ValidationRecord [TYPE Class]\n# @BRIEF SQLAlchemy model for dashboard validation history.\nclass ValidationRecord(Base):\n __tablename__ = \"llm_validation_results\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n task_id = Column(String, nullable=True, index=True) # Reference to TaskRecord\n policy_id = Column(String, nullable=True, index=True) # Reference to ValidationPolicy.id\n dashboard_id = Column(String, nullable=False, index=True)\n environment_id = Column(String, nullable=True, index=True)\n timestamp = Column(DateTime, default=datetime.utcnow)\n status = Column(String, nullable=False) # PASS, WARN, FAIL, UNKNOWN\n screenshot_path = Column(String, nullable=True)\n issues = Column(JSON, nullable=False)\n summary = Column(Text, nullable=False)\n raw_response = Column(Text, nullable=True)\n# #endregion ValidationRecord\n\n# #endregion LlmModels\n"
+ "body": "# #region LlmModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, llm, model, schema, validate, provider]\n# @BRIEF SQLAlchemy models for LLM provider configuration and validation results.\n# @LAYER Domain\n# @RELATION INHERITS -> [MappingModels]\n\nfrom datetime import datetime\nimport uuid\n\nfrom sqlalchemy import JSON, Boolean, Column, DateTime, String, Text, Time\n\nfrom .mapping import Base\n\n\ndef generate_uuid():\n return str(uuid.uuid4())\n\n# #region ValidationPolicy [TYPE Class]\n# @BRIEF Defines a scheduled rule for validating a group of dashboards within an execution window.\n# @RELATION DEPENDS_ON -> [LLMProvider]\nclass ValidationPolicy(Base):\n __tablename__ = \"validation_policies\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n name = Column(String, nullable=False)\n environment_id = Column(String, nullable=False)\n is_active = Column(Boolean, default=True)\n dashboard_ids = Column(JSON, nullable=False) # Array of dashboard IDs\n provider_id = Column(String, nullable=True) # Reference to LLMProvider.id\n schedule_days = Column(JSON, nullable=False) # Array of integers (0-6)\n window_start = Column(Time, nullable=False)\n window_end = Column(Time, nullable=False)\n notify_owners = Column(Boolean, default=True)\n custom_channels = Column(JSON, nullable=True) # List of external channels\n alert_condition = Column(String, default=\"FAIL_ONLY\") # FAIL_ONLY, WARN_AND_FAIL, ALWAYS\n created_at = Column(DateTime, default=datetime.utcnow)\n updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)\n# #endregion ValidationPolicy\n\n# #region LLMProvider [TYPE Class]\n# @BRIEF SQLAlchemy model for LLM provider configuration.\nclass LLMProvider(Base):\n __tablename__ = \"llm_providers\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n provider_type = Column(String, nullable=False) # openai, openrouter, kilo\n name = Column(String, nullable=False)\n base_url = Column(String, nullable=False)\n api_key = Column(String, nullable=False) # Should be encrypted\n default_model = Column(String, nullable=False)\n is_active = Column(Boolean, default=True)\n is_multimodal = Column(Boolean, default=False)\n created_at = Column(DateTime, default=datetime.utcnow)\n# #endregion LLMProvider\n\n# #region ValidationRecord [TYPE Class]\n# @BRIEF SQLAlchemy model for dashboard validation history.\nclass ValidationRecord(Base):\n __tablename__ = \"llm_validation_results\"\n\n id = Column(String, primary_key=True, default=generate_uuid)\n task_id = Column(String, nullable=True, index=True) # Reference to TaskRecord\n policy_id = Column(String, nullable=True, index=True) # Reference to ValidationPolicy.id\n dashboard_id = Column(String, nullable=False, index=True)\n environment_id = Column(String, nullable=True, index=True)\n timestamp = Column(DateTime, default=datetime.utcnow)\n status = Column(String, nullable=False) # PASS, WARN, FAIL, UNKNOWN\n screenshot_path = Column(String, nullable=True)\n issues = Column(JSON, nullable=False)\n summary = Column(Text, nullable=False)\n raw_response = Column(Text, nullable=True)\n# #endregion ValidationRecord\n\n# #endregion LlmModels\n"
},
{
"contract_id": "ValidationPolicy",
@@ -33797,14 +33889,14 @@
{
"source_id": "MaintenanceModels",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:internal:MappingBase",
- "target_ref": "[EXT:internal:MappingBase]"
+ "target_id": "MappingModels",
+ "target_ref": "[MappingModels]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region MaintenanceModels [C:2] [TYPE Module] [SEMANTICS sqlalchemy, maintenance, banner, event, settings, model]\n# @BRIEF SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]\n# @RELATION DEPENDS_ON -> [EXT:internal:MappingBase]\n# @INVARIANT MaintenanceDashboardBanner has unique partial index on (environment_id, dashboard_id) WHERE status='active'\n# @INVARIANT MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint\n\nimport enum\nimport uuid\n\nfrom sqlalchemy import (\n CheckConstraint,\n Column,\n DateTime,\n Enum as SQLEnum,\n ForeignKey,\n Index,\n Integer,\n JSON,\n String,\n Text,\n)\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy.sql import func\n\nfrom .mapping import Base\n\n\n# #region MaintenanceEventStatus [C:1] [TYPE Class]\nclass MaintenanceEventStatus(str, enum.Enum):\n PENDING = \"pending\"\n APPLYING = \"applying\"\n ACTIVE = \"active\"\n PARTIAL = \"partial\"\n ENDING = \"ending\"\n COMPLETED = \"completed\"\n FAILED = \"failed\"\n# #endregion MaintenanceEventStatus\n\n\n# #region MaintenanceDashboardBannerStatus [C:1] [TYPE Class]\nclass MaintenanceDashboardBannerStatus(str, enum.Enum):\n ACTIVE = \"active\"\n REMOVED = \"removed\"\n# #endregion MaintenanceDashboardBannerStatus\n\n\n# #region MaintenanceDashboardStateStatus [C:1] [TYPE Class]\nclass MaintenanceDashboardStateStatus(str, enum.Enum):\n PENDING_APPLY = \"pending_apply\"\n ACTIVE = \"active\"\n REMOVING = \"removing\"\n REMOVED = \"removed\"\n APPLY_FAILED = \"apply_failed\"\n REMOVAL_FAILED = \"removal_failed\"\n# #endregion MaintenanceDashboardStateStatus\n\n\n# #region DashboardScope [C:1] [TYPE Class]\nclass DashboardScope(str, enum.Enum):\n PUBLISHED_ONLY = \"published_only\"\n DRAFT_ONLY = \"draft_only\"\n ALL = \"all\"\n# #endregion DashboardScope\n\n\n# #region MaintenanceEvent [C:1] [TYPE Class]\n# @BRIEF A record of a maintenance event with table list, time window, status, and linked dashboard states.\n# @RELATION DEPENDS_ON -> [MaintenanceDashboardState]\nclass MaintenanceEvent(Base):\n __tablename__ = \"maintenance_events\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)\n task_id = Column(String, nullable=True, index=True)\n environment_id = Column(String, nullable=False)\n tables = Column(JSON, nullable=False)\n start_time = Column(DateTime(timezone=True), nullable=False)\n end_time = Column(DateTime(timezone=True), nullable=True)\n message = Column(Text, nullable=True)\n status = Column(\n SQLEnum(MaintenanceEventStatus),\n nullable=False,\n default=MaintenanceEventStatus.PENDING,\n index=True,\n )\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n dashboard_states = relationship(\n \"MaintenanceDashboardState\",\n back_populates=\"maintenance_event\",\n cascade=\"all, delete-orphan\",\n )\n# #endregion MaintenanceEvent\n\n\n# #region MaintenanceDashboardBanner [C:1] [TYPE Class]\n# @BRIEF The canonical \"one chart per dashboard\" entity. Unique partial index enforces single active banner per dashboard.\n# @INVARIANT Unique partial index (environment_id, dashboard_id) WHERE status='active'\nclass MaintenanceDashboardBanner(Base):\n __tablename__ = \"maintenance_dashboard_banners\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)\n environment_id = Column(String, nullable=False)\n dashboard_id = Column(Integer, nullable=False, index=True)\n chart_id = Column(Integer, nullable=True)\n banner_text = Column(Text, nullable=True)\n status = Column(\n SQLEnum(MaintenanceDashboardBannerStatus),\n nullable=False,\n default=MaintenanceDashboardBannerStatus.ACTIVE,\n )\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n dashboard_states = relationship(\n \"MaintenanceDashboardState\", back_populates=\"banner\"\n )\n\n __table_args__ = (\n Index(\n \"ix_banner_unique_active\",\n \"environment_id\",\n \"dashboard_id\",\n unique=True,\n postgresql_where=(status == \"active\"),\n ),\n )\n# #endregion MaintenanceDashboardBanner\n\n\n# #region MaintenanceDashboardState [C:1] [TYPE Class]\n# @BRIEF Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.\n# @RELATION DEPENDS_ON -> [MaintenanceEvent]\n# @RELATION DEPENDS_ON -> [MaintenanceDashboardBanner]\nclass MaintenanceDashboardState(Base):\n __tablename__ = \"maintenance_dashboard_states\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)\n event_id = Column(\n String, ForeignKey(\"maintenance_events.id\"), nullable=False, index=True\n )\n dashboard_id = Column(Integer, nullable=False, index=True)\n banner_id = Column(\n String,\n ForeignKey(\"maintenance_dashboard_banners.id\"),\n nullable=True,\n )\n status = Column(\n SQLEnum(MaintenanceDashboardStateStatus),\n nullable=False,\n default=MaintenanceDashboardStateStatus.PENDING_APPLY,\n )\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n maintenance_event = relationship(\n \"MaintenanceEvent\", back_populates=\"dashboard_states\"\n )\n banner = relationship(\n \"MaintenanceDashboardBanner\", back_populates=\"dashboard_states\"\n )\n\n __table_args__ = (\n Index(\"ix_mds_dashboard_status\", \"dashboard_id\", \"status\"),\n )\n# #endregion MaintenanceDashboardState\n\n\n# #region MaintenanceSettings [C:1] [TYPE Class]\n# @BRIEF Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').\n# @INVARIANT id must always be 'default' — enforced by CheckConstraint\nclass MaintenanceSettings(Base):\n __tablename__ = \"maintenance_settings\"\n\n id = Column(String, primary_key=True, default=\"default\")\n target_environment_id = Column(String, nullable=False)\n display_timezone = Column(String, nullable=False, default=\"UTC\")\n banner_template = Column(\n Text,\n nullable=False,\n default=(\n '
\\n\\n'\n \"## ⚠️ Технические работы\\n\\n\"\n \"{message}\\n\\n\"\n \"**Начало:** {start_time}\\n\"\n \"**Конец:** {end_time}\\n\\n\"\n \"*Данные могут быть неполными или временно недоступны.*\\n\\n\"\n \"
\"\n ),\n )\n dashboard_scope = Column(\n SQLEnum(DashboardScope),\n nullable=False,\n default=DashboardScope.PUBLISHED_ONLY,\n )\n excluded_dashboard_ids = Column(JSON, nullable=False, default=list)\n forced_dashboard_ids = Column(JSON, nullable=False, default=list)\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n __table_args__ = (\n CheckConstraint(\"id = 'default'\", name=\"ck_settings_singleton\"),\n )\n# #endregion MaintenanceSettings\n\n# #endregion MaintenanceModels\n"
+ "body": "# #region MaintenanceModels [C:2] [TYPE Module] [SEMANTICS sqlalchemy, maintenance, banner, event, settings, model]\n# @BRIEF SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]\n# @RELATION DEPENDS_ON -> [MappingModels]\n# @INVARIANT MaintenanceDashboardBanner has unique partial index on (environment_id, dashboard_id) WHERE status='active'\n# @INVARIANT MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint\n\nimport enum\nimport uuid\n\nfrom sqlalchemy import (\n CheckConstraint,\n Column,\n DateTime,\n Enum as SQLEnum,\n ForeignKey,\n Index,\n Integer,\n JSON,\n String,\n Text,\n)\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy.sql import func\n\nfrom .mapping import Base\n\n\n# #region MaintenanceEventStatus [C:1] [TYPE Class]\nclass MaintenanceEventStatus(str, enum.Enum):\n PENDING = \"pending\"\n APPLYING = \"applying\"\n ACTIVE = \"active\"\n PARTIAL = \"partial\"\n ENDING = \"ending\"\n COMPLETED = \"completed\"\n FAILED = \"failed\"\n# #endregion MaintenanceEventStatus\n\n\n# #region MaintenanceDashboardBannerStatus [C:1] [TYPE Class]\nclass MaintenanceDashboardBannerStatus(str, enum.Enum):\n ACTIVE = \"active\"\n REMOVED = \"removed\"\n# #endregion MaintenanceDashboardBannerStatus\n\n\n# #region MaintenanceDashboardStateStatus [C:1] [TYPE Class]\nclass MaintenanceDashboardStateStatus(str, enum.Enum):\n PENDING_APPLY = \"pending_apply\"\n ACTIVE = \"active\"\n REMOVING = \"removing\"\n REMOVED = \"removed\"\n APPLY_FAILED = \"apply_failed\"\n REMOVAL_FAILED = \"removal_failed\"\n# #endregion MaintenanceDashboardStateStatus\n\n\n# #region DashboardScope [C:1] [TYPE Class]\nclass DashboardScope(str, enum.Enum):\n PUBLISHED_ONLY = \"published_only\"\n DRAFT_ONLY = \"draft_only\"\n ALL = \"all\"\n# #endregion DashboardScope\n\n\n# #region MaintenanceEvent [C:1] [TYPE Class]\n# @BRIEF A record of a maintenance event with table list, time window, status, and linked dashboard states.\n# @RELATION DEPENDS_ON -> [MaintenanceDashboardState]\nclass MaintenanceEvent(Base):\n __tablename__ = \"maintenance_events\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)\n task_id = Column(String, nullable=True, index=True)\n environment_id = Column(String, nullable=False)\n tables = Column(JSON, nullable=False)\n start_time = Column(DateTime(timezone=True), nullable=False)\n end_time = Column(DateTime(timezone=True), nullable=True)\n message = Column(Text, nullable=True)\n status = Column(\n SQLEnum(MaintenanceEventStatus),\n nullable=False,\n default=MaintenanceEventStatus.PENDING,\n index=True,\n )\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n dashboard_states = relationship(\n \"MaintenanceDashboardState\",\n back_populates=\"maintenance_event\",\n cascade=\"all, delete-orphan\",\n )\n# #endregion MaintenanceEvent\n\n\n# #region MaintenanceDashboardBanner [C:1] [TYPE Class]\n# @BRIEF The canonical \"one chart per dashboard\" entity. Unique partial index enforces single active banner per dashboard.\n# @INVARIANT Unique partial index (environment_id, dashboard_id) WHERE status='active'\nclass MaintenanceDashboardBanner(Base):\n __tablename__ = \"maintenance_dashboard_banners\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)\n environment_id = Column(String, nullable=False)\n dashboard_id = Column(Integer, nullable=False, index=True)\n chart_id = Column(Integer, nullable=True)\n banner_text = Column(Text, nullable=True)\n status = Column(\n SQLEnum(MaintenanceDashboardBannerStatus),\n nullable=False,\n default=MaintenanceDashboardBannerStatus.ACTIVE,\n )\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n dashboard_states = relationship(\n \"MaintenanceDashboardState\", back_populates=\"banner\"\n )\n\n __table_args__ = (\n Index(\n \"ix_banner_unique_active\",\n \"environment_id\",\n \"dashboard_id\",\n unique=True,\n postgresql_where=(status == \"active\"),\n ),\n )\n# #endregion MaintenanceDashboardBanner\n\n\n# #region MaintenanceDashboardState [C:1] [TYPE Class]\n# @BRIEF Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.\n# @RELATION DEPENDS_ON -> [MaintenanceEvent]\n# @RELATION DEPENDS_ON -> [MaintenanceDashboardBanner]\nclass MaintenanceDashboardState(Base):\n __tablename__ = \"maintenance_dashboard_states\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), index=True)\n event_id = Column(\n String, ForeignKey(\"maintenance_events.id\"), nullable=False, index=True\n )\n dashboard_id = Column(Integer, nullable=False, index=True)\n banner_id = Column(\n String,\n ForeignKey(\"maintenance_dashboard_banners.id\"),\n nullable=True,\n )\n status = Column(\n SQLEnum(MaintenanceDashboardStateStatus),\n nullable=False,\n default=MaintenanceDashboardStateStatus.PENDING_APPLY,\n )\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n maintenance_event = relationship(\n \"MaintenanceEvent\", back_populates=\"dashboard_states\"\n )\n banner = relationship(\n \"MaintenanceDashboardBanner\", back_populates=\"dashboard_states\"\n )\n\n __table_args__ = (\n Index(\"ix_mds_dashboard_status\", \"dashboard_id\", \"status\"),\n )\n# #endregion MaintenanceDashboardState\n\n\n# #region MaintenanceSettings [C:1] [TYPE Class]\n# @BRIEF Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').\n# @INVARIANT id must always be 'default' — enforced by CheckConstraint\nclass MaintenanceSettings(Base):\n __tablename__ = \"maintenance_settings\"\n\n id = Column(String, primary_key=True, default=\"default\")\n target_environment_id = Column(String, nullable=False)\n display_timezone = Column(String, nullable=False, default=\"UTC\")\n banner_template = Column(\n Text,\n nullable=False,\n default=(\n '\\n\\n'\n \"## ⚠️ Технические работы\\n\\n\"\n \"{message}\\n\\n\"\n \"**Начало:** {start_time}\\n\"\n \"**Конец:** {end_time}\\n\\n\"\n \"*Данные могут быть неполными или временно недоступны.*\\n\\n\"\n \"
\"\n ),\n )\n dashboard_scope = Column(\n SQLEnum(DashboardScope),\n nullable=False,\n default=DashboardScope.PUBLISHED_ONLY,\n )\n excluded_dashboard_ids = Column(JSON, nullable=False, default=list)\n forced_dashboard_ids = Column(JSON, nullable=False, default=list)\n updated_at = Column(\n DateTime(timezone=True), server_default=func.now(), onupdate=func.now()\n )\n\n __table_args__ = (\n CheckConstraint(\"id = 'default'\", name=\"ck_settings_singleton\"),\n )\n# #endregion MaintenanceSettings\n\n# #endregion MaintenanceModels\n"
},
{
"contract_id": "MaintenanceEventStatus",
@@ -33973,7 +34065,7 @@
"contract_type": "Module",
"file_path": "backend/src/models/mapping.py",
"start_line": 1,
- "end_line": 99,
+ "end_line": 102,
"tier": "TIER_3",
"complexity": 5,
"metadata": {
@@ -33993,14 +34085,32 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region MappingModels [C:5] [TYPE Module] [SEMANTICS sqlalchemy, mapping, model, schema, resource-type]\n#\n# @BRIEF Defines the database schema for environment metadata and database mappings using SQLAlchemy.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]\n\n#\n# @INVARIANT All primary keys are UUID strings.\n# CONSTRAINT: source_env_id and target_env_id must be valid environment IDs.\n# @PRE Database engine initialized\n# @POST Mapping ORM models registered with UUID primary keys\n# @SIDE_EFFECT Defines environment/database/resource mapping tables\n# @DATA_CONTRACT MappingData -> MappingRecord\n\nimport enum\nimport uuid\n\nfrom sqlalchemy import Boolean, Column, DateTime, Enum as SQLEnum, ForeignKey, String\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.sql import func\n\nBase = declarative_base()\n\n# #region ResourceType [C:1] [TYPE Class]\n# @BRIEF Enumeration of possible Superset resource types for ID mapping.\nclass ResourceType(str, enum.Enum):\n CHART = \"chart\"\n DATASET = \"dataset\"\n DASHBOARD = \"dashboard\"\n# #endregion ResourceType\n\n\n# #region MigrationStatus [C:1] [TYPE Class]\n# @BRIEF Enumeration of possible migration job statuses.\nclass MigrationStatus(enum.Enum):\n PENDING = \"PENDING\"\n RUNNING = \"RUNNING\"\n COMPLETED = \"COMPLETED\"\n FAILED = \"FAILED\"\n AWAITING_MAPPING = \"AWAITING_MAPPING\"\n# #endregion MigrationStatus\n\n# #region Environment [C:3] [TYPE Class]\n# @BRIEF Represents a Superset instance environment.\n# @RELATION DEPENDS_ON -> MappingModels\nclass Environment(Base):\n __tablename__ = \"environments\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n name = Column(String, nullable=False)\n url = Column(String, nullable=False)\n credentials_id = Column(String, nullable=False)\n# #endregion Environment\n\n# #region DatabaseMapping [C:3] [TYPE Class]\n# @BRIEF Represents a mapping between source and target databases.\nclass DatabaseMapping(Base):\n __tablename__ = \"database_mappings\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n source_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n target_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n source_db_uuid = Column(String, nullable=False)\n target_db_uuid = Column(String, nullable=False)\n source_db_name = Column(String, nullable=False)\n target_db_name = Column(String, nullable=False)\n engine = Column(String, nullable=True)\n# #endregion DatabaseMapping\n\n# #region MigrationJob [C:2] [TYPE Class]\n# @BRIEF Represents a single migration execution job.\nclass MigrationJob(Base):\n __tablename__ = \"migration_jobs\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n source_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n target_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n status = Column(SQLEnum(MigrationStatus), default=MigrationStatus.PENDING)\n replace_db = Column(Boolean, default=False)\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n# #endregion MigrationJob\n\n# #region ResourceMapping [C:3] [TYPE Class]\n# @BRIEF Maps a universal UUID for a resource to its actual ID on a specific environment.\n# @TEST_DATA: resource_mapping_record -> {'environment_id': 'prod-env-1', 'resource_type': 'chart', 'uuid': '123e4567-e89b-12d3-a456-426614174000', 'remote_integer_id': '42'}\n# @RELATION DEPENDS_ON -> MappingModels\nclass ResourceMapping(Base):\n __tablename__ = \"resource_mappings\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n environment_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n resource_type = Column(SQLEnum(ResourceType), nullable=False)\n uuid = Column(String, nullable=False)\n remote_integer_id = Column(String, nullable=False) # Stored as string to handle potentially large or composite IDs safely, though Superset usually uses integers.\n resource_name = Column(String, nullable=True) # Used for UI display\n last_synced_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())\n# #endregion ResourceMapping\n\n# #endregion MappingModels\n"
+ "body": "# #region MappingModels [C:5] [TYPE Module] [SEMANTICS sqlalchemy, mapping, model, schema, resource-type]\n#\n# @BRIEF Defines the database schema for environment metadata and database mappings using SQLAlchemy.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]\n\n#\n# @INVARIANT All primary keys are UUID strings.\n# CONSTRAINT: source_env_id and target_env_id must be valid environment IDs.\n# @PRE Database engine initialized\n# @POST Mapping ORM models registered with UUID primary keys\n# @SIDE_EFFECT Defines environment/database/resource mapping tables\n# @DATA_CONTRACT MappingData -> MappingRecord\n\nimport enum\nimport uuid\n\nfrom sqlalchemy import Boolean, Column, DateTime, Enum as SQLEnum, ForeignKey, String\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.sql import func\n\n# #region Base [C:1] [TYPE Class]\n# @BRIEF SQLAlchemy declarative base for all domain models.\n# #endregion Base\nBase = declarative_base()\n\n# #region ResourceType [C:1] [TYPE Class]\n# @BRIEF Enumeration of possible Superset resource types for ID mapping.\nclass ResourceType(str, enum.Enum):\n CHART = \"chart\"\n DATASET = \"dataset\"\n DASHBOARD = \"dashboard\"\n# #endregion ResourceType\n\n\n# #region MigrationStatus [C:1] [TYPE Class]\n# @BRIEF Enumeration of possible migration job statuses.\nclass MigrationStatus(enum.Enum):\n PENDING = \"PENDING\"\n RUNNING = \"RUNNING\"\n COMPLETED = \"COMPLETED\"\n FAILED = \"FAILED\"\n AWAITING_MAPPING = \"AWAITING_MAPPING\"\n# #endregion MigrationStatus\n\n# #region Environment [C:3] [TYPE Class]\n# @BRIEF Represents a Superset instance environment.\n# @RELATION DEPENDS_ON -> MappingModels\nclass Environment(Base):\n __tablename__ = \"environments\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n name = Column(String, nullable=False)\n url = Column(String, nullable=False)\n credentials_id = Column(String, nullable=False)\n# #endregion Environment\n\n# #region DatabaseMapping [C:3] [TYPE Class]\n# @BRIEF Represents a mapping between source and target databases.\nclass DatabaseMapping(Base):\n __tablename__ = \"database_mappings\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n source_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n target_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n source_db_uuid = Column(String, nullable=False)\n target_db_uuid = Column(String, nullable=False)\n source_db_name = Column(String, nullable=False)\n target_db_name = Column(String, nullable=False)\n engine = Column(String, nullable=True)\n# #endregion DatabaseMapping\n\n# #region MigrationJob [C:2] [TYPE Class]\n# @BRIEF Represents a single migration execution job.\nclass MigrationJob(Base):\n __tablename__ = \"migration_jobs\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n source_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n target_env_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n status = Column(SQLEnum(MigrationStatus), default=MigrationStatus.PENDING)\n replace_db = Column(Boolean, default=False)\n created_at = Column(DateTime(timezone=True), server_default=func.now())\n# #endregion MigrationJob\n\n# #region ResourceMapping [C:3] [TYPE Class]\n# @BRIEF Maps a universal UUID for a resource to its actual ID on a specific environment.\n# @TEST_DATA: resource_mapping_record -> {'environment_id': 'prod-env-1', 'resource_type': 'chart', 'uuid': '123e4567-e89b-12d3-a456-426614174000', 'remote_integer_id': '42'}\n# @RELATION DEPENDS_ON -> MappingModels\nclass ResourceMapping(Base):\n __tablename__ = \"resource_mappings\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n environment_id = Column(String, ForeignKey(\"environments.id\", ondelete=\"CASCADE\"), nullable=False)\n resource_type = Column(SQLEnum(ResourceType), nullable=False)\n uuid = Column(String, nullable=False)\n remote_integer_id = Column(String, nullable=False) # Stored as string to handle potentially large or composite IDs safely, though Superset usually uses integers.\n resource_name = Column(String, nullable=True) # Used for UI display\n last_synced_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())\n# #endregion ResourceMapping\n\n# #endregion MappingModels\n"
+ },
+ {
+ "contract_id": "Base",
+ "contract_type": "Class",
+ "file_path": "backend/src/models/mapping.py",
+ "start_line": 22,
+ "end_line": 24,
+ "tier": "TIER_1",
+ "complexity": 1,
+ "metadata": {
+ "BRIEF": "SQLAlchemy declarative base for all domain models.",
+ "COMPLEXITY": 1
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "# #region Base [C:1] [TYPE Class]\n# @BRIEF SQLAlchemy declarative base for all domain models.\n# #endregion Base\n"
},
{
"contract_id": "ResourceType",
"contract_type": "Class",
"file_path": "backend/src/models/mapping.py",
- "start_line": 24,
- "end_line": 30,
+ "start_line": 27,
+ "end_line": 33,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -34017,8 +34127,8 @@
"contract_id": "MigrationStatus",
"contract_type": "Class",
"file_path": "backend/src/models/mapping.py",
- "start_line": 33,
- "end_line": 41,
+ "start_line": 36,
+ "end_line": 44,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -34035,8 +34145,8 @@
"contract_id": "MigrationJob",
"contract_type": "Class",
"file_path": "backend/src/models/mapping.py",
- "start_line": 70,
- "end_line": 81,
+ "start_line": 73,
+ "end_line": 84,
"tier": "TIER_1",
"complexity": 2,
"metadata": {
@@ -34053,8 +34163,8 @@
"contract_id": "ResourceMapping",
"contract_type": "Class",
"file_path": "backend/src/models/mapping.py",
- "start_line": 83,
- "end_line": 97,
+ "start_line": 86,
+ "end_line": 100,
"tier": "TIER_2",
"complexity": 3,
"metadata": {
@@ -34103,14 +34213,14 @@
{
"source_id": "ProfileModels",
"relation_type": "INHERITS",
- "target_id": "EXT:internal:MappingModels:Base",
- "target_ref": "[EXT:internal:MappingModels:Base]"
+ "target_id": "MappingModels",
+ "target_ref": "[MappingModels]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region ProfileModels [C:5] [TYPE Module] [SEMANTICS sqlalchemy, profile, model, schema, git, dashboard]\n#\n# @BRIEF Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [AuthModels]\n# @RELATION INHERITS -> [EXT:internal:MappingModels:Base]\n#\n# @INVARIANT Exactly one preference row exists per user_id.\n# @INVARIANT Sensitive Git token is stored encrypted and never returned in plaintext.\n# @PRE Database engine initialized\n# @POST Profile ORM models registered\n# @SIDE_EFFECT Defines user profile/preference tables\n# @DATA_CONTRACT ProfileData -> PreferenceRecord\n\nfrom datetime import datetime\nimport uuid\n\nfrom sqlalchemy import Boolean, Column, DateTime, ForeignKey, String\nfrom sqlalchemy.orm import relationship\n\nfrom .mapping import Base\n\n\n# #region UserDashboardPreference [C:3] [TYPE Class]\n# @BRIEF Stores Superset username binding and default \"my dashboards\" toggle for one authenticated user.\n# @RELATION INHERITS -> MappingModels:Base\nclass UserDashboardPreference(Base):\n __tablename__ = \"user_dashboard_preferences\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n user_id = Column(String, ForeignKey(\"users.id\"), nullable=False, unique=True, index=True)\n\n superset_username = Column(String, nullable=True)\n superset_username_normalized = Column(String, nullable=True, index=True)\n\n show_only_my_dashboards = Column(Boolean, nullable=False, default=False)\n show_only_slug_dashboards = Column(Boolean, nullable=False, default=True)\n\n git_username = Column(String, nullable=True)\n git_email = Column(String, nullable=True)\n git_personal_access_token_encrypted = Column(String, nullable=True)\n\n start_page = Column(String, nullable=False, default=\"dashboards\")\n auto_open_task_drawer = Column(Boolean, nullable=False, default=True)\n dashboards_table_density = Column(String, nullable=False, default=\"comfortable\")\n\n telegram_id = Column(String, nullable=True)\n email_address = Column(String, nullable=True)\n notify_on_fail = Column(Boolean, nullable=False, default=True)\n\n created_at = Column(DateTime, nullable=False, default=datetime.utcnow)\n updated_at = Column(\n DateTime,\n nullable=False,\n default=datetime.utcnow,\n onupdate=datetime.utcnow,\n )\n\n user = relationship(\"User\")\n# #endregion UserDashboardPreference\n\n# #endregion ProfileModels\n"
+ "body": "# #region ProfileModels [C:5] [TYPE Module] [SEMANTICS sqlalchemy, profile, model, schema, git, dashboard]\n#\n# @BRIEF Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [AuthModels]\n# @RELATION INHERITS -> [MappingModels]\n#\n# @INVARIANT Exactly one preference row exists per user_id.\n# @INVARIANT Sensitive Git token is stored encrypted and never returned in plaintext.\n# @PRE Database engine initialized\n# @POST Profile ORM models registered\n# @SIDE_EFFECT Defines user profile/preference tables\n# @DATA_CONTRACT ProfileData -> PreferenceRecord\n\nfrom datetime import datetime\nimport uuid\n\nfrom sqlalchemy import Boolean, Column, DateTime, ForeignKey, String\nfrom sqlalchemy.orm import relationship\n\nfrom .mapping import Base\n\n\n# #region UserDashboardPreference [C:3] [TYPE Class]\n# @BRIEF Stores Superset username binding and default \"my dashboards\" toggle for one authenticated user.\n# @RELATION INHERITS -> [MappingModels]\nclass UserDashboardPreference(Base):\n __tablename__ = \"user_dashboard_preferences\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n user_id = Column(String, ForeignKey(\"users.id\"), nullable=False, unique=True, index=True)\n\n superset_username = Column(String, nullable=True)\n superset_username_normalized = Column(String, nullable=True, index=True)\n\n show_only_my_dashboards = Column(Boolean, nullable=False, default=False)\n show_only_slug_dashboards = Column(Boolean, nullable=False, default=True)\n\n git_username = Column(String, nullable=True)\n git_email = Column(String, nullable=True)\n git_personal_access_token_encrypted = Column(String, nullable=True)\n\n start_page = Column(String, nullable=False, default=\"dashboards\")\n auto_open_task_drawer = Column(Boolean, nullable=False, default=True)\n dashboards_table_density = Column(String, nullable=False, default=\"comfortable\")\n\n telegram_id = Column(String, nullable=True)\n email_address = Column(String, nullable=True)\n notify_on_fail = Column(Boolean, nullable=False, default=True)\n\n created_at = Column(DateTime, nullable=False, default=datetime.utcnow)\n updated_at = Column(\n DateTime,\n nullable=False,\n default=datetime.utcnow,\n onupdate=datetime.utcnow,\n )\n\n user = relationship(\"User\")\n# #endregion UserDashboardPreference\n\n# #endregion ProfileModels\n"
},
{
"contract_id": "UserDashboardPreference",
@@ -34129,13 +34239,13 @@
"source_id": "UserDashboardPreference",
"relation_type": "INHERITS",
"target_id": "MappingModels",
- "target_ref": "MappingModels:Base"
+ "target_ref": "[MappingModels]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region UserDashboardPreference [C:3] [TYPE Class]\n# @BRIEF Stores Superset username binding and default \"my dashboards\" toggle for one authenticated user.\n# @RELATION INHERITS -> MappingModels:Base\nclass UserDashboardPreference(Base):\n __tablename__ = \"user_dashboard_preferences\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n user_id = Column(String, ForeignKey(\"users.id\"), nullable=False, unique=True, index=True)\n\n superset_username = Column(String, nullable=True)\n superset_username_normalized = Column(String, nullable=True, index=True)\n\n show_only_my_dashboards = Column(Boolean, nullable=False, default=False)\n show_only_slug_dashboards = Column(Boolean, nullable=False, default=True)\n\n git_username = Column(String, nullable=True)\n git_email = Column(String, nullable=True)\n git_personal_access_token_encrypted = Column(String, nullable=True)\n\n start_page = Column(String, nullable=False, default=\"dashboards\")\n auto_open_task_drawer = Column(Boolean, nullable=False, default=True)\n dashboards_table_density = Column(String, nullable=False, default=\"comfortable\")\n\n telegram_id = Column(String, nullable=True)\n email_address = Column(String, nullable=True)\n notify_on_fail = Column(Boolean, nullable=False, default=True)\n\n created_at = Column(DateTime, nullable=False, default=datetime.utcnow)\n updated_at = Column(\n DateTime,\n nullable=False,\n default=datetime.utcnow,\n onupdate=datetime.utcnow,\n )\n\n user = relationship(\"User\")\n# #endregion UserDashboardPreference\n"
+ "body": "# #region UserDashboardPreference [C:3] [TYPE Class]\n# @BRIEF Stores Superset username binding and default \"my dashboards\" toggle for one authenticated user.\n# @RELATION INHERITS -> [MappingModels]\nclass UserDashboardPreference(Base):\n __tablename__ = \"user_dashboard_preferences\"\n\n id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))\n user_id = Column(String, ForeignKey(\"users.id\"), nullable=False, unique=True, index=True)\n\n superset_username = Column(String, nullable=True)\n superset_username_normalized = Column(String, nullable=True, index=True)\n\n show_only_my_dashboards = Column(Boolean, nullable=False, default=False)\n show_only_slug_dashboards = Column(Boolean, nullable=False, default=True)\n\n git_username = Column(String, nullable=True)\n git_email = Column(String, nullable=True)\n git_personal_access_token_encrypted = Column(String, nullable=True)\n\n start_page = Column(String, nullable=False, default=\"dashboards\")\n auto_open_task_drawer = Column(Boolean, nullable=False, default=True)\n dashboards_table_density = Column(String, nullable=False, default=\"comfortable\")\n\n telegram_id = Column(String, nullable=True)\n email_address = Column(String, nullable=True)\n notify_on_fail = Column(Boolean, nullable=False, default=True)\n\n created_at = Column(DateTime, nullable=False, default=datetime.utcnow)\n updated_at = Column(\n DateTime,\n nullable=False,\n default=datetime.utcnow,\n onupdate=datetime.utcnow,\n )\n\n user = relationship(\"User\")\n# #endregion UserDashboardPreference\n"
},
{
"contract_id": "ReportModels",
@@ -34929,8 +35039,8 @@
{
"source_id": "GitPluginModule",
"relation_type": "INHERITS",
- "target_id": "EXT:path:src.core.plugin_base.PluginBase",
- "target_ref": "[EXT:path:src.core.plugin_base.PluginBase]"
+ "target_id": "PluginBase",
+ "target_ref": "[PluginBase]"
},
{
"source_id": "GitPluginModule",
@@ -34960,7 +35070,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region GitPluginModule [C:4] [TYPE Module] [SEMANTICS git, versioning, deploy, sync, superset, backup, transactional]\n#\n# @BRIEF Предоставляет плагин для версионирования и развертывания дашбордов Superset.\n# @LAYER Plugin\n# @RELATION INHERITS -> [EXT:path:src.core.plugin_base.PluginBase]\n# @RELATION DEPENDS_ON -> [GitService]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @RELATION DEPENDS_ON -> [TaskContext]\n#\n# @INVARIANT Все операции с Git должны выполняться через GitService.\n# @CONSTRAINT: Плагин работает только с распакованными YAML-экспортами Superset.\n# @INVARIANT _handle_sync сохраняет backup управляемых директорий перед удалением;\n# при ошибке распаковки backup восстанавливается.\n\nimport io\nimport os\nfrom pathlib import Path\nimport shutil\nimport time\nfrom typing import Any\nimport zipfile\n\nfrom src.core.config_manager import ConfigManager\nfrom src.core.logger import belief_scope, logger as app_logger\nfrom src.core.plugin_base import PluginBase\nfrom src.core.superset_client import SupersetClient\nfrom src.core.task_manager.context import TaskContext\nfrom src.services.git_service import GitService\n\n\n# #region GitPlugin [TYPE Class]\n# @BRIEF Реализация плагина Git Integration для управления версиями дашбордов.\nclass GitPlugin(PluginBase):\n\n # region __init__ [TYPE Function]\n # @PURPOSE: Инициализирует плагин и его зависимости.\n # @PRE shared config_manager доступен через src.dependencies.\n # @POST Инициализированы git_service и config_manager.\n def __init__(self):\n with belief_scope(\"GitPlugin.__init__\"):\n app_logger.info(\"Initializing GitPlugin.\")\n self.git_service = GitService()\n\n # Используем shared config_manager из dependencies\n try:\n from src.dependencies import config_manager\n self.config_manager = config_manager\n app_logger.info(\"GitPlugin initialized using shared config_manager.\")\n except Exception as exc:\n app_logger.error(f\"GitPlugin: failed to get shared config_manager: {exc}\")\n self.config_manager = ConfigManager()\n app_logger.info(\"GitPlugin initialized with fallback ConfigManager.\")\n # endregion __init__\n\n @property\n # region id [C:1] [TYPE Function]\n def id(self) -> str:\n return \"git-integration\"\n # endregion id\n\n @property\n # region name [C:1] [TYPE Function]\n def name(self) -> str:\n return \"Git Integration\"\n # endregion name\n\n @property\n # region description [C:1] [TYPE Function]\n def description(self) -> str:\n return \"Version control for Superset dashboards\"\n # endregion description\n\n @property\n # region version [C:1] [TYPE Function]\n def version(self) -> str:\n return \"0.1.0\"\n # endregion version\n\n @property\n # region ui_route [C:1] [TYPE Function]\n def ui_route(self) -> str:\n return \"/git\"\n # endregion ui_route\n\n # region get_schema [TYPE Function]\n # @PURPOSE: Возвращает JSON-схему параметров для выполнения задач плагина.\n # @PRE GitPlugin is initialized.\n # @POST Returns a JSON schema dictionary.\n # @RETURN Dict[str, Any] - Схема параметров.\n def get_schema(self) -> dict[str, Any]:\n with belief_scope(\"GitPlugin.get_schema\"):\n return {\n \"type\": \"object\",\n \"properties\": {\n \"operation\": {\"type\": \"string\", \"enum\": [\"sync\", \"deploy\", \"history\"]},\n \"dashboard_id\": {\"type\": \"integer\"},\n \"environment_id\": {\"type\": \"string\"},\n \"source_env_id\": {\"type\": \"string\"}\n },\n \"required\": [\"operation\", \"dashboard_id\"]\n }\n # endregion get_schema\n\n # region initialize [C:1] [TYPE Function]\n async def initialize(self):\n app_logger.reason(\"Initializing Git Integration Plugin logic.\", extra={\"src\": \"GitPlugin.initialize\"})\n # endregion initialize\n\n # region execute [C:3] [TYPE Function]\n # @PURPOSE: Main task executor with TaskContext support.\n # @RELATION CALLS -> self._handle_sync\n # @RELATION CALLS -> self._handle_deploy\n async def execute(self, task_data: dict[str, Any], context: TaskContext | None = None) -> dict[str, Any]:\n with belief_scope(\"GitPlugin.execute\"):\n operation = task_data.get(\"operation\")\n dashboard_id = task_data.get(\"dashboard_id\")\n\n # Use TaskContext logger if available, otherwise fall back to app_logger\n log = context.logger if context else app_logger\n\n # Create sub-loggers for different components\n git_log = log.with_source(\"git\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing operation: {operation} for dashboard {dashboard_id}\")\n\n if operation == \"sync\":\n source_env_id = task_data.get(\"source_env_id\")\n result = await self._handle_sync(dashboard_id, source_env_id, log, git_log, superset_log)\n elif operation == \"deploy\":\n env_id = task_data.get(\"environment_id\")\n result = await self._handle_deploy(dashboard_id, env_id, log, git_log, superset_log)\n elif operation == \"history\":\n result = {\"status\": \"success\", \"message\": \"History available via API\"}\n else:\n log.error(f\"Unknown operation: {operation}\")\n raise ValueError(f\"Unknown operation: {operation}\")\n\n log.info(f\"Operation {operation} completed.\")\n return result\n # endregion execute\n\n # region _handle_sync [C:4] [TYPE Function] [SEMANTICS git,sync,backup,transactional]\n # @PURPOSE: Экспортирует дашборд из Superset и распаковывает в Git-репозиторий с backup/restore.\n # @PRE Репозиторий для дашборда должен существовать.\n # @POST Файлы в репозитории обновлены до текущего состояния в Superset.\n # Управляемые директории backup-ируются перед удалением; при ошибке распаковки backup восстанавливается.\n # @SIDE_EFFECT Изменяет файлы в локальной рабочей директории репозитория.\n # Создаёт временный backup в /tmp/ss-tools-backup-{dashboard_id}-{timestamp}/.\n # @RETURN Dict[str, str] - Результат синхронизации.\n # @RELATION CALLS -> src.services.git_service.GitService.get_repo\n # @RELATION CALLS -> src.core.superset_client.SupersetClient.export_dashboard\n async def _handle_sync(self, dashboard_id: int, source_env_id: str | None = None, log=None, git_log=None, superset_log=None) -> dict[str, str]:\n with belief_scope(\"GitPlugin._handle_sync\"):\n try:\n repo = self.git_service.get_repo(dashboard_id)\n repo_path = Path(repo.working_dir)\n git_log.info(f\"Target repo path: {repo_path}\")\n\n env = self._get_env(source_env_id)\n client = SupersetClient(env)\n client.authenticate()\n\n superset_log.info(f\"Exporting dashboard {dashboard_id} from {env.name}\")\n zip_bytes, _ = client.export_dashboard(dashboard_id)\n\n git_log.info(f\"Unpacking export to {repo_path}\")\n\n managed_dirs = [\"dashboards\", \"charts\", \"datasets\", \"databases\"]\n managed_files = [\"metadata.yaml\"]\n\n # Fix 1: Create backup before deleting managed files\n backup_dir = Path(f\"/tmp/ss-tools-backup-{dashboard_id}-{time.time_ns()}\")\n for d in managed_dirs:\n d_path = repo_path / d\n if d_path.exists() and d_path.is_dir():\n shutil.copytree(d_path, backup_dir / d)\n for f in managed_files:\n f_path = repo_path / f\n if f_path.exists():\n (backup_dir / f).parent.mkdir(parents=True, exist_ok=True)\n shutil.copy2(f_path, backup_dir / f)\n\n # Delete old managed files\n for d in managed_dirs:\n d_path = repo_path / d\n if d_path.exists() and d_path.is_dir():\n shutil.rmtree(d_path)\n for f in managed_files:\n f_path = repo_path / f\n if f_path.exists():\n f_path.unlink()\n\n try:\n with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf:\n namelist = zf.namelist()\n if not namelist:\n raise ValueError(\"Export ZIP is empty\")\n root_folder = namelist[0].split('/')[0]\n git_log.info(f\"Detected root folder in ZIP: {root_folder}\")\n for member in zf.infolist():\n if member.filename.startswith(root_folder + \"/\") and len(member.filename) > len(root_folder) + 1:\n relative_path = member.filename[len(root_folder)+1:]\n target_path = repo_path / relative_path\n if member.is_dir():\n target_path.mkdir(parents=True, exist_ok=True)\n else:\n target_path.parent.mkdir(parents=True, exist_ok=True)\n with zf.open(member) as source, open(target_path, \"wb\") as target:\n shutil.copyfileobj(source, target)\n except Exception:\n # Fix 1: Restore backup on unzip failure\n if backup_dir.exists():\n for d in managed_dirs:\n src = backup_dir / d\n if src.exists():\n dst = repo_path / d\n if dst.exists():\n shutil.rmtree(dst)\n shutil.copytree(src, dst)\n for f in managed_files:\n src = backup_dir / f\n if src.exists():\n dst = repo_path / f\n dst.parent.mkdir(parents=True, exist_ok=True)\n shutil.copy2(src, dst)\n raise\n\n # Fix 1: Remove backup on success\n if backup_dir.exists():\n shutil.rmtree(backup_dir, ignore_errors=True)\n\n try:\n repo.git.add(A=True)\n app_logger.reason(\"Changes staged in git\", extra={\"src\": \"_handle_sync\"})\n except Exception as ge:\n app_logger.explore(f\"Failed to stage changes: {ge}\", extra={\"src\": \"_handle_sync\"})\n\n app_logger.info(f\"[_handle_sync][Coherence:OK] Dashboard {dashboard_id} synced successfully.\")\n return {\"status\": \"success\", \"message\": \"Dashboard synced and flattened in local repository\"}\n\n except Exception as e:\n app_logger.error(f\"[_handle_sync][Coherence:Failed] Sync failed: {e}\")\n raise\n # endregion _handle_sync\n\n # region _handle_deploy [C:4] [TYPE Function] [SEMANTICS git,deploy,zip]\n # @PURPOSE: Packages repository into ZIP and imports into target Superset environment.\n # @POST Dashboard imported into target Superset.\n # @SIDE_EFFECT Creates and removes temporary ZIP file.\n # @RELATION CALLS -> src.core.superset_client.SupersetClient.import_dashboard\n async def _handle_deploy(self, dashboard_id: int, env_id: str, log=None, git_log=None, superset_log=None) -> dict[str, Any]:\n with belief_scope(\"GitPlugin._handle_deploy\"):\n try:\n if not env_id:\n raise ValueError(\"Target environment ID required for deployment\")\n repo = self.git_service.get_repo(dashboard_id)\n repo_path = Path(repo.working_dir)\n git_log.info(f\"Packing repository {repo_path} for deployment.\")\n zip_buffer = io.BytesIO()\n root_dir_name = f\"dashboard_export_{dashboard_id}\"\n with zipfile.ZipFile(zip_buffer, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(repo_path):\n if \".git\" in dirs:\n dirs.remove(\".git\")\n for file in files:\n if file == \".git\" or file.endswith(\".zip\"):\n continue\n file_path = Path(root) / file\n arcname = Path(root_dir_name) / file_path.relative_to(repo_path)\n zf.write(file_path, arcname)\n zip_buffer.seek(0)\n env = self.config_manager.get_environment(env_id)\n if not env:\n raise ValueError(f\"Environment {env_id} not found\")\n client = SupersetClient(env)\n client.authenticate()\n temp_zip_path = repo_path / f\"deploy_{dashboard_id}.zip\"\n git_log.info(f\"Saving temporary zip to {temp_zip_path}\")\n with open(temp_zip_path, \"wb\") as f:\n f.write(zip_buffer.getvalue())\n\n try:\n app_logger.reason(f\"Importing dashboard to {env.name}\", extra={\"src\": \"_handle_deploy\"})\n result = client.import_dashboard(temp_zip_path)\n app_logger.info(f\"[_handle_deploy][Coherence:OK] Deployment successful for dashboard {dashboard_id}.\")\n return {\"status\": \"success\", \"message\": f\"Dashboard deployed to {env.name}\", \"details\": result}\n finally:\n if temp_zip_path.exists():\n os.remove(temp_zip_path)\n\n except Exception as e:\n app_logger.error(f\"[_handle_deploy][Coherence:Failed] Deployment failed: {e}\")\n raise\n # endregion _handle_deploy\n\n # region _get_env [C:4] [TYPE Function] [SEMANTICS env,config,strict]\n # @PURPOSE: Вспомогательный метод для получения конфигурации окружения.\n # @PARAM env_id (Optional[str]) - ID окружения.\n # @PRE env_id is a string or None.\n # @POST Returns an Environment object from config or DB.\n # When env_id is explicitly provided and not found, raises ValueError (no fallback).\n # @RETURN Environment - Объект конфигурации окружения.\n def _get_env(self, env_id: str | None = None):\n with belief_scope(\"GitPlugin._get_env\"):\n app_logger.reason(f\"Fetching environment for ID: {env_id}\", extra={\"src\": \"_get_env\"})\n\n # Priority 1: ConfigManager (config.json)\n if env_id:\n env = self.config_manager.get_environment(env_id)\n if env:\n app_logger.reflect(f\"Found environment by ID in ConfigManager: {env.name}\", extra={\"src\": \"_get_env\"})\n return env\n\n # Priority 2: Database (DeploymentEnvironment)\n from src.core.database import SessionLocal\n from src.models.git import DeploymentEnvironment\n\n db = SessionLocal()\n try:\n if env_id:\n db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.id == env_id).first()\n else:\n db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.is_active).first()\n if not db_env:\n db_env = db.query(DeploymentEnvironment).first()\n\n if db_env:\n app_logger.reflect(f\"Found environment in DB: {db_env.name}\", extra={\"src\": \"_get_env\"})\n from src.core.config_models import Environment\n return Environment(\n id=db_env.id,\n name=db_env.name,\n url=db_env.superset_url,\n username=\"admin\",\n password=db_env.superset_token,\n verify_ssl=True\n )\n\n # Fix 7: Strict check — if env_id was explicitly provided but not found, raise immediately\n if env_id:\n raise ValueError(f\"Environment '{env_id}' not found in ConfigManager or database\")\n finally:\n db.close()\n\n # Priority 3: fallback to first env only when no specific env_id was requested\n envs = self.config_manager.get_environments()\n if envs and not env_id:\n app_logger.reflect(f\"Using first environment from ConfigManager: {envs[0].name}\", extra={\"src\": \"_get_env\"})\n return envs[0]\n\n app_logger.error(f\"[_get_env][Coherence:Failed] No environments configured (searched config.json and DB). env_id={env_id}\")\n raise ValueError(\"No environments configured. Please add a Superset Environment in Settings.\")\n # endregion _get_env\n\n# #endregion GitPlugin\n# #endregion GitPluginModule\n"
+ "body": "# #region GitPluginModule [C:4] [TYPE Module] [SEMANTICS git, versioning, deploy, sync, superset, backup, transactional]\n#\n# @BRIEF Предоставляет плагин для версионирования и развертывания дашбордов Superset.\n# @LAYER Plugin\n# @RELATION INHERITS -> [PluginBase]\n# @RELATION DEPENDS_ON -> [GitService]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @RELATION DEPENDS_ON -> [TaskContext]\n#\n# @INVARIANT Все операции с Git должны выполняться через GitService.\n# @CONSTRAINT: Плагин работает только с распакованными YAML-экспортами Superset.\n# @INVARIANT _handle_sync сохраняет backup управляемых директорий перед удалением;\n# при ошибке распаковки backup восстанавливается.\n\nimport io\nimport os\nfrom pathlib import Path\nimport shutil\nimport time\nfrom typing import Any\nimport zipfile\n\nfrom src.core.config_manager import ConfigManager\nfrom src.core.logger import belief_scope, logger as app_logger\nfrom src.core.plugin_base import PluginBase\nfrom src.core.superset_client import SupersetClient\nfrom src.core.task_manager.context import TaskContext\nfrom src.services.git_service import GitService\n\n\n# #region GitPlugin [TYPE Class]\n# @BRIEF Реализация плагина Git Integration для управления версиями дашбордов.\nclass GitPlugin(PluginBase):\n\n # region __init__ [TYPE Function]\n # @PURPOSE: Инициализирует плагин и его зависимости.\n # @PRE shared config_manager доступен через src.dependencies.\n # @POST Инициализированы git_service и config_manager.\n def __init__(self):\n with belief_scope(\"GitPlugin.__init__\"):\n app_logger.info(\"Initializing GitPlugin.\")\n self.git_service = GitService()\n\n # Используем shared config_manager из dependencies\n try:\n from src.dependencies import config_manager\n self.config_manager = config_manager\n app_logger.info(\"GitPlugin initialized using shared config_manager.\")\n except Exception as exc:\n app_logger.error(f\"GitPlugin: failed to get shared config_manager: {exc}\")\n self.config_manager = ConfigManager()\n app_logger.info(\"GitPlugin initialized with fallback ConfigManager.\")\n # endregion __init__\n\n @property\n # region id [C:1] [TYPE Function]\n def id(self) -> str:\n return \"git-integration\"\n # endregion id\n\n @property\n # region name [C:1] [TYPE Function]\n def name(self) -> str:\n return \"Git Integration\"\n # endregion name\n\n @property\n # region description [C:1] [TYPE Function]\n def description(self) -> str:\n return \"Version control for Superset dashboards\"\n # endregion description\n\n @property\n # region version [C:1] [TYPE Function]\n def version(self) -> str:\n return \"0.1.0\"\n # endregion version\n\n @property\n # region ui_route [C:1] [TYPE Function]\n def ui_route(self) -> str:\n return \"/git\"\n # endregion ui_route\n\n # region get_schema [TYPE Function]\n # @PURPOSE: Возвращает JSON-схему параметров для выполнения задач плагина.\n # @PRE GitPlugin is initialized.\n # @POST Returns a JSON schema dictionary.\n # @RETURN Dict[str, Any] - Схема параметров.\n def get_schema(self) -> dict[str, Any]:\n with belief_scope(\"GitPlugin.get_schema\"):\n return {\n \"type\": \"object\",\n \"properties\": {\n \"operation\": {\"type\": \"string\", \"enum\": [\"sync\", \"deploy\", \"history\"]},\n \"dashboard_id\": {\"type\": \"integer\"},\n \"environment_id\": {\"type\": \"string\"},\n \"source_env_id\": {\"type\": \"string\"}\n },\n \"required\": [\"operation\", \"dashboard_id\"]\n }\n # endregion get_schema\n\n # region initialize [C:1] [TYPE Function]\n async def initialize(self):\n app_logger.reason(\"Initializing Git Integration Plugin logic.\", extra={\"src\": \"GitPlugin.initialize\"})\n # endregion initialize\n\n # region execute [C:3] [TYPE Function]\n # @PURPOSE: Main task executor with TaskContext support.\n # @RELATION CALLS -> self._handle_sync\n # @RELATION CALLS -> self._handle_deploy\n async def execute(self, task_data: dict[str, Any], context: TaskContext | None = None) -> dict[str, Any]:\n with belief_scope(\"GitPlugin.execute\"):\n operation = task_data.get(\"operation\")\n dashboard_id = task_data.get(\"dashboard_id\")\n\n # Use TaskContext logger if available, otherwise fall back to app_logger\n log = context.logger if context else app_logger\n\n # Create sub-loggers for different components\n git_log = log.with_source(\"git\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing operation: {operation} for dashboard {dashboard_id}\")\n\n if operation == \"sync\":\n source_env_id = task_data.get(\"source_env_id\")\n result = await self._handle_sync(dashboard_id, source_env_id, log, git_log, superset_log)\n elif operation == \"deploy\":\n env_id = task_data.get(\"environment_id\")\n result = await self._handle_deploy(dashboard_id, env_id, log, git_log, superset_log)\n elif operation == \"history\":\n result = {\"status\": \"success\", \"message\": \"History available via API\"}\n else:\n log.error(f\"Unknown operation: {operation}\")\n raise ValueError(f\"Unknown operation: {operation}\")\n\n log.info(f\"Operation {operation} completed.\")\n return result\n # endregion execute\n\n # region _handle_sync [C:4] [TYPE Function] [SEMANTICS git,sync,backup,transactional]\n # @PURPOSE: Экспортирует дашборд из Superset и распаковывает в Git-репозиторий с backup/restore.\n # @PRE Репозиторий для дашборда должен существовать.\n # @POST Файлы в репозитории обновлены до текущего состояния в Superset.\n # Управляемые директории backup-ируются перед удалением; при ошибке распаковки backup восстанавливается.\n # @SIDE_EFFECT Изменяет файлы в локальной рабочей директории репозитория.\n # Создаёт временный backup в /tmp/ss-tools-backup-{dashboard_id}-{timestamp}/.\n # @RETURN Dict[str, str] - Результат синхронизации.\n # @RELATION CALLS -> src.services.git_service.GitService.get_repo\n # @RELATION CALLS -> src.core.superset_client.SupersetClient.export_dashboard\n async def _handle_sync(self, dashboard_id: int, source_env_id: str | None = None, log=None, git_log=None, superset_log=None) -> dict[str, str]:\n with belief_scope(\"GitPlugin._handle_sync\"):\n try:\n repo = self.git_service.get_repo(dashboard_id)\n repo_path = Path(repo.working_dir)\n git_log.info(f\"Target repo path: {repo_path}\")\n\n env = self._get_env(source_env_id)\n client = SupersetClient(env)\n client.authenticate()\n\n superset_log.info(f\"Exporting dashboard {dashboard_id} from {env.name}\")\n zip_bytes, _ = client.export_dashboard(dashboard_id)\n\n git_log.info(f\"Unpacking export to {repo_path}\")\n\n managed_dirs = [\"dashboards\", \"charts\", \"datasets\", \"databases\"]\n managed_files = [\"metadata.yaml\"]\n\n # Fix 1: Create backup before deleting managed files\n backup_dir = Path(f\"/tmp/ss-tools-backup-{dashboard_id}-{time.time_ns()}\")\n for d in managed_dirs:\n d_path = repo_path / d\n if d_path.exists() and d_path.is_dir():\n shutil.copytree(d_path, backup_dir / d)\n for f in managed_files:\n f_path = repo_path / f\n if f_path.exists():\n (backup_dir / f).parent.mkdir(parents=True, exist_ok=True)\n shutil.copy2(f_path, backup_dir / f)\n\n # Delete old managed files\n for d in managed_dirs:\n d_path = repo_path / d\n if d_path.exists() and d_path.is_dir():\n shutil.rmtree(d_path)\n for f in managed_files:\n f_path = repo_path / f\n if f_path.exists():\n f_path.unlink()\n\n try:\n with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf:\n namelist = zf.namelist()\n if not namelist:\n raise ValueError(\"Export ZIP is empty\")\n root_folder = namelist[0].split('/')[0]\n git_log.info(f\"Detected root folder in ZIP: {root_folder}\")\n for member in zf.infolist():\n if member.filename.startswith(root_folder + \"/\") and len(member.filename) > len(root_folder) + 1:\n relative_path = member.filename[len(root_folder)+1:]\n target_path = repo_path / relative_path\n if member.is_dir():\n target_path.mkdir(parents=True, exist_ok=True)\n else:\n target_path.parent.mkdir(parents=True, exist_ok=True)\n with zf.open(member) as source, open(target_path, \"wb\") as target:\n shutil.copyfileobj(source, target)\n except Exception:\n # Fix 1: Restore backup on unzip failure\n if backup_dir.exists():\n for d in managed_dirs:\n src = backup_dir / d\n if src.exists():\n dst = repo_path / d\n if dst.exists():\n shutil.rmtree(dst)\n shutil.copytree(src, dst)\n for f in managed_files:\n src = backup_dir / f\n if src.exists():\n dst = repo_path / f\n dst.parent.mkdir(parents=True, exist_ok=True)\n shutil.copy2(src, dst)\n raise\n\n # Fix 1: Remove backup on success\n if backup_dir.exists():\n shutil.rmtree(backup_dir, ignore_errors=True)\n\n try:\n repo.git.add(A=True)\n app_logger.reason(\"Changes staged in git\", extra={\"src\": \"_handle_sync\"})\n except Exception as ge:\n app_logger.explore(f\"Failed to stage changes: {ge}\", extra={\"src\": \"_handle_sync\"})\n\n app_logger.info(f\"[_handle_sync][Coherence:OK] Dashboard {dashboard_id} synced successfully.\")\n return {\"status\": \"success\", \"message\": \"Dashboard synced and flattened in local repository\"}\n\n except Exception as e:\n app_logger.error(f\"[_handle_sync][Coherence:Failed] Sync failed: {e}\")\n raise\n # endregion _handle_sync\n\n # region _handle_deploy [C:4] [TYPE Function] [SEMANTICS git,deploy,zip]\n # @PURPOSE: Packages repository into ZIP and imports into target Superset environment.\n # @POST Dashboard imported into target Superset.\n # @SIDE_EFFECT Creates and removes temporary ZIP file.\n # @RELATION CALLS -> src.core.superset_client.SupersetClient.import_dashboard\n async def _handle_deploy(self, dashboard_id: int, env_id: str, log=None, git_log=None, superset_log=None) -> dict[str, Any]:\n with belief_scope(\"GitPlugin._handle_deploy\"):\n try:\n if not env_id:\n raise ValueError(\"Target environment ID required for deployment\")\n repo = self.git_service.get_repo(dashboard_id)\n repo_path = Path(repo.working_dir)\n git_log.info(f\"Packing repository {repo_path} for deployment.\")\n zip_buffer = io.BytesIO()\n root_dir_name = f\"dashboard_export_{dashboard_id}\"\n with zipfile.ZipFile(zip_buffer, \"w\", zipfile.ZIP_DEFLATED) as zf:\n for root, dirs, files in os.walk(repo_path):\n if \".git\" in dirs:\n dirs.remove(\".git\")\n for file in files:\n if file == \".git\" or file.endswith(\".zip\"):\n continue\n file_path = Path(root) / file\n arcname = Path(root_dir_name) / file_path.relative_to(repo_path)\n zf.write(file_path, arcname)\n zip_buffer.seek(0)\n env = self.config_manager.get_environment(env_id)\n if not env:\n raise ValueError(f\"Environment {env_id} not found\")\n client = SupersetClient(env)\n client.authenticate()\n temp_zip_path = repo_path / f\"deploy_{dashboard_id}.zip\"\n git_log.info(f\"Saving temporary zip to {temp_zip_path}\")\n with open(temp_zip_path, \"wb\") as f:\n f.write(zip_buffer.getvalue())\n\n try:\n app_logger.reason(f\"Importing dashboard to {env.name}\", extra={\"src\": \"_handle_deploy\"})\n result = client.import_dashboard(temp_zip_path)\n app_logger.info(f\"[_handle_deploy][Coherence:OK] Deployment successful for dashboard {dashboard_id}.\")\n return {\"status\": \"success\", \"message\": f\"Dashboard deployed to {env.name}\", \"details\": result}\n finally:\n if temp_zip_path.exists():\n os.remove(temp_zip_path)\n\n except Exception as e:\n app_logger.error(f\"[_handle_deploy][Coherence:Failed] Deployment failed: {e}\")\n raise\n # endregion _handle_deploy\n\n # region _get_env [C:4] [TYPE Function] [SEMANTICS env,config,strict]\n # @PURPOSE: Вспомогательный метод для получения конфигурации окружения.\n # @PARAM env_id (Optional[str]) - ID окружения.\n # @PRE env_id is a string or None.\n # @POST Returns an Environment object from config or DB.\n # When env_id is explicitly provided and not found, raises ValueError (no fallback).\n # @RETURN Environment - Объект конфигурации окружения.\n def _get_env(self, env_id: str | None = None):\n with belief_scope(\"GitPlugin._get_env\"):\n app_logger.reason(f\"Fetching environment for ID: {env_id}\", extra={\"src\": \"_get_env\"})\n\n # Priority 1: ConfigManager (config.json)\n if env_id:\n env = self.config_manager.get_environment(env_id)\n if env:\n app_logger.reflect(f\"Found environment by ID in ConfigManager: {env.name}\", extra={\"src\": \"_get_env\"})\n return env\n\n # Priority 2: Database (DeploymentEnvironment)\n from src.core.database import SessionLocal\n from src.models.git import DeploymentEnvironment\n\n db = SessionLocal()\n try:\n if env_id:\n db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.id == env_id).first()\n else:\n db_env = db.query(DeploymentEnvironment).filter(DeploymentEnvironment.is_active).first()\n if not db_env:\n db_env = db.query(DeploymentEnvironment).first()\n\n if db_env:\n app_logger.reflect(f\"Found environment in DB: {db_env.name}\", extra={\"src\": \"_get_env\"})\n from src.core.config_models import Environment\n return Environment(\n id=db_env.id,\n name=db_env.name,\n url=db_env.superset_url,\n username=\"admin\",\n password=db_env.superset_token,\n verify_ssl=True\n )\n\n # Fix 7: Strict check — if env_id was explicitly provided but not found, raise immediately\n if env_id:\n raise ValueError(f\"Environment '{env_id}' not found in ConfigManager or database\")\n finally:\n db.close()\n\n # Priority 3: fallback to first env only when no specific env_id was requested\n envs = self.config_manager.get_environments()\n if envs and not env_id:\n app_logger.reflect(f\"Using first environment from ConfigManager: {envs[0].name}\", extra={\"src\": \"_get_env\"})\n return envs[0]\n\n app_logger.error(f\"[_get_env][Coherence:Failed] No environments configured (searched config.json and DB). env_id={env_id}\")\n raise ValueError(\"No environments configured. Please add a Superset Environment in Settings.\")\n # endregion _get_env\n\n# #endregion GitPlugin\n# #endregion GitPluginModule\n"
},
{
"contract_id": "GitPlugin",
@@ -35155,7 +35265,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region LLMAnalysisPlugin [C:5] [TYPE Module] [SEMANTICS llm, analysis, dashboard, validation, documentation]\n# @BRIEF Implements DashboardValidationPlugin and DocumentationPlugin.\n# @LAYER Plugin\n# @RELATION INHERITS -> [PluginBase]\n# @RELATION CALLS -> [ScreenshotService]\n# @RELATION CALLS -> [LLMClient]\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [TaskContext]\n# @INVARIANT All LLM interactions must be executed as asynchronous tasks.\n# @DATA_CONTRACT AnalysisRequest -> AnalysisResult\n\nfrom datetime import datetime, timedelta\nimport json\nimport os\nfrom typing import Any\n\nfrom ...core.database import SessionLocal\nfrom ...core.logger import belief_scope, logger\nfrom ...core.plugin_base import PluginBase\nfrom ...core.superset_client import SupersetClient\nfrom ...core.task_manager.context import TaskContext\nfrom ...models.llm import ValidationPolicy, ValidationRecord\nfrom ...services.llm_prompt_templates import (\n DEFAULT_LLM_PROMPTS,\n normalize_llm_settings,\n render_prompt,\n)\nfrom ...services.llm_provider import LLMProviderService\nfrom ...services.notifications.service import NotificationService\nfrom .models import DetectedIssue, LLMProviderType, ValidationResult, ValidationStatus\nfrom .service import LLMClient, ScreenshotService\n\n\n# #region _is_masked_or_invalid_api_key [TYPE Function]\n# @BRIEF Guards against placeholder or malformed API keys in runtime.\n# @PRE value may be None.\n# @POST Returns True when value cannot be used for authenticated provider calls.\ndef _is_masked_or_invalid_api_key(value: str | None) -> bool:\n key = (value or \"\").strip()\n if not key:\n return True\n if key in {\"********\", \"EMPTY_OR_NONE\"}:\n return True\n # Most provider tokens are significantly longer; short values are almost always placeholders.\n return len(key) < 16\n# #endregion _is_masked_or_invalid_api_key\n\n# #region _json_safe_value [TYPE Function]\n# @BRIEF Recursively normalize payload values for JSON serialization.\n# @PRE value may be nested dict/list with datetime values.\n# @POST datetime values are converted to ISO strings.\ndef _json_safe_value(value: Any):\n if isinstance(value, datetime):\n return value.isoformat()\n if isinstance(value, dict):\n return {k: _json_safe_value(v) for k, v in value.items()}\n if isinstance(value, list):\n return [_json_safe_value(v) for v in value]\n return value\n# #endregion _json_safe_value\n\n# #region DashboardValidationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dashboard health analysis using LLMs.\n# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]\nclass DashboardValidationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_dashboard_validation\"\n\n @property\n def name(self) -> str:\n return \"Dashboard LLM Validation\"\n\n @property\n def description(self) -> str:\n return \"Automated dashboard health analysis using multimodal LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dashboard_id\": {\"type\": \"string\", \"title\": \"Dashboard ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dashboard_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DashboardValidationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dashboard validation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Validation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dashboard_id, environment_id, and provider_id.\n # @POST Returns a dictionary with validation results and persists them to the database.\n # @SIDE_EFFECT Captures a screenshot, calls LLM API, and writes to the database.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n validation_started_at = datetime.utcnow()\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n screenshot_log = log.with_source(\"screenshot\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dashboard_id_raw = params.get(\"dashboard_id\")\n dashboard_id = str(dashboard_id_raw) if dashboard_id_raw is not None else None\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n llm_log.debug(f\" Is Active: {db_provider.is_active}\")\n llm_log.debug(f\" Is Multimodal: {db_provider.is_multimodal}\")\n if not bool(db_provider.is_multimodal):\n raise ValueError(\n \"Dashboard validation requires a multimodal model (image input support).\"\n )\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Capture Screenshot\n screenshot_service = ScreenshotService(env)\n\n storage_root = config_mgr.get_config().settings.storage.root_path\n screenshots_dir = os.path.join(storage_root, \"screenshots\")\n os.makedirs(screenshots_dir, exist_ok=True)\n\n filename = f\"{dashboard_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png\"\n screenshot_path = os.path.join(screenshots_dir, filename)\n\n screenshot_started_at = datetime.utcnow()\n screenshot_log.info(f\"Capturing screenshot for dashboard {dashboard_id}\")\n await screenshot_service.capture_dashboard(dashboard_id, screenshot_path)\n screenshot_log.debug(f\"Screenshot saved to: {screenshot_path}\")\n screenshot_finished_at = datetime.utcnow()\n\n # 4. Fetch Logs (from Environment /api/v1/log/)\n logs = []\n logs_fetch_started_at = datetime.utcnow()\n try:\n client = SupersetClient(env)\n\n # Calculate time window (last 24 hours)\n start_time = (datetime.now() - timedelta(hours=24)).isoformat()\n\n # Construct filter for logs\n # Note: We filter by dashboard_id matching the object\n query_params = {\n \"filters\": [\n {\"col\": \"dashboard_id\", \"opr\": \"eq\", \"value\": dashboard_id},\n {\"col\": \"dttm\", \"opr\": \"gt\", \"value\": start_time}\n ],\n \"order_column\": \"dttm\",\n \"order_direction\": \"desc\",\n \"page\": 0,\n \"page_size\": 100\n }\n\n superset_log.debug(f\"Fetching logs for dashboard {dashboard_id}\")\n response = client.network.request(\n method=\"GET\",\n endpoint=\"/log/\",\n params={\"q\": json.dumps(query_params)}\n )\n\n if isinstance(response, dict) and \"result\" in response:\n for item in response[\"result\"]:\n action = item.get(\"action\", \"unknown\")\n dttm = item.get(\"dttm\", \"\")\n details = item.get(\"json\", \"\")\n logs.append(f\"[{dttm}] {action}: {details}\")\n\n if not logs:\n logs = [\"No recent logs found for this dashboard.\"]\n superset_log.debug(\"No recent logs found for this dashboard\")\n\n except Exception as e:\n superset_log.warning(f\"Failed to fetch logs from environment: {e}\")\n logs = [f\"Error fetching remote logs: {e!s}\"]\n logs_fetch_finished_at = datetime.utcnow()\n\n # 5. Analyze with LLM\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_log.info(f\"Analyzing dashboard {dashboard_id} with LLM\")\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n dashboard_prompt = llm_settings[\"prompts\"].get(\n \"dashboard_validation_prompt\",\n DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n )\n llm_call_started_at = datetime.utcnow()\n analysis = await llm_client.analyze_dashboard(\n screenshot_path,\n logs,\n prompt_template=dashboard_prompt,\n )\n llm_call_finished_at = datetime.utcnow()\n\n # Log analysis summary to task logs for better visibility\n llm_log.info(f\"[ANALYSIS_SUMMARY] Status: {analysis['status']}\")\n llm_log.info(f\"[ANALYSIS_SUMMARY] Summary: {analysis['summary']}\")\n if analysis.get(\"issues\"):\n for i, issue in enumerate(analysis[\"issues\"]):\n llm_log.info(f\"[ANALYSIS_ISSUE][{i+1}] {issue.get('severity')}: {issue.get('message')} (Location: {issue.get('location', 'N/A')})\")\n\n # 6. Persist Result\n validation_result = ValidationResult(\n dashboard_id=dashboard_id,\n status=ValidationStatus(analysis[\"status\"]),\n summary=analysis[\"summary\"],\n issues=[DetectedIssue(**issue) for issue in analysis[\"issues\"]],\n screenshot_path=screenshot_path,\n raw_response=str(analysis)\n )\n validation_finished_at = datetime.utcnow()\n\n result_payload = _json_safe_value(validation_result.dict())\n result_payload[\"screenshot_paths\"] = [screenshot_path]\n result_payload[\"logs_sent_to_llm\"] = logs\n result_payload[\"logs_sent_count\"] = len(logs)\n result_payload[\"prompt_template\"] = dashboard_prompt\n result_payload[\"provider\"] = {\n \"id\": db_provider.id,\n \"name\": db_provider.name,\n \"type\": db_provider.provider_type,\n \"base_url\": db_provider.base_url,\n \"model\": db_provider.default_model,\n }\n result_payload[\"environment_id\"] = env_id\n result_payload[\"timings\"] = {\n \"validation_started_at\": validation_started_at.isoformat(),\n \"validation_finished_at\": validation_finished_at.isoformat(),\n \"validation_duration_ms\": int((validation_finished_at - validation_started_at).total_seconds() * 1000),\n \"screenshot_started_at\": screenshot_started_at.isoformat(),\n \"screenshot_finished_at\": screenshot_finished_at.isoformat(),\n \"screenshot_duration_ms\": int((screenshot_finished_at - screenshot_started_at).total_seconds() * 1000),\n \"logs_fetch_started_at\": logs_fetch_started_at.isoformat(),\n \"logs_fetch_finished_at\": logs_fetch_finished_at.isoformat(),\n \"logs_fetch_duration_ms\": int((logs_fetch_finished_at - logs_fetch_started_at).total_seconds() * 1000),\n \"llm_call_started_at\": llm_call_started_at.isoformat(),\n \"llm_call_finished_at\": llm_call_finished_at.isoformat(),\n \"llm_call_duration_ms\": int((llm_call_finished_at - llm_call_started_at).total_seconds() * 1000),\n }\n\n db_record = ValidationRecord(\n task_id=context.task_id if context else None,\n policy_id=params.get(\"policy_id\"),\n dashboard_id=validation_result.dashboard_id,\n environment_id=env_id,\n status=validation_result.status.value,\n summary=validation_result.summary,\n issues=[issue.dict() for issue in validation_result.issues],\n screenshot_path=validation_result.screenshot_path,\n raw_response=json.dumps(result_payload, ensure_ascii=False)\n )\n db.add(db_record)\n db.commit()\n\n # 7. Notification on failure (US1 / FR-015)\n try:\n policy_id = params.get(\"policy_id\")\n policy = None\n if policy_id:\n policy = db.query(ValidationPolicy).filter(ValidationPolicy.id == policy_id).first()\n\n notification_service = NotificationService(db, config_mgr)\n await notification_service.dispatch_report(\n record=db_record,\n policy=policy,\n background_tasks=getattr(context, \"background_tasks\", None) if context else None\n )\n except Exception as e:\n log.error(f\"Failed to dispatch notifications: {e}\")\n\n # Final log to ensure all analysis is visible in task logs\n log.info(f\"Validation completed for dashboard {dashboard_id}. Status: {validation_result.status.value}\")\n\n return result_payload\n\n finally:\n db.close()\n # endregion DashboardValidationPlugin.execute\n# #endregion DashboardValidationPlugin\n\n# #region DocumentationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dataset documentation using LLMs.\n# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]\nclass DocumentationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_documentation\"\n\n @property\n def name(self) -> str:\n return \"Dataset LLM Documentation\"\n\n @property\n def description(self) -> str:\n return \"Automated dataset and column documentation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dataset_id\": {\"type\": \"string\", \"title\": \"Dataset ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dataset_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DocumentationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dataset documentation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Documentation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dataset_id, environment_id, and provider_id.\n # @POST Returns generated documentation and updates the dataset in Superset.\n # @SIDE_EFFECT Calls LLM API and updates dataset metadata in Superset.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dataset_id = params.get(\"dataset_id\")\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Fetch Metadata (US2 / T024)\n from ...core.superset_client import SupersetClient\n client = SupersetClient(env)\n\n superset_log.debug(f\"Fetching dataset {dataset_id}\")\n dataset = client.get_dataset(int(dataset_id))\n\n # Extract columns and existing descriptions\n columns_data = []\n for col in dataset.get(\"columns\", []):\n columns_data.append({\n \"name\": col.get(\"column_name\"),\n \"type\": col.get(\"type\"),\n \"description\": col.get(\"description\")\n })\n superset_log.debug(f\"Extracted {len(columns_data)} columns from dataset\")\n\n # 4. Construct Prompt & Analyze (US2 / T025)\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n documentation_prompt = llm_settings[\"prompts\"].get(\n \"documentation_prompt\",\n DEFAULT_LLM_PROMPTS[\"documentation_prompt\"],\n )\n prompt = render_prompt(\n documentation_prompt,\n {\n \"dataset_name\": dataset.get(\"table_name\") or \"\",\n \"columns_json\": json.dumps(columns_data, ensure_ascii=False),\n },\n )\n\n # Using a generic chat completion for text-only US2\n llm_log.info(f\"Generating documentation for dataset {dataset_id}\")\n doc_result = await llm_client.get_json_completion([{\"role\": \"user\", \"content\": prompt}])\n\n # 5. Update Metadata (US2 / T026)\n update_payload = {\n \"description\": doc_result[\"dataset_description\"],\n \"columns\": []\n }\n\n # Map generated descriptions back to column IDs\n for col_doc in doc_result[\"column_descriptions\"]:\n for col in dataset.get(\"columns\", []):\n if col.get(\"column_name\") == col_doc[\"name\"]:\n update_payload[\"columns\"].append({\n \"id\": col.get(\"id\"),\n \"description\": col_doc[\"description\"]\n })\n\n superset_log.info(f\"Updating dataset {dataset_id} with generated documentation\")\n client.update_dataset(int(dataset_id), update_payload)\n\n log.info(f\"Documentation completed for dataset {dataset_id}\")\n\n return doc_result\n\n finally:\n db.close()\n # endregion DocumentationPlugin.execute\n# #endregion DocumentationPlugin\n\n# #endregion LLMAnalysisPlugin\n"
+ "body": "# #region LLMAnalysisPlugin [C:5] [TYPE Module] [SEMANTICS llm, analysis, dashboard, validation, documentation]\n# @BRIEF Implements DashboardValidationPlugin and DocumentationPlugin.\n# @LAYER Plugin\n# @RELATION INHERITS -> [PluginBase]\n# @RELATION CALLS -> [ScreenshotService]\n# @RELATION CALLS -> [LLMClient]\n# @RELATION CALLS -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [TaskContext]\n# @INVARIANT All LLM interactions must be executed as asynchronous tasks.\n# @DATA_CONTRACT AnalysisRequest -> AnalysisResult\n\nfrom datetime import datetime, timedelta\nimport json\nimport os\nfrom typing import Any\n\nfrom ...core.database import SessionLocal\nfrom ...core.logger import belief_scope, logger\nfrom ...core.plugin_base import PluginBase\nfrom ...core.superset_client import SupersetClient\nfrom ...core.task_manager.context import TaskContext\nfrom ...models.llm import ValidationPolicy, ValidationRecord\nfrom ...services.llm_prompt_templates import (\n DEFAULT_LLM_PROMPTS,\n normalize_llm_settings,\n render_prompt,\n)\nfrom ...services.llm_provider import LLMProviderService\nfrom ...services.notifications.service import NotificationService\nfrom .models import DetectedIssue, LLMProviderType, ValidationResult, ValidationStatus\nfrom .service import LLMClient, ScreenshotService\n\n\n# #region _is_masked_or_invalid_api_key [TYPE Function]\n# @BRIEF Guards against placeholder or malformed API keys in runtime.\n# @PRE value may be None.\n# @POST Returns True when value cannot be used for authenticated provider calls.\ndef _is_masked_or_invalid_api_key(value: str | None) -> bool:\n key = (value or \"\").strip()\n if not key:\n return True\n if key in {\"********\", \"EMPTY_OR_NONE\"}:\n return True\n # Most provider tokens are significantly longer; short values are almost always placeholders.\n return len(key) < 16\n# #endregion _is_masked_or_invalid_api_key\n\n# #region _json_safe_value [TYPE Function]\n# @BRIEF Recursively normalize payload values for JSON serialization.\n# @PRE value may be nested dict/list with datetime values.\n# @POST datetime values are converted to ISO strings.\ndef _json_safe_value(value: Any):\n if isinstance(value, datetime):\n return value.isoformat()\n if isinstance(value, dict):\n return {k: _json_safe_value(v) for k, v in value.items()}\n if isinstance(value, list):\n return [_json_safe_value(v) for v in value]\n return value\n# #endregion _json_safe_value\n\n# #region DashboardValidationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dashboard health analysis using LLMs.\n# @RELATION IMPLEMENTS -> [PluginBase]\nclass DashboardValidationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_dashboard_validation\"\n\n @property\n def name(self) -> str:\n return \"Dashboard LLM Validation\"\n\n @property\n def description(self) -> str:\n return \"Automated dashboard health analysis using multimodal LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dashboard_id\": {\"type\": \"string\", \"title\": \"Dashboard ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dashboard_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DashboardValidationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dashboard validation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Validation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dashboard_id, environment_id, and provider_id.\n # @POST Returns a dictionary with validation results and persists them to the database.\n # @SIDE_EFFECT Captures a screenshot, calls LLM API, and writes to the database.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n validation_started_at = datetime.utcnow()\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n screenshot_log = log.with_source(\"screenshot\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dashboard_id_raw = params.get(\"dashboard_id\")\n dashboard_id = str(dashboard_id_raw) if dashboard_id_raw is not None else None\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n llm_log.debug(f\" Is Active: {db_provider.is_active}\")\n llm_log.debug(f\" Is Multimodal: {db_provider.is_multimodal}\")\n if not bool(db_provider.is_multimodal):\n raise ValueError(\n \"Dashboard validation requires a multimodal model (image input support).\"\n )\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Capture Screenshot\n screenshot_service = ScreenshotService(env)\n\n storage_root = config_mgr.get_config().settings.storage.root_path\n screenshots_dir = os.path.join(storage_root, \"screenshots\")\n os.makedirs(screenshots_dir, exist_ok=True)\n\n filename = f\"{dashboard_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png\"\n screenshot_path = os.path.join(screenshots_dir, filename)\n\n screenshot_started_at = datetime.utcnow()\n screenshot_log.info(f\"Capturing screenshot for dashboard {dashboard_id}\")\n await screenshot_service.capture_dashboard(dashboard_id, screenshot_path)\n screenshot_log.debug(f\"Screenshot saved to: {screenshot_path}\")\n screenshot_finished_at = datetime.utcnow()\n\n # 4. Fetch Logs (from Environment /api/v1/log/)\n logs = []\n logs_fetch_started_at = datetime.utcnow()\n try:\n client = SupersetClient(env)\n\n # Calculate time window (last 24 hours)\n start_time = (datetime.now() - timedelta(hours=24)).isoformat()\n\n # Construct filter for logs\n # Note: We filter by dashboard_id matching the object\n query_params = {\n \"filters\": [\n {\"col\": \"dashboard_id\", \"opr\": \"eq\", \"value\": dashboard_id},\n {\"col\": \"dttm\", \"opr\": \"gt\", \"value\": start_time}\n ],\n \"order_column\": \"dttm\",\n \"order_direction\": \"desc\",\n \"page\": 0,\n \"page_size\": 100\n }\n\n superset_log.debug(f\"Fetching logs for dashboard {dashboard_id}\")\n response = client.network.request(\n method=\"GET\",\n endpoint=\"/log/\",\n params={\"q\": json.dumps(query_params)}\n )\n\n if isinstance(response, dict) and \"result\" in response:\n for item in response[\"result\"]:\n action = item.get(\"action\", \"unknown\")\n dttm = item.get(\"dttm\", \"\")\n details = item.get(\"json\", \"\")\n logs.append(f\"[{dttm}] {action}: {details}\")\n\n if not logs:\n logs = [\"No recent logs found for this dashboard.\"]\n superset_log.debug(\"No recent logs found for this dashboard\")\n\n except Exception as e:\n superset_log.warning(f\"Failed to fetch logs from environment: {e}\")\n logs = [f\"Error fetching remote logs: {e!s}\"]\n logs_fetch_finished_at = datetime.utcnow()\n\n # 5. Analyze with LLM\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_log.info(f\"Analyzing dashboard {dashboard_id} with LLM\")\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n dashboard_prompt = llm_settings[\"prompts\"].get(\n \"dashboard_validation_prompt\",\n DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n )\n llm_call_started_at = datetime.utcnow()\n analysis = await llm_client.analyze_dashboard(\n screenshot_path,\n logs,\n prompt_template=dashboard_prompt,\n )\n llm_call_finished_at = datetime.utcnow()\n\n # Log analysis summary to task logs for better visibility\n llm_log.info(f\"[ANALYSIS_SUMMARY] Status: {analysis['status']}\")\n llm_log.info(f\"[ANALYSIS_SUMMARY] Summary: {analysis['summary']}\")\n if analysis.get(\"issues\"):\n for i, issue in enumerate(analysis[\"issues\"]):\n llm_log.info(f\"[ANALYSIS_ISSUE][{i+1}] {issue.get('severity')}: {issue.get('message')} (Location: {issue.get('location', 'N/A')})\")\n\n # 6. Persist Result\n validation_result = ValidationResult(\n dashboard_id=dashboard_id,\n status=ValidationStatus(analysis[\"status\"]),\n summary=analysis[\"summary\"],\n issues=[DetectedIssue(**issue) for issue in analysis[\"issues\"]],\n screenshot_path=screenshot_path,\n raw_response=str(analysis)\n )\n validation_finished_at = datetime.utcnow()\n\n result_payload = _json_safe_value(validation_result.dict())\n result_payload[\"screenshot_paths\"] = [screenshot_path]\n result_payload[\"logs_sent_to_llm\"] = logs\n result_payload[\"logs_sent_count\"] = len(logs)\n result_payload[\"prompt_template\"] = dashboard_prompt\n result_payload[\"provider\"] = {\n \"id\": db_provider.id,\n \"name\": db_provider.name,\n \"type\": db_provider.provider_type,\n \"base_url\": db_provider.base_url,\n \"model\": db_provider.default_model,\n }\n result_payload[\"environment_id\"] = env_id\n result_payload[\"timings\"] = {\n \"validation_started_at\": validation_started_at.isoformat(),\n \"validation_finished_at\": validation_finished_at.isoformat(),\n \"validation_duration_ms\": int((validation_finished_at - validation_started_at).total_seconds() * 1000),\n \"screenshot_started_at\": screenshot_started_at.isoformat(),\n \"screenshot_finished_at\": screenshot_finished_at.isoformat(),\n \"screenshot_duration_ms\": int((screenshot_finished_at - screenshot_started_at).total_seconds() * 1000),\n \"logs_fetch_started_at\": logs_fetch_started_at.isoformat(),\n \"logs_fetch_finished_at\": logs_fetch_finished_at.isoformat(),\n \"logs_fetch_duration_ms\": int((logs_fetch_finished_at - logs_fetch_started_at).total_seconds() * 1000),\n \"llm_call_started_at\": llm_call_started_at.isoformat(),\n \"llm_call_finished_at\": llm_call_finished_at.isoformat(),\n \"llm_call_duration_ms\": int((llm_call_finished_at - llm_call_started_at).total_seconds() * 1000),\n }\n\n db_record = ValidationRecord(\n task_id=context.task_id if context else None,\n policy_id=params.get(\"policy_id\"),\n dashboard_id=validation_result.dashboard_id,\n environment_id=env_id,\n status=validation_result.status.value,\n summary=validation_result.summary,\n issues=[issue.dict() for issue in validation_result.issues],\n screenshot_path=validation_result.screenshot_path,\n raw_response=json.dumps(result_payload, ensure_ascii=False)\n )\n db.add(db_record)\n db.commit()\n\n # 7. Notification on failure (US1 / FR-015)\n try:\n policy_id = params.get(\"policy_id\")\n policy = None\n if policy_id:\n policy = db.query(ValidationPolicy).filter(ValidationPolicy.id == policy_id).first()\n\n notification_service = NotificationService(db, config_mgr)\n await notification_service.dispatch_report(\n record=db_record,\n policy=policy,\n background_tasks=getattr(context, \"background_tasks\", None) if context else None\n )\n except Exception as e:\n log.error(f\"Failed to dispatch notifications: {e}\")\n\n # Final log to ensure all analysis is visible in task logs\n log.info(f\"Validation completed for dashboard {dashboard_id}. Status: {validation_result.status.value}\")\n\n return result_payload\n\n finally:\n db.close()\n # endregion DashboardValidationPlugin.execute\n# #endregion DashboardValidationPlugin\n\n# #region DocumentationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dataset documentation using LLMs.\n# @RELATION IMPLEMENTS -> [PluginBase]\nclass DocumentationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_documentation\"\n\n @property\n def name(self) -> str:\n return \"Dataset LLM Documentation\"\n\n @property\n def description(self) -> str:\n return \"Automated dataset and column documentation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dataset_id\": {\"type\": \"string\", \"title\": \"Dataset ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dataset_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DocumentationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dataset documentation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Documentation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dataset_id, environment_id, and provider_id.\n # @POST Returns generated documentation and updates the dataset in Superset.\n # @SIDE_EFFECT Calls LLM API and updates dataset metadata in Superset.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dataset_id = params.get(\"dataset_id\")\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Fetch Metadata (US2 / T024)\n from ...core.superset_client import SupersetClient\n client = SupersetClient(env)\n\n superset_log.debug(f\"Fetching dataset {dataset_id}\")\n dataset = client.get_dataset(int(dataset_id))\n\n # Extract columns and existing descriptions\n columns_data = []\n for col in dataset.get(\"columns\", []):\n columns_data.append({\n \"name\": col.get(\"column_name\"),\n \"type\": col.get(\"type\"),\n \"description\": col.get(\"description\")\n })\n superset_log.debug(f\"Extracted {len(columns_data)} columns from dataset\")\n\n # 4. Construct Prompt & Analyze (US2 / T025)\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n documentation_prompt = llm_settings[\"prompts\"].get(\n \"documentation_prompt\",\n DEFAULT_LLM_PROMPTS[\"documentation_prompt\"],\n )\n prompt = render_prompt(\n documentation_prompt,\n {\n \"dataset_name\": dataset.get(\"table_name\") or \"\",\n \"columns_json\": json.dumps(columns_data, ensure_ascii=False),\n },\n )\n\n # Using a generic chat completion for text-only US2\n llm_log.info(f\"Generating documentation for dataset {dataset_id}\")\n doc_result = await llm_client.get_json_completion([{\"role\": \"user\", \"content\": prompt}])\n\n # 5. Update Metadata (US2 / T026)\n update_payload = {\n \"description\": doc_result[\"dataset_description\"],\n \"columns\": []\n }\n\n # Map generated descriptions back to column IDs\n for col_doc in doc_result[\"column_descriptions\"]:\n for col in dataset.get(\"columns\", []):\n if col.get(\"column_name\") == col_doc[\"name\"]:\n update_payload[\"columns\"].append({\n \"id\": col.get(\"id\"),\n \"description\": col_doc[\"description\"]\n })\n\n superset_log.info(f\"Updating dataset {dataset_id} with generated documentation\")\n client.update_dataset(int(dataset_id), update_payload)\n\n log.info(f\"Documentation completed for dataset {dataset_id}\")\n\n return doc_result\n\n finally:\n db.close()\n # endregion DocumentationPlugin.execute\n# #endregion DocumentationPlugin\n\n# #endregion LLMAnalysisPlugin\n"
},
{
"contract_id": "_is_masked_or_invalid_api_key",
@@ -35210,14 +35320,14 @@
{
"source_id": "DashboardValidationPlugin",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:path:backend.src.core.plugin_base.PluginBase",
- "target_ref": "[EXT:path:backend.src.core.plugin_base.PluginBase]"
+ "target_id": "PluginBase",
+ "target_ref": "[PluginBase]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DashboardValidationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dashboard health analysis using LLMs.\n# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]\nclass DashboardValidationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_dashboard_validation\"\n\n @property\n def name(self) -> str:\n return \"Dashboard LLM Validation\"\n\n @property\n def description(self) -> str:\n return \"Automated dashboard health analysis using multimodal LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dashboard_id\": {\"type\": \"string\", \"title\": \"Dashboard ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dashboard_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DashboardValidationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dashboard validation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Validation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dashboard_id, environment_id, and provider_id.\n # @POST Returns a dictionary with validation results and persists them to the database.\n # @SIDE_EFFECT Captures a screenshot, calls LLM API, and writes to the database.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n validation_started_at = datetime.utcnow()\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n screenshot_log = log.with_source(\"screenshot\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dashboard_id_raw = params.get(\"dashboard_id\")\n dashboard_id = str(dashboard_id_raw) if dashboard_id_raw is not None else None\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n llm_log.debug(f\" Is Active: {db_provider.is_active}\")\n llm_log.debug(f\" Is Multimodal: {db_provider.is_multimodal}\")\n if not bool(db_provider.is_multimodal):\n raise ValueError(\n \"Dashboard validation requires a multimodal model (image input support).\"\n )\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Capture Screenshot\n screenshot_service = ScreenshotService(env)\n\n storage_root = config_mgr.get_config().settings.storage.root_path\n screenshots_dir = os.path.join(storage_root, \"screenshots\")\n os.makedirs(screenshots_dir, exist_ok=True)\n\n filename = f\"{dashboard_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png\"\n screenshot_path = os.path.join(screenshots_dir, filename)\n\n screenshot_started_at = datetime.utcnow()\n screenshot_log.info(f\"Capturing screenshot for dashboard {dashboard_id}\")\n await screenshot_service.capture_dashboard(dashboard_id, screenshot_path)\n screenshot_log.debug(f\"Screenshot saved to: {screenshot_path}\")\n screenshot_finished_at = datetime.utcnow()\n\n # 4. Fetch Logs (from Environment /api/v1/log/)\n logs = []\n logs_fetch_started_at = datetime.utcnow()\n try:\n client = SupersetClient(env)\n\n # Calculate time window (last 24 hours)\n start_time = (datetime.now() - timedelta(hours=24)).isoformat()\n\n # Construct filter for logs\n # Note: We filter by dashboard_id matching the object\n query_params = {\n \"filters\": [\n {\"col\": \"dashboard_id\", \"opr\": \"eq\", \"value\": dashboard_id},\n {\"col\": \"dttm\", \"opr\": \"gt\", \"value\": start_time}\n ],\n \"order_column\": \"dttm\",\n \"order_direction\": \"desc\",\n \"page\": 0,\n \"page_size\": 100\n }\n\n superset_log.debug(f\"Fetching logs for dashboard {dashboard_id}\")\n response = client.network.request(\n method=\"GET\",\n endpoint=\"/log/\",\n params={\"q\": json.dumps(query_params)}\n )\n\n if isinstance(response, dict) and \"result\" in response:\n for item in response[\"result\"]:\n action = item.get(\"action\", \"unknown\")\n dttm = item.get(\"dttm\", \"\")\n details = item.get(\"json\", \"\")\n logs.append(f\"[{dttm}] {action}: {details}\")\n\n if not logs:\n logs = [\"No recent logs found for this dashboard.\"]\n superset_log.debug(\"No recent logs found for this dashboard\")\n\n except Exception as e:\n superset_log.warning(f\"Failed to fetch logs from environment: {e}\")\n logs = [f\"Error fetching remote logs: {e!s}\"]\n logs_fetch_finished_at = datetime.utcnow()\n\n # 5. Analyze with LLM\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_log.info(f\"Analyzing dashboard {dashboard_id} with LLM\")\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n dashboard_prompt = llm_settings[\"prompts\"].get(\n \"dashboard_validation_prompt\",\n DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n )\n llm_call_started_at = datetime.utcnow()\n analysis = await llm_client.analyze_dashboard(\n screenshot_path,\n logs,\n prompt_template=dashboard_prompt,\n )\n llm_call_finished_at = datetime.utcnow()\n\n # Log analysis summary to task logs for better visibility\n llm_log.info(f\"[ANALYSIS_SUMMARY] Status: {analysis['status']}\")\n llm_log.info(f\"[ANALYSIS_SUMMARY] Summary: {analysis['summary']}\")\n if analysis.get(\"issues\"):\n for i, issue in enumerate(analysis[\"issues\"]):\n llm_log.info(f\"[ANALYSIS_ISSUE][{i+1}] {issue.get('severity')}: {issue.get('message')} (Location: {issue.get('location', 'N/A')})\")\n\n # 6. Persist Result\n validation_result = ValidationResult(\n dashboard_id=dashboard_id,\n status=ValidationStatus(analysis[\"status\"]),\n summary=analysis[\"summary\"],\n issues=[DetectedIssue(**issue) for issue in analysis[\"issues\"]],\n screenshot_path=screenshot_path,\n raw_response=str(analysis)\n )\n validation_finished_at = datetime.utcnow()\n\n result_payload = _json_safe_value(validation_result.dict())\n result_payload[\"screenshot_paths\"] = [screenshot_path]\n result_payload[\"logs_sent_to_llm\"] = logs\n result_payload[\"logs_sent_count\"] = len(logs)\n result_payload[\"prompt_template\"] = dashboard_prompt\n result_payload[\"provider\"] = {\n \"id\": db_provider.id,\n \"name\": db_provider.name,\n \"type\": db_provider.provider_type,\n \"base_url\": db_provider.base_url,\n \"model\": db_provider.default_model,\n }\n result_payload[\"environment_id\"] = env_id\n result_payload[\"timings\"] = {\n \"validation_started_at\": validation_started_at.isoformat(),\n \"validation_finished_at\": validation_finished_at.isoformat(),\n \"validation_duration_ms\": int((validation_finished_at - validation_started_at).total_seconds() * 1000),\n \"screenshot_started_at\": screenshot_started_at.isoformat(),\n \"screenshot_finished_at\": screenshot_finished_at.isoformat(),\n \"screenshot_duration_ms\": int((screenshot_finished_at - screenshot_started_at).total_seconds() * 1000),\n \"logs_fetch_started_at\": logs_fetch_started_at.isoformat(),\n \"logs_fetch_finished_at\": logs_fetch_finished_at.isoformat(),\n \"logs_fetch_duration_ms\": int((logs_fetch_finished_at - logs_fetch_started_at).total_seconds() * 1000),\n \"llm_call_started_at\": llm_call_started_at.isoformat(),\n \"llm_call_finished_at\": llm_call_finished_at.isoformat(),\n \"llm_call_duration_ms\": int((llm_call_finished_at - llm_call_started_at).total_seconds() * 1000),\n }\n\n db_record = ValidationRecord(\n task_id=context.task_id if context else None,\n policy_id=params.get(\"policy_id\"),\n dashboard_id=validation_result.dashboard_id,\n environment_id=env_id,\n status=validation_result.status.value,\n summary=validation_result.summary,\n issues=[issue.dict() for issue in validation_result.issues],\n screenshot_path=validation_result.screenshot_path,\n raw_response=json.dumps(result_payload, ensure_ascii=False)\n )\n db.add(db_record)\n db.commit()\n\n # 7. Notification on failure (US1 / FR-015)\n try:\n policy_id = params.get(\"policy_id\")\n policy = None\n if policy_id:\n policy = db.query(ValidationPolicy).filter(ValidationPolicy.id == policy_id).first()\n\n notification_service = NotificationService(db, config_mgr)\n await notification_service.dispatch_report(\n record=db_record,\n policy=policy,\n background_tasks=getattr(context, \"background_tasks\", None) if context else None\n )\n except Exception as e:\n log.error(f\"Failed to dispatch notifications: {e}\")\n\n # Final log to ensure all analysis is visible in task logs\n log.info(f\"Validation completed for dashboard {dashboard_id}. Status: {validation_result.status.value}\")\n\n return result_payload\n\n finally:\n db.close()\n # endregion DashboardValidationPlugin.execute\n# #endregion DashboardValidationPlugin\n"
+ "body": "# #region DashboardValidationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dashboard health analysis using LLMs.\n# @RELATION IMPLEMENTS -> [PluginBase]\nclass DashboardValidationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_dashboard_validation\"\n\n @property\n def name(self) -> str:\n return \"Dashboard LLM Validation\"\n\n @property\n def description(self) -> str:\n return \"Automated dashboard health analysis using multimodal LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dashboard_id\": {\"type\": \"string\", \"title\": \"Dashboard ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dashboard_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DashboardValidationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dashboard validation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Validation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dashboard_id, environment_id, and provider_id.\n # @POST Returns a dictionary with validation results and persists them to the database.\n # @SIDE_EFFECT Captures a screenshot, calls LLM API, and writes to the database.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n validation_started_at = datetime.utcnow()\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n screenshot_log = log.with_source(\"screenshot\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dashboard_id_raw = params.get(\"dashboard_id\")\n dashboard_id = str(dashboard_id_raw) if dashboard_id_raw is not None else None\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n llm_log.debug(f\" Is Active: {db_provider.is_active}\")\n llm_log.debug(f\" Is Multimodal: {db_provider.is_multimodal}\")\n if not bool(db_provider.is_multimodal):\n raise ValueError(\n \"Dashboard validation requires a multimodal model (image input support).\"\n )\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Capture Screenshot\n screenshot_service = ScreenshotService(env)\n\n storage_root = config_mgr.get_config().settings.storage.root_path\n screenshots_dir = os.path.join(storage_root, \"screenshots\")\n os.makedirs(screenshots_dir, exist_ok=True)\n\n filename = f\"{dashboard_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png\"\n screenshot_path = os.path.join(screenshots_dir, filename)\n\n screenshot_started_at = datetime.utcnow()\n screenshot_log.info(f\"Capturing screenshot for dashboard {dashboard_id}\")\n await screenshot_service.capture_dashboard(dashboard_id, screenshot_path)\n screenshot_log.debug(f\"Screenshot saved to: {screenshot_path}\")\n screenshot_finished_at = datetime.utcnow()\n\n # 4. Fetch Logs (from Environment /api/v1/log/)\n logs = []\n logs_fetch_started_at = datetime.utcnow()\n try:\n client = SupersetClient(env)\n\n # Calculate time window (last 24 hours)\n start_time = (datetime.now() - timedelta(hours=24)).isoformat()\n\n # Construct filter for logs\n # Note: We filter by dashboard_id matching the object\n query_params = {\n \"filters\": [\n {\"col\": \"dashboard_id\", \"opr\": \"eq\", \"value\": dashboard_id},\n {\"col\": \"dttm\", \"opr\": \"gt\", \"value\": start_time}\n ],\n \"order_column\": \"dttm\",\n \"order_direction\": \"desc\",\n \"page\": 0,\n \"page_size\": 100\n }\n\n superset_log.debug(f\"Fetching logs for dashboard {dashboard_id}\")\n response = client.network.request(\n method=\"GET\",\n endpoint=\"/log/\",\n params={\"q\": json.dumps(query_params)}\n )\n\n if isinstance(response, dict) and \"result\" in response:\n for item in response[\"result\"]:\n action = item.get(\"action\", \"unknown\")\n dttm = item.get(\"dttm\", \"\")\n details = item.get(\"json\", \"\")\n logs.append(f\"[{dttm}] {action}: {details}\")\n\n if not logs:\n logs = [\"No recent logs found for this dashboard.\"]\n superset_log.debug(\"No recent logs found for this dashboard\")\n\n except Exception as e:\n superset_log.warning(f\"Failed to fetch logs from environment: {e}\")\n logs = [f\"Error fetching remote logs: {e!s}\"]\n logs_fetch_finished_at = datetime.utcnow()\n\n # 5. Analyze with LLM\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_log.info(f\"Analyzing dashboard {dashboard_id} with LLM\")\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n dashboard_prompt = llm_settings[\"prompts\"].get(\n \"dashboard_validation_prompt\",\n DEFAULT_LLM_PROMPTS[\"dashboard_validation_prompt\"],\n )\n llm_call_started_at = datetime.utcnow()\n analysis = await llm_client.analyze_dashboard(\n screenshot_path,\n logs,\n prompt_template=dashboard_prompt,\n )\n llm_call_finished_at = datetime.utcnow()\n\n # Log analysis summary to task logs for better visibility\n llm_log.info(f\"[ANALYSIS_SUMMARY] Status: {analysis['status']}\")\n llm_log.info(f\"[ANALYSIS_SUMMARY] Summary: {analysis['summary']}\")\n if analysis.get(\"issues\"):\n for i, issue in enumerate(analysis[\"issues\"]):\n llm_log.info(f\"[ANALYSIS_ISSUE][{i+1}] {issue.get('severity')}: {issue.get('message')} (Location: {issue.get('location', 'N/A')})\")\n\n # 6. Persist Result\n validation_result = ValidationResult(\n dashboard_id=dashboard_id,\n status=ValidationStatus(analysis[\"status\"]),\n summary=analysis[\"summary\"],\n issues=[DetectedIssue(**issue) for issue in analysis[\"issues\"]],\n screenshot_path=screenshot_path,\n raw_response=str(analysis)\n )\n validation_finished_at = datetime.utcnow()\n\n result_payload = _json_safe_value(validation_result.dict())\n result_payload[\"screenshot_paths\"] = [screenshot_path]\n result_payload[\"logs_sent_to_llm\"] = logs\n result_payload[\"logs_sent_count\"] = len(logs)\n result_payload[\"prompt_template\"] = dashboard_prompt\n result_payload[\"provider\"] = {\n \"id\": db_provider.id,\n \"name\": db_provider.name,\n \"type\": db_provider.provider_type,\n \"base_url\": db_provider.base_url,\n \"model\": db_provider.default_model,\n }\n result_payload[\"environment_id\"] = env_id\n result_payload[\"timings\"] = {\n \"validation_started_at\": validation_started_at.isoformat(),\n \"validation_finished_at\": validation_finished_at.isoformat(),\n \"validation_duration_ms\": int((validation_finished_at - validation_started_at).total_seconds() * 1000),\n \"screenshot_started_at\": screenshot_started_at.isoformat(),\n \"screenshot_finished_at\": screenshot_finished_at.isoformat(),\n \"screenshot_duration_ms\": int((screenshot_finished_at - screenshot_started_at).total_seconds() * 1000),\n \"logs_fetch_started_at\": logs_fetch_started_at.isoformat(),\n \"logs_fetch_finished_at\": logs_fetch_finished_at.isoformat(),\n \"logs_fetch_duration_ms\": int((logs_fetch_finished_at - logs_fetch_started_at).total_seconds() * 1000),\n \"llm_call_started_at\": llm_call_started_at.isoformat(),\n \"llm_call_finished_at\": llm_call_finished_at.isoformat(),\n \"llm_call_duration_ms\": int((llm_call_finished_at - llm_call_started_at).total_seconds() * 1000),\n }\n\n db_record = ValidationRecord(\n task_id=context.task_id if context else None,\n policy_id=params.get(\"policy_id\"),\n dashboard_id=validation_result.dashboard_id,\n environment_id=env_id,\n status=validation_result.status.value,\n summary=validation_result.summary,\n issues=[issue.dict() for issue in validation_result.issues],\n screenshot_path=validation_result.screenshot_path,\n raw_response=json.dumps(result_payload, ensure_ascii=False)\n )\n db.add(db_record)\n db.commit()\n\n # 7. Notification on failure (US1 / FR-015)\n try:\n policy_id = params.get(\"policy_id\")\n policy = None\n if policy_id:\n policy = db.query(ValidationPolicy).filter(ValidationPolicy.id == policy_id).first()\n\n notification_service = NotificationService(db, config_mgr)\n await notification_service.dispatch_report(\n record=db_record,\n policy=policy,\n background_tasks=getattr(context, \"background_tasks\", None) if context else None\n )\n except Exception as e:\n log.error(f\"Failed to dispatch notifications: {e}\")\n\n # Final log to ensure all analysis is visible in task logs\n log.info(f\"Validation completed for dashboard {dashboard_id}. Status: {validation_result.status.value}\")\n\n return result_payload\n\n finally:\n db.close()\n # endregion DashboardValidationPlugin.execute\n# #endregion DashboardValidationPlugin\n"
},
{
"contract_id": "DocumentationPlugin",
@@ -35234,14 +35344,14 @@
{
"source_id": "DocumentationPlugin",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:path:backend.src.core.plugin_base.PluginBase",
- "target_ref": "[EXT:path:backend.src.core.plugin_base.PluginBase]"
+ "target_id": "PluginBase",
+ "target_ref": "[PluginBase]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DocumentationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dataset documentation using LLMs.\n# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]\nclass DocumentationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_documentation\"\n\n @property\n def name(self) -> str:\n return \"Dataset LLM Documentation\"\n\n @property\n def description(self) -> str:\n return \"Automated dataset and column documentation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dataset_id\": {\"type\": \"string\", \"title\": \"Dataset ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dataset_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DocumentationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dataset documentation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Documentation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dataset_id, environment_id, and provider_id.\n # @POST Returns generated documentation and updates the dataset in Superset.\n # @SIDE_EFFECT Calls LLM API and updates dataset metadata in Superset.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dataset_id = params.get(\"dataset_id\")\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Fetch Metadata (US2 / T024)\n from ...core.superset_client import SupersetClient\n client = SupersetClient(env)\n\n superset_log.debug(f\"Fetching dataset {dataset_id}\")\n dataset = client.get_dataset(int(dataset_id))\n\n # Extract columns and existing descriptions\n columns_data = []\n for col in dataset.get(\"columns\", []):\n columns_data.append({\n \"name\": col.get(\"column_name\"),\n \"type\": col.get(\"type\"),\n \"description\": col.get(\"description\")\n })\n superset_log.debug(f\"Extracted {len(columns_data)} columns from dataset\")\n\n # 4. Construct Prompt & Analyze (US2 / T025)\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n documentation_prompt = llm_settings[\"prompts\"].get(\n \"documentation_prompt\",\n DEFAULT_LLM_PROMPTS[\"documentation_prompt\"],\n )\n prompt = render_prompt(\n documentation_prompt,\n {\n \"dataset_name\": dataset.get(\"table_name\") or \"\",\n \"columns_json\": json.dumps(columns_data, ensure_ascii=False),\n },\n )\n\n # Using a generic chat completion for text-only US2\n llm_log.info(f\"Generating documentation for dataset {dataset_id}\")\n doc_result = await llm_client.get_json_completion([{\"role\": \"user\", \"content\": prompt}])\n\n # 5. Update Metadata (US2 / T026)\n update_payload = {\n \"description\": doc_result[\"dataset_description\"],\n \"columns\": []\n }\n\n # Map generated descriptions back to column IDs\n for col_doc in doc_result[\"column_descriptions\"]:\n for col in dataset.get(\"columns\", []):\n if col.get(\"column_name\") == col_doc[\"name\"]:\n update_payload[\"columns\"].append({\n \"id\": col.get(\"id\"),\n \"description\": col_doc[\"description\"]\n })\n\n superset_log.info(f\"Updating dataset {dataset_id} with generated documentation\")\n client.update_dataset(int(dataset_id), update_payload)\n\n log.info(f\"Documentation completed for dataset {dataset_id}\")\n\n return doc_result\n\n finally:\n db.close()\n # endregion DocumentationPlugin.execute\n# #endregion DocumentationPlugin\n"
+ "body": "# #region DocumentationPlugin [TYPE Class]\n# @BRIEF Plugin for automated dataset documentation using LLMs.\n# @RELATION IMPLEMENTS -> [PluginBase]\nclass DocumentationPlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"llm_documentation\"\n\n @property\n def name(self) -> str:\n return \"Dataset LLM Documentation\"\n\n @property\n def description(self) -> str:\n return \"Automated dataset and column documentation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"dataset_id\": {\"type\": \"string\", \"title\": \"Dataset ID\"},\n \"environment_id\": {\"type\": \"string\", \"title\": \"Environment ID\"},\n \"provider_id\": {\"type\": \"string\", \"title\": \"LLM Provider ID\"}\n },\n \"required\": [\"dataset_id\", \"environment_id\", \"provider_id\"]\n }\n\n # region DocumentationPlugin.execute [TYPE Function]\n # @PURPOSE: Executes the dataset documentation task with TaskContext support.\n # @PARAM params (Dict[str, Any]) - Documentation parameters.\n # @PARAM context (Optional[TaskContext]) - Task context for logging with source attribution.\n # @PRE params contains dataset_id, environment_id, and provider_id.\n # @POST Returns generated documentation and updates the dataset in Superset.\n # @SIDE_EFFECT Calls LLM API and updates dataset metadata in Superset.\n async def execute(self, params: dict[str, Any], context: TaskContext | None = None):\n with belief_scope(\"execute\", f\"plugin_id={self.id}\"):\n # Use TaskContext logger if available, otherwise fall back to app logger\n log = context.logger if context else logger\n\n # Create sub-loggers for different components\n llm_log = log.with_source(\"llm\") if context else log\n superset_log = log.with_source(\"superset_api\") if context else log\n\n log.info(f\"Executing {self.name} with params: {params}\")\n\n dataset_id = params.get(\"dataset_id\")\n env_id = params.get(\"environment_id\")\n provider_id = params.get(\"provider_id\")\n\n db = SessionLocal()\n try:\n # 1. Get Environment\n from ...dependencies import get_config_manager\n config_mgr = get_config_manager()\n env = config_mgr.get_environment(env_id)\n if not env:\n log.error(f\"Environment {env_id} not found\")\n raise ValueError(f\"Environment {env_id} not found\")\n\n # 2. Get LLM Provider\n llm_service = LLMProviderService(db)\n db_provider = llm_service.get_provider(provider_id)\n if not db_provider:\n log.error(f\"LLM Provider {provider_id} not found\")\n raise ValueError(f\"LLM Provider {provider_id} not found\")\n\n llm_log.debug(\"Retrieved provider config:\")\n llm_log.debug(f\" Provider ID: {db_provider.id}\")\n llm_log.debug(f\" Provider Name: {db_provider.name}\")\n llm_log.debug(f\" Provider Type: {db_provider.provider_type}\")\n llm_log.debug(f\" Base URL: {db_provider.base_url}\")\n llm_log.debug(f\" Default Model: {db_provider.default_model}\")\n\n api_key = llm_service.get_decrypted_api_key(provider_id)\n llm_log.debug(f\"API Key decrypted (first 8 chars): {api_key[:8] if api_key and len(api_key) > 8 else 'EMPTY_OR_NONE'}...\")\n\n # Check if API key was successfully decrypted\n if _is_masked_or_invalid_api_key(api_key):\n raise ValueError(\n f\"Invalid API key for provider {provider_id}. \"\n \"Please open LLM provider settings and save a real API key (not masked placeholder).\"\n )\n\n # 3. Fetch Metadata (US2 / T024)\n from ...core.superset_client import SupersetClient\n client = SupersetClient(env)\n\n superset_log.debug(f\"Fetching dataset {dataset_id}\")\n dataset = client.get_dataset(int(dataset_id))\n\n # Extract columns and existing descriptions\n columns_data = []\n for col in dataset.get(\"columns\", []):\n columns_data.append({\n \"name\": col.get(\"column_name\"),\n \"type\": col.get(\"type\"),\n \"description\": col.get(\"description\")\n })\n superset_log.debug(f\"Extracted {len(columns_data)} columns from dataset\")\n\n # 4. Construct Prompt & Analyze (US2 / T025)\n llm_client = LLMClient(\n provider_type=LLMProviderType(db_provider.provider_type),\n api_key=api_key,\n base_url=db_provider.base_url,\n default_model=db_provider.default_model\n )\n\n llm_settings = normalize_llm_settings(config_mgr.get_config().settings.llm)\n documentation_prompt = llm_settings[\"prompts\"].get(\n \"documentation_prompt\",\n DEFAULT_LLM_PROMPTS[\"documentation_prompt\"],\n )\n prompt = render_prompt(\n documentation_prompt,\n {\n \"dataset_name\": dataset.get(\"table_name\") or \"\",\n \"columns_json\": json.dumps(columns_data, ensure_ascii=False),\n },\n )\n\n # Using a generic chat completion for text-only US2\n llm_log.info(f\"Generating documentation for dataset {dataset_id}\")\n doc_result = await llm_client.get_json_completion([{\"role\": \"user\", \"content\": prompt}])\n\n # 5. Update Metadata (US2 / T026)\n update_payload = {\n \"description\": doc_result[\"dataset_description\"],\n \"columns\": []\n }\n\n # Map generated descriptions back to column IDs\n for col_doc in doc_result[\"column_descriptions\"]:\n for col in dataset.get(\"columns\", []):\n if col.get(\"column_name\") == col_doc[\"name\"]:\n update_payload[\"columns\"].append({\n \"id\": col.get(\"id\"),\n \"description\": col_doc[\"description\"]\n })\n\n superset_log.info(f\"Updating dataset {dataset_id} with generated documentation\")\n client.update_dataset(int(dataset_id), update_payload)\n\n log.info(f\"Documentation completed for dataset {dataset_id}\")\n\n return doc_result\n\n finally:\n db.close()\n # endregion DocumentationPlugin.execute\n# #endregion DocumentationPlugin\n"
},
{
"contract_id": "LLMAnalysisScheduler",
@@ -35706,7 +35816,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TestDictionaryLegacyHub [C:3] [TYPE Module] [SEMANTICS test, dictionary, hub]\n# @BRIEF Legacy test module — all tests migrated to domain-specific test files:\n# test_dictionary_crud.py — DictionaryCRUD + DictionaryEntryCRUD\n# test_dictionary_import.py — Import/export operations\n# test_dictionary_filter.py — Batch filter + migration\n# test_dictionary_correction.py — Correction context capture\n# test_dictionary_prompt_builder.py — Prompt builder operations\n# test_dictionary[EXT:internal:_utils].py — Utility functions\n# @RELATION BINDS_TO -> [DictionaryManager]\n# @RATIONALE Split monolithic test module into domain-specific files per INV_7.\n# @REJECTED Keeping 1199-line test module violates module < 400 lines constraint.\n\n# All tests have been migrated to the following modules:\nfrom .test_dictionary_correction import * # noqa: F401, F403\nfrom .test_dictionary_crud import * # noqa: F401, F403\nfrom .test_dictionary_filter import * # noqa: F401, F403\nfrom .test_dictionary_import import * # noqa: F401, F403\nfrom .test_dictionary_prompt_builder import * # noqa: F401, F403\nfrom .test_dictionary[EXT:internal:_utils] import * # noqa: F401, F403\n# #endregion TestDictionaryLegacyHub\n"
+ "body": "# #region TestDictionaryLegacyHub [C:3] [TYPE Module] [SEMANTICS test, dictionary, hub]\n# @BRIEF Legacy test module — all tests migrated to domain-specific test files:\n# test_dictionary_crud.py — DictionaryCRUD + DictionaryEntryCRUD\n# test_dictionary_import.py — Import/export operations\n# test_dictionary_filter.py — Batch filter + migration\n# test_dictionary_correction.py — Correction context capture\n# test_dictionary_prompt_builder.py — Prompt builder operations\n# test_dictionary_utils.py — Utility functions\n# @RELATION BINDS_TO -> [DictionaryManager]\n# @RATIONALE Split monolithic test module into domain-specific files per INV_7.\n# @REJECTED Keeping 1199-line test module violates module < 400 lines constraint.\n\n# All tests have been migrated to the following modules:\nfrom .test_dictionary_correction import * # noqa: F401, F403\nfrom .test_dictionary_crud import * # noqa: F401, F403\nfrom .test_dictionary_filter import * # noqa: F401, F403\nfrom .test_dictionary_import import * # noqa: F401, F403\nfrom .test_dictionary_prompt_builder import * # noqa: F401, F403\nfrom .test_dictionary_utils import * # noqa: F401, F403\n# #endregion TestDictionaryLegacyHub\n"
},
{
"contract_id": "TestDictionaryCorrection",
@@ -35858,14 +35968,14 @@
{
"source_id": "TestDictionaryUtils",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:internal:_utils]",
- "target_ref": "[[EXT:internal:_utils]]"
+ "target_id": "TranslationUtils",
+ "target_ref": "[TranslationUtils]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TestDictionaryUtils [C:3] [TYPE Module] [SEMANTICS test, dictionary, utils, normalization]\n# @BRIEF Validate utility functions: _normalize_term and _detect_delimiter.\n# @RELATION BINDS_TO -> [[EXT:internal:_utils]]\n\nfrom src.plugins.translate.[EXT:internal:_utils] import _detect_delimiter, _normalize_term\n\n\nclass TestNormalizeTerm:\n \"\"\"Verify _normalize_term produces lowercase NFC-normalized strings.\"\"\"\n\n # region test_normalize_term [C:2] [TYPE Function]\n def test_normalize_term(self):\n assert _normalize_term(\"Hello\") == \"hello\"\n assert _normalize_term(\"HELLO\") == \"hello\"\n assert _normalize_term(\" hello \") == \"hello\"\n composed = \"\\u00C9\"\n decomposed = \"\\u0045\\u0301\"\n assert _normalize_term(composed) == _normalize_term(decomposed)\n # endregion test_normalize_term\n\n\nclass TestDetectDelimiter:\n \"\"\"Verify _detect_delimiter correctly identifies CSV vs TSV.\"\"\"\n\n # region test_detect_delimiter [C:2] [TYPE Function]\n def test_detect_delimiter(self):\n csv_content = \"source_term,target_term,context_notes\\nhello,hola,\"\n assert _detect_delimiter(csv_content) == \",\"\n\n tsv_content = \"source_term\\ttarget_term\\nhello\\thola\"\n assert _detect_delimiter(tsv_content) == \"\\t\"\n\n empty_content = \"\"\n assert _detect_delimiter(empty_content) == \",\"\n # endregion test_detect_delimiter\n# #endregion TestDictionaryUtils\n"
+ "body": "# #region TestDictionaryUtils [C:3] [TYPE Module] [SEMANTICS test, dictionary, utils, normalization]\n# @BRIEF Validate utility functions: _normalize_term and _detect_delimiter.\n# @RELATION BINDS_TO -> [TranslationUtils]\n\nfrom src.plugins.translate._utils import _detect_delimiter, _normalize_term\n\n\nclass TestNormalizeTerm:\n \"\"\"Verify _normalize_term produces lowercase NFC-normalized strings.\"\"\"\n\n # region test_normalize_term [C:2] [TYPE Function]\n def test_normalize_term(self):\n assert _normalize_term(\"Hello\") == \"hello\"\n assert _normalize_term(\"HELLO\") == \"hello\"\n assert _normalize_term(\" hello \") == \"hello\"\n composed = \"\\u00C9\"\n decomposed = \"\\u0045\\u0301\"\n assert _normalize_term(composed) == _normalize_term(decomposed)\n # endregion test_normalize_term\n\n\nclass TestDetectDelimiter:\n \"\"\"Verify _detect_delimiter correctly identifies CSV vs TSV.\"\"\"\n\n # region test_detect_delimiter [C:2] [TYPE Function]\n def test_detect_delimiter(self):\n csv_content = \"source_term,target_term,context_notes\\nhello,hola,\"\n assert _detect_delimiter(csv_content) == \",\"\n\n tsv_content = \"source_term\\ttarget_term\\nhello\\thola\"\n assert _detect_delimiter(tsv_content) == \"\\t\"\n\n empty_content = \"\"\n assert _detect_delimiter(empty_content) == \",\"\n # endregion test_detect_delimiter\n# #endregion TestDictionaryUtils\n"
},
{
"contract_id": "LanguageDetectServiceTests",
@@ -36029,14 +36139,14 @@
{
"source_id": "TestTextCleaner",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:internal:_text_cleaner]",
- "target_ref": "[[EXT:internal:_text_cleaner]]"
+ "target_id": "TextCleaner",
+ "target_ref": "[TextCleaner]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TestTextCleaner [C:3] [TYPE Module] [SEMANTICS test, text, cleaner, whitespace, truncation]\n# @BRIEF Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.\n# @RELATION BINDS_TO -> [[EXT:internal:_text_cleaner]]\n# @TEST_EDGE empty_string — empty/whitespace-only input returns \"\"\n# @TEST_EDGE whitespace_variants — multiple spaces, newlines, tabs all collapse to single space\n# @TEST_EDGE truncation_boundary — text shorter than, equal to, and longer than max_length\n# @TEST_EDGE clean_combined — clean_text correctly chains normalize + truncate\n# @TEST_EDGE zero_max_length — max_length=0 forces truncation on any non-empty text\n\nfrom src.plugins.translate.[EXT:internal:_text_cleaner] import clean_text, normalize_whitespace, truncate_text\n\n\n# region TestNormalizeWhitespace [TYPE Class]\n# @BRIEF Test suite for normalize_whitespace.\nclass TestNormalizeWhitespace:\n\n # region test_empty_string [TYPE Function]\n # @BRIEF Empty string returns empty string.\n def test_empty_string(self):\n assert normalize_whitespace(\"\") == \"\"\n # endregion test_empty_string\n\n # region test_whitespace_only [TYPE Function]\n # @BRIEF String with only whitespace returns empty string.\n def test_whitespace_only(self):\n assert normalize_whitespace(\" \") == \"\"\n assert normalize_whitespace(\"\\t\") == \"\"\n assert normalize_whitespace(\"\\n\") == \"\"\n # endregion test_whitespace_only\n\n # region test_multiple_spaces [TYPE Function]\n # @BRIEF Multiple spaces between words are collapsed to single space.\n def test_multiple_spaces(self):\n assert normalize_whitespace(\"hello world\") == \"hello world\"\n # endregion test_multiple_spaces\n\n # region test_multiple_newlines [TYPE Function]\n # @BRIEF Multiple newlines are collapsed to single space.\n def test_multiple_newlines(self):\n assert normalize_whitespace(\"hello\\n\\n\\nworld\") == \"hello world\"\n # endregion test_multiple_newlines\n\n # region test_mixed_whitespace [TYPE Function]\n # @BRIEF Tabs, newlines, and spaces all collapse to single space.\n def test_mixed_whitespace(self):\n assert normalize_whitespace(\"hello\\t \\n world\") == \"hello world\"\n # endregion test_mixed_whitespace\n\n # region test_leading_trailing_whitespace [TYPE Function]\n # @BRIEF Leading and trailing whitespace is trimmed.\n def test_leading_trailing_whitespace(self):\n assert normalize_whitespace(\" hello world \") == \"hello world\"\n assert normalize_whitespace(\"\\nhello world\\n\") == \"hello world\"\n # endregion test_leading_trailing_whitespace\n\n # region test_already_clean [TYPE Function]\n # @BRIEF Already clean text is returned unchanged.\n def test_already_clean(self):\n assert normalize_whitespace(\"hello world\") == \"hello world\"\n # endregion test_already_clean\n\n # region test_single_word [TYPE Function]\n # @BRIEF Single word with surrounding whitespace is trimmed to the word.\n def test_single_word(self):\n assert normalize_whitespace(\" hello \") == \"hello\"\n # endregion test_single_word\n\n# endregion TestNormalizeWhitespace\n\n\n# region TestTruncateText [TYPE Class]\n# @BRIEF Test suite for truncate_text.\nclass TestTruncateText:\n\n # region test_empty_string [TYPE Function]\n # @BRIEF Empty string stays empty regardless of max_length.\n def test_empty_string(self):\n assert truncate_text(\"\") == \"\"\n assert truncate_text(\"\", max_length=0) == \"\"\n # endregion test_empty_string\n\n # region test_shorter_than_max [TYPE Function]\n # @BRIEF Text shorter than max_length is returned unchanged.\n def test_shorter_than_max(self):\n assert truncate_text(\"hi\", max_length=5) == \"hi\"\n # endregion test_shorter_than_max\n\n # region test_exactly_at_max [TYPE Function]\n # @BRIEF Text exactly at max_length is returned unchanged (no \"...\" appended).\n def test_exactly_at_max(self):\n assert truncate_text(\"hello\", max_length=5) == \"hello\"\n # endregion test_exactly_at_max\n\n # region test_longer_than_max [TYPE Function]\n # @BRIEF Text longer than max_length is truncated with \"...\" appended.\n def test_longer_than_max(self):\n result = truncate_text(\"hello world\", max_length=5)\n assert result == \"hello...\"\n assert len(result) == 8 # 5 chars + \"...\"\n # endregion test_longer_than_max\n\n # region test_zero_max_length [TYPE Function]\n # @BRIEF max_length=0 truncates any non-empty text to \"...\".\n def test_zero_max_length(self):\n assert truncate_text(\"hello\", max_length=0) == \"...\"\n # endregion test_zero_max_length\n\n # region test_default_max_length [TYPE Function]\n # @BRIEF Default max_length of 500 does not truncate short text.\n def test_default_max_length(self):\n text = \"x\" * 100\n assert truncate_text(text) == text\n # endregion test_default_max_length\n\n # region test_truncation_at_default_boundary [TYPE Function]\n # @BRIEF Text exactly 500 chars is unchanged; 501 chars is truncated.\n def test_truncation_at_default_boundary(self):\n text_500 = \"x\" * 500\n text_501 = \"x\" * 501\n assert truncate_text(text_500) == text_500\n result = truncate_text(text_501)\n assert result == \"x\" * 500 + \"...\"\n assert len(result) == 503\n # endregion test_truncation_at_default_boundary\n\n# endregion TestTruncateText\n\n\n# region TestCleanText [TYPE Class]\n# @BRIEF Test suite for clean_text (combined normalize + truncate).\nclass TestCleanText:\n\n # region test_empty_string [TYPE Function]\n # @BRIEF Empty string returns empty string.\n def test_empty_string(self):\n assert clean_text(\"\") == \"\"\n # endregion test_empty_string\n\n # region test_whitespace_only [TYPE Function]\n # @BRIEF Whitespace-only input returns empty string.\n def test_whitespace_only(self):\n assert clean_text(\" \\n \\t \") == \"\"\n # endregion test_whitespace_only\n\n # region test_clean_and_short [TYPE Function]\n # @BRIEF Already clean, short text is returned unchanged.\n def test_clean_and_short(self):\n assert clean_text(\"hello world\") == \"hello world\"\n # endregion test_clean_and_short\n\n # region test_normalize_then_truncate [TYPE Function]\n # @BRIEF Whitespace is normalized before truncation — counting clean chars.\n def test_normalize_then_truncate(self):\n # \"hello world\" has 15 chars raw, normalized to \"hello world\" (11 chars)\n # With max_length=5, should truncate normalized text to \"hello...\"\n result = clean_text(\"hello world\", max_length=5)\n assert result == \"hello...\"\n # endregion test_normalize_then_truncate\n\n # region test_normalize_keeps_text_under_limit [TYPE Function]\n # @BRIEF Normalization reduces length enough that truncation is not needed.\n def test_normalize_keeps_text_under_limit(self):\n # \"A B\" has 4 chars raw, normalizes to \"A B\" (3 chars), still under 5\n result = clean_text(\"A B\", max_length=5)\n assert result == \"A B\"\n # endregion test_normalize_keeps_text_under_limit\n\n # region test_leading_whitespace_then_truncate [TYPE Function]\n # @BRIEF Leading whitespace is removed before truncation, avoiding wasted chars.\n def test_leading_whitespace_then_truncate(self):\n # \" hello world\" normalizes to \"hello world\" (11 chars)\n # With max_length=5: truncates to \"hello...\"\n result = clean_text(\" hello world\", max_length=5)\n assert result == \"hello...\"\n # endregion test_leading_whitespace_then_truncate\n\n # region test_default_max_length_passthrough [TYPE Function]\n # @BRIEF With default max_length=500, text under 500 after normalize is unchanged.\n def test_default_max_length_passthrough(self):\n text = \" hello world \"\n expected = \"hello world\"\n assert clean_text(text) == expected\n # endregion test_default_max_length_passthrough\n\n# endregion TestCleanText\n# #endregion TestTextCleaner\n"
+ "body": "# #region TestTextCleaner [C:3] [TYPE Module] [SEMANTICS test, text, cleaner, whitespace, truncation]\n# @BRIEF Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.\n# @RELATION BINDS_TO -> [TextCleaner]\n# @TEST_EDGE empty_string — empty/whitespace-only input returns \"\"\n# @TEST_EDGE whitespace_variants — multiple spaces, newlines, tabs all collapse to single space\n# @TEST_EDGE truncation_boundary — text shorter than, equal to, and longer than max_length\n# @TEST_EDGE clean_combined — clean_text correctly chains normalize + truncate\n# @TEST_EDGE zero_max_length — max_length=0 forces truncation on any non-empty text\n\nfrom src.plugins.translate._text_cleaner import clean_text, normalize_whitespace, truncate_text\n\n\n# region TestNormalizeWhitespace [TYPE Class]\n# @BRIEF Test suite for normalize_whitespace.\nclass TestNormalizeWhitespace:\n\n # region test_empty_string [TYPE Function]\n # @BRIEF Empty string returns empty string.\n def test_empty_string(self):\n assert normalize_whitespace(\"\") == \"\"\n # endregion test_empty_string\n\n # region test_whitespace_only [TYPE Function]\n # @BRIEF String with only whitespace returns empty string.\n def test_whitespace_only(self):\n assert normalize_whitespace(\" \") == \"\"\n assert normalize_whitespace(\"\\t\") == \"\"\n assert normalize_whitespace(\"\\n\") == \"\"\n # endregion test_whitespace_only\n\n # region test_multiple_spaces [TYPE Function]\n # @BRIEF Multiple spaces between words are collapsed to single space.\n def test_multiple_spaces(self):\n assert normalize_whitespace(\"hello world\") == \"hello world\"\n # endregion test_multiple_spaces\n\n # region test_multiple_newlines [TYPE Function]\n # @BRIEF Multiple newlines are collapsed to single space.\n def test_multiple_newlines(self):\n assert normalize_whitespace(\"hello\\n\\n\\nworld\") == \"hello world\"\n # endregion test_multiple_newlines\n\n # region test_mixed_whitespace [TYPE Function]\n # @BRIEF Tabs, newlines, and spaces all collapse to single space.\n def test_mixed_whitespace(self):\n assert normalize_whitespace(\"hello\\t \\n world\") == \"hello world\"\n # endregion test_mixed_whitespace\n\n # region test_leading_trailing_whitespace [TYPE Function]\n # @BRIEF Leading and trailing whitespace is trimmed.\n def test_leading_trailing_whitespace(self):\n assert normalize_whitespace(\" hello world \") == \"hello world\"\n assert normalize_whitespace(\"\\nhello world\\n\") == \"hello world\"\n # endregion test_leading_trailing_whitespace\n\n # region test_already_clean [TYPE Function]\n # @BRIEF Already clean text is returned unchanged.\n def test_already_clean(self):\n assert normalize_whitespace(\"hello world\") == \"hello world\"\n # endregion test_already_clean\n\n # region test_single_word [TYPE Function]\n # @BRIEF Single word with surrounding whitespace is trimmed to the word.\n def test_single_word(self):\n assert normalize_whitespace(\" hello \") == \"hello\"\n # endregion test_single_word\n\n# endregion TestNormalizeWhitespace\n\n\n# region TestTruncateText [TYPE Class]\n# @BRIEF Test suite for truncate_text.\nclass TestTruncateText:\n\n # region test_empty_string [TYPE Function]\n # @BRIEF Empty string stays empty regardless of max_length.\n def test_empty_string(self):\n assert truncate_text(\"\") == \"\"\n assert truncate_text(\"\", max_length=0) == \"\"\n # endregion test_empty_string\n\n # region test_shorter_than_max [TYPE Function]\n # @BRIEF Text shorter than max_length is returned unchanged.\n def test_shorter_than_max(self):\n assert truncate_text(\"hi\", max_length=5) == \"hi\"\n # endregion test_shorter_than_max\n\n # region test_exactly_at_max [TYPE Function]\n # @BRIEF Text exactly at max_length is returned unchanged (no \"...\" appended).\n def test_exactly_at_max(self):\n assert truncate_text(\"hello\", max_length=5) == \"hello\"\n # endregion test_exactly_at_max\n\n # region test_longer_than_max [TYPE Function]\n # @BRIEF Text longer than max_length is truncated with \"...\" appended.\n def test_longer_than_max(self):\n result = truncate_text(\"hello world\", max_length=5)\n assert result == \"hello...\"\n assert len(result) == 8 # 5 chars + \"...\"\n # endregion test_longer_than_max\n\n # region test_zero_max_length [TYPE Function]\n # @BRIEF max_length=0 truncates any non-empty text to \"...\".\n def test_zero_max_length(self):\n assert truncate_text(\"hello\", max_length=0) == \"...\"\n # endregion test_zero_max_length\n\n # region test_default_max_length [TYPE Function]\n # @BRIEF Default max_length of 500 does not truncate short text.\n def test_default_max_length(self):\n text = \"x\" * 100\n assert truncate_text(text) == text\n # endregion test_default_max_length\n\n # region test_truncation_at_default_boundary [TYPE Function]\n # @BRIEF Text exactly 500 chars is unchanged; 501 chars is truncated.\n def test_truncation_at_default_boundary(self):\n text_500 = \"x\" * 500\n text_501 = \"x\" * 501\n assert truncate_text(text_500) == text_500\n result = truncate_text(text_501)\n assert result == \"x\" * 500 + \"...\"\n assert len(result) == 503\n # endregion test_truncation_at_default_boundary\n\n# endregion TestTruncateText\n\n\n# region TestCleanText [TYPE Class]\n# @BRIEF Test suite for clean_text (combined normalize + truncate).\nclass TestCleanText:\n\n # region test_empty_string [TYPE Function]\n # @BRIEF Empty string returns empty string.\n def test_empty_string(self):\n assert clean_text(\"\") == \"\"\n # endregion test_empty_string\n\n # region test_whitespace_only [TYPE Function]\n # @BRIEF Whitespace-only input returns empty string.\n def test_whitespace_only(self):\n assert clean_text(\" \\n \\t \") == \"\"\n # endregion test_whitespace_only\n\n # region test_clean_and_short [TYPE Function]\n # @BRIEF Already clean, short text is returned unchanged.\n def test_clean_and_short(self):\n assert clean_text(\"hello world\") == \"hello world\"\n # endregion test_clean_and_short\n\n # region test_normalize_then_truncate [TYPE Function]\n # @BRIEF Whitespace is normalized before truncation — counting clean chars.\n def test_normalize_then_truncate(self):\n # \"hello world\" has 15 chars raw, normalized to \"hello world\" (11 chars)\n # With max_length=5, should truncate normalized text to \"hello...\"\n result = clean_text(\"hello world\", max_length=5)\n assert result == \"hello...\"\n # endregion test_normalize_then_truncate\n\n # region test_normalize_keeps_text_under_limit [TYPE Function]\n # @BRIEF Normalization reduces length enough that truncation is not needed.\n def test_normalize_keeps_text_under_limit(self):\n # \"A B\" has 4 chars raw, normalizes to \"A B\" (3 chars), still under 5\n result = clean_text(\"A B\", max_length=5)\n assert result == \"A B\"\n # endregion test_normalize_keeps_text_under_limit\n\n # region test_leading_whitespace_then_truncate [TYPE Function]\n # @BRIEF Leading whitespace is removed before truncation, avoiding wasted chars.\n def test_leading_whitespace_then_truncate(self):\n # \" hello world\" normalizes to \"hello world\" (11 chars)\n # With max_length=5: truncates to \"hello...\"\n result = clean_text(\" hello world\", max_length=5)\n assert result == \"hello...\"\n # endregion test_leading_whitespace_then_truncate\n\n # region test_default_max_length_passthrough [TYPE Function]\n # @BRIEF With default max_length=500, text under 500 after normalize is unchanged.\n def test_default_max_length_passthrough(self):\n text = \" hello world \"\n expected = \"hello world\"\n assert clean_text(text) == expected\n # endregion test_default_max_length_passthrough\n\n# endregion TestCleanText\n# #endregion TestTextCleaner\n"
},
{
"contract_id": "TestTokenBudget",
@@ -36236,7 +36346,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region BatchProcessingService [C:4] [TYPE Module] [SEMANTICS translate, batch, process, classify, cache]\n# @BRIEF Batch processing for translation: classify rows (same-language/cache/preview/LLM),\n# call LLM service, persist TranslationRecord/TranslationLanguage rows.\n# Local language detection (lingua) replaces LLM-based detection.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationBatch], [TranslationRecord], [TranslationLanguage]\n# @RELATION DEPENDS_ON -> [DictionaryManager], [LLMTranslationService], [LanguageDetectService]\n# @RELATION DEPENDS_ON -> [estimate_token_budget], [ConfigManager]\n# @PRE DB session is available. Job configuration is valid.\n# @POST TranslationBatch, TranslationRecord, TranslationLanguage rows created and committed.\n# @SIDE_EFFECT LLM API calls via LLMTranslationService; DB writes.\n# @RATIONALE Extracted from TranslationExecutor. Batch insert delegated to _batch_insert.py.\n# @REJECTED Keeping batch processing inside TranslationExecutor — caused class to exceed INV_7.\n\nfrom datetime import UTC, datetime\nimport time\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationBatch, TranslationJob, TranslationLanguage, TranslationRecord\nfrom ...services.llm_provider import LLMProviderService\nfrom ._batch_insert import insert_batch_to_target\nfrom ._lang_detect import batch_detect, get_detector\nfrom ._llm_call import LLMTranslationService\nfrom ._token_budget import estimate_token_budget\nfrom .[EXT:internal:_utils] import _check_translation_cache, _compute_key_hash, _compute_source_hash\nfrom .dictionary import DictionaryManager\n\n\n# #region BatchProcessingService [C:4] [TYPE Class]\n# @BRIEF Create batch records, classify rows, process LLM calls, persist results.\nclass BatchProcessingService:\n \"\"\"Process a batch: classify (cache/preview/LLM), persist, and insert to target.\"\"\"\n\n def __init__(self, db: Session, config_manager: ConfigManager) -> None:\n self.db = db\n self.config_manager = config_manager\n self._llm_service = LLMTranslationService(db)\n\n # #region process_batch [C:3] [TYPE Function]\n # @BRIEF Process a single batch: create record, classify rows, call LLM, persist.\n # @PRE job and batch_rows are valid.\n # @POST TranslationBatch and TranslationRecord rows are created.\n # @SIDE_EFFECT LLM API call; DB writes.\n def process_batch(\n self, job: TranslationJob, run_id: str, batch_index: int,\n batch_rows: list[dict[str, Any]],\n dict_snapshot_hash: str | None = None, config_hash: str | None = None,\n preview_edits_cache: dict[str, dict[str, str]] | None = None,\n ) -> dict[str, int]:\n \"\"\"Process a single batch: classify rows, call LLM (if needed), persist records.\"\"\"\n with belief_scope(\"BatchProcessingService.process_batch\"):\n batch_start = time.monotonic()\n batch = self._create_batch(run_id, batch_index, batch_rows)\n bid = batch.id\n result = {\"successful\": 0, \"failed\": 0, \"skipped\": 0, \"retries\": 0}\n\n tls = job.target_languages or [job.target_dialect or \"en\"]\n tls = [str(tls)] if not isinstance(tls, list) else tls\n\n # ★ Run local language detection on all rows (heuristic, no LLM)\n self._detect_languages(batch_rows, tls)\n\n source_texts = [r.get(\"source_text\", \"\") for r in batch_rows if r.get(\"source_text\")]\n rc = batch_rows[0].get(\"source_data\") if batch_rows else None\n dict_matches = DictionaryManager.filter_for_batch(self.db, source_texts, job.id, row_context=rc)\n\n self._check_cache(job, batch_rows, dict_snapshot_hash, config_hash)\n llm_rows, pre_rows = self._classify(batch_rows, preview_edits_cache, tls)\n\n result[\"successful\"] += self._persist_pre(pre_rows, bid, run_id, tls)\n if llm_rows:\n llm_res = self._process_llm(job, run_id, llm_rows, dict_matches, bid, tls)\n for k in (\"successful\", \"failed\", \"skipped\", \"retries\"):\n result[k] += llm_res.get(k, 0)\n\n batch.successful_records = result[\"successful\"]\n batch.failed_records = result[\"failed\"]\n batch.completed_at = datetime.now(UTC)\n batch.status = \"COMPLETED\" if result[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n self.db.flush()\n\n latency = int((time.monotonic() - batch_start) * 1000)\n logger.reason(f\"Batch {batch_index} complete\", {\"batch_id\": bid, \"latency_ms\": latency, **result})\n return {**result, \"batch_id\": bid}\n # #endregion process_batch\n\n def _create_batch(self, run_id, batch_index, batch_rows):\n b = TranslationBatch(id=str(uuid.uuid4()), run_id=run_id, batch_index=batch_index,\n status=\"RUNNING\", total_records=len(batch_rows), started_at=datetime.now(UTC))\n self.db.add(b)\n self.db.flush()\n return b\n\n def _check_cache(self, job, batch_rows, dict_snapshot_hash, config_hash):\n for row in batch_rows:\n if row.get(\"approved_translation\"):\n continue\n st = row.get(\"source_text\", \"\")\n if not st:\n continue\n ctx = list(job.context_columns or [])\n h = _compute_source_hash(st, row.get(\"source_data\"), dict_snapshot_hash, config_hash, ctx)\n row[\"_source_hash\"] = h\n cached = _check_translation_cache(self.db, h)\n if cached:\n row[\"_cached_lang_values\"] = cached\n logger.reason(\"Translation cache hit\", {\"source_hash\": h[:12], \"langs\": list(cached.keys())})\n\n # ★ Local language detection — replaces LLM-based detection\n def _detect_languages(self, batch_rows: list[dict], target_languages: list[str]) -> None:\n \"\"\"Run local language detection on all batch rows (no LLM).\n\n Attaches '_detected_lang' (BCP-47 code or 'und') to each row dict.\n Uses batch_detect() for efficient multi-text processing.\n \"\"\"\n texts = [row.get(\"source_text\", \"\") for row in batch_rows]\n results = batch_detect(texts, target_languages)\n for row, lang in zip(batch_rows, results):\n row[\"_detected_lang\"] = lang\n\n def _classify(self, batch_rows, preview_edits_cache, tls):\n llm_rows, pre_rows = [], []\n tls_lower = [str(t).lower() for t in tls]\n for row in batch_rows:\n # ★ NEW: Same-language pre-filter — detected language matches target\n dl = row.get(\"_detected_lang\")\n if dl and str(dl).lower() not in (\"und\", \"\") and str(dl).lower() in tls_lower:\n row[\"_same_language\"] = True\n pre_rows.append(row)\n continue\n\n if row.get(\"approved_translation\"):\n pre_rows.append(row)\n continue\n cl = row.get(\"_cached_lang_values\")\n if cl:\n if all(lc in cl for lc in tls):\n pre_rows.append(row)\n continue\n if preview_edits_cache:\n sd = row.get(\"source_data\") or {}\n if sd:\n kh = _compute_key_hash(sd)\n pe = preview_edits_cache.get(kh)\n if pe:\n fe = next(iter(pe.values()), None)\n if fe:\n row[\"approved_translation\"] = fe\n pre_rows.append(row)\n continue\n llm_rows.append(row)\n return llm_rows, pre_rows\n\n def _persist_pre(self, pre_rows, bid, run_id, tls):\n count = 0\n for row in pre_rows:\n # ★ Same-language row: source language = target → no translation needed\n if row.get(\"_same_language\"):\n dl = str(row[\"_detected_lang\"])\n source_text = row.get(\"source_text\", \"\")\n rec = TranslationRecord(\n id=str(uuid.uuid4()), batch_id=bid, run_id=run_id,\n source_sql=source_text, target_sql=source_text,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(rec)\n # One TranslationLanguage for the detected (same) language\n self.db.add(TranslationLanguage(\n id=str(uuid.uuid4()), record_id=rec.id, language_code=dl,\n source_language_detected=dl, translated_value=source_text,\n final_value=source_text, status=\"translated\", needs_review=False,\n ))\n count += 1\n continue\n\n # Existing: cached / approved rows\n cl = row.get(\"_cached_lang_values\")\n detected_lang = row.get(\"_detected_lang\", \"und\") or \"und\"\n rec = TranslationRecord(\n id=str(uuid.uuid4()), batch_id=bid, run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"), target_sql=row.get(\"approved_translation\", \"\"),\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(rec)\n for lc in tls:\n fv = cl[lc] if (cl and lc in cl) else row.get(\"approved_translation\", \"\")\n self.db.add(TranslationLanguage(\n id=str(uuid.uuid4()), record_id=rec.id, language_code=lc,\n source_language_detected=detected_lang, translated_value=fv,\n final_value=fv, status=\"translated\", needs_review=False,\n ))\n count += 1\n return count\n\n def _process_llm(self, job, run_id, rows_for_llm, dict_matches, bid, tls):\n provider_model = None\n if job.provider_id:\n try:\n p = LLMProviderService(self.db).get_provider(job.provider_id)\n if p:\n provider_model = p.default_model or \"gpt-4o-mini\"\n except Exception:\n provider_model = None\n\n tb = estimate_token_budget(\n source_rows=rows_for_llm, target_languages=tls,\n source_column=\"source_text\", context_columns=None,\n dictionary_entries=dict_matches, batch_size=len(rows_for_llm),\n provider_info=provider_model,\n )\n if tb[\"warning\"]:\n logger.explore(\"Token budget warning\", {\"batch_id\": bid, \"warning\": tb[\"warning\"]})\n\n return self._llm_service.call_llm_for_batch(\n job=job, run_id=run_id, batch_rows=rows_for_llm,\n dict_matches=dict_matches, batch_id=bid,\n max_tokens=tb[\"max_output_needed\"],\n )\n\n # -- Batch insert (delegation) --\n def insert_batch_to_target(self, job: TranslationJob, batch_id: str, run_id: str) -> None:\n insert_batch_to_target(self.db, self.config_manager, job, batch_id, run_id)\n# #endregion BatchProcessingService\n# #endregion BatchProcessingService\n"
+ "body": "# #region BatchProcessingService [C:4] [TYPE Module] [SEMANTICS translate, batch, process, classify, cache]\n# @BRIEF Batch processing for translation: classify rows (same-language/cache/preview/LLM),\n# call LLM service, persist TranslationRecord/TranslationLanguage rows.\n# Local language detection (lingua) replaces LLM-based detection.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationBatch], [TranslationRecord], [TranslationLanguage]\n# @RELATION DEPENDS_ON -> [DictionaryManager], [LLMTranslationService], [LanguageDetectService]\n# @RELATION DEPENDS_ON -> [estimate_token_budget], [ConfigManager]\n# @PRE DB session is available. Job configuration is valid.\n# @POST TranslationBatch, TranslationRecord, TranslationLanguage rows created and committed.\n# @SIDE_EFFECT LLM API calls via LLMTranslationService; DB writes.\n# @RATIONALE Extracted from TranslationExecutor. Batch insert delegated to _batch_insert.py.\n# @REJECTED Keeping batch processing inside TranslationExecutor — caused class to exceed INV_7.\n\nfrom datetime import UTC, datetime\nimport time\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationBatch, TranslationJob, TranslationLanguage, TranslationRecord\nfrom ...services.llm_provider import LLMProviderService\nfrom ._batch_insert import insert_batch_to_target\nfrom ._lang_detect import batch_detect, get_detector\nfrom ._llm_call import LLMTranslationService\nfrom ._token_budget import estimate_token_budget\nfrom ._utils import _check_translation_cache, _compute_key_hash, _compute_source_hash\nfrom .dictionary import DictionaryManager\n\n\n# #region BatchProcessingService [C:4] [TYPE Class]\n# @BRIEF Create batch records, classify rows, process LLM calls, persist results.\nclass BatchProcessingService:\n \"\"\"Process a batch: classify (cache/preview/LLM), persist, and insert to target.\"\"\"\n\n def __init__(self, db: Session, config_manager: ConfigManager) -> None:\n self.db = db\n self.config_manager = config_manager\n self._llm_service = LLMTranslationService(db)\n\n # #region process_batch [C:3] [TYPE Function]\n # @BRIEF Process a single batch: create record, classify rows, call LLM, persist.\n # @PRE job and batch_rows are valid.\n # @POST TranslationBatch and TranslationRecord rows are created.\n # @SIDE_EFFECT LLM API call; DB writes.\n def process_batch(\n self, job: TranslationJob, run_id: str, batch_index: int,\n batch_rows: list[dict[str, Any]],\n dict_snapshot_hash: str | None = None, config_hash: str | None = None,\n preview_edits_cache: dict[str, dict[str, str]] | None = None,\n ) -> dict[str, int]:\n \"\"\"Process a single batch: classify rows, call LLM (if needed), persist records.\"\"\"\n with belief_scope(\"BatchProcessingService.process_batch\"):\n batch_start = time.monotonic()\n batch = self._create_batch(run_id, batch_index, batch_rows)\n bid = batch.id\n result = {\"successful\": 0, \"failed\": 0, \"skipped\": 0, \"retries\": 0}\n\n tls = job.target_languages or [job.target_dialect or \"en\"]\n tls = [str(tls)] if not isinstance(tls, list) else tls\n\n # ★ Run local language detection on all rows (heuristic, no LLM)\n self._detect_languages(batch_rows, tls)\n\n source_texts = [r.get(\"source_text\", \"\") for r in batch_rows if r.get(\"source_text\")]\n rc = batch_rows[0].get(\"source_data\") if batch_rows else None\n dict_matches = DictionaryManager.filter_for_batch(self.db, source_texts, job.id, row_context=rc)\n\n self._check_cache(job, batch_rows, dict_snapshot_hash, config_hash)\n llm_rows, pre_rows = self._classify(batch_rows, preview_edits_cache, tls)\n\n result[\"successful\"] += self._persist_pre(pre_rows, bid, run_id, tls)\n if llm_rows:\n llm_res = self._process_llm(job, run_id, llm_rows, dict_matches, bid, tls)\n for k in (\"successful\", \"failed\", \"skipped\", \"retries\"):\n result[k] += llm_res.get(k, 0)\n\n batch.successful_records = result[\"successful\"]\n batch.failed_records = result[\"failed\"]\n batch.completed_at = datetime.now(UTC)\n batch.status = \"COMPLETED\" if result[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n self.db.flush()\n\n latency = int((time.monotonic() - batch_start) * 1000)\n logger.reason(f\"Batch {batch_index} complete\", {\"batch_id\": bid, \"latency_ms\": latency, **result})\n return {**result, \"batch_id\": bid}\n # #endregion process_batch\n\n def _create_batch(self, run_id, batch_index, batch_rows):\n b = TranslationBatch(id=str(uuid.uuid4()), run_id=run_id, batch_index=batch_index,\n status=\"RUNNING\", total_records=len(batch_rows), started_at=datetime.now(UTC))\n self.db.add(b)\n self.db.flush()\n return b\n\n def _check_cache(self, job, batch_rows, dict_snapshot_hash, config_hash):\n for row in batch_rows:\n if row.get(\"approved_translation\"):\n continue\n st = row.get(\"source_text\", \"\")\n if not st:\n continue\n ctx = list(job.context_columns or [])\n h = _compute_source_hash(st, row.get(\"source_data\"), dict_snapshot_hash, config_hash, ctx)\n row[\"_source_hash\"] = h\n cached = _check_translation_cache(self.db, h)\n if cached:\n row[\"_cached_lang_values\"] = cached\n logger.reason(\"Translation cache hit\", {\"source_hash\": h[:12], \"langs\": list(cached.keys())})\n\n # ★ Local language detection — replaces LLM-based detection\n def _detect_languages(self, batch_rows: list[dict], target_languages: list[str]) -> None:\n \"\"\"Run local language detection on all batch rows (no LLM).\n\n Attaches '_detected_lang' (BCP-47 code or 'und') to each row dict.\n Uses batch_detect() for efficient multi-text processing.\n \"\"\"\n texts = [row.get(\"source_text\", \"\") for row in batch_rows]\n results = batch_detect(texts, target_languages)\n for row, lang in zip(batch_rows, results):\n row[\"_detected_lang\"] = lang\n\n def _classify(self, batch_rows, preview_edits_cache, tls):\n llm_rows, pre_rows = [], []\n tls_lower = [str(t).lower() for t in tls]\n for row in batch_rows:\n # ★ NEW: Same-language pre-filter — detected language matches target\n dl = row.get(\"_detected_lang\")\n if dl and str(dl).lower() not in (\"und\", \"\") and str(dl).lower() in tls_lower:\n row[\"_same_language\"] = True\n pre_rows.append(row)\n continue\n\n if row.get(\"approved_translation\"):\n pre_rows.append(row)\n continue\n cl = row.get(\"_cached_lang_values\")\n if cl:\n if all(lc in cl for lc in tls):\n pre_rows.append(row)\n continue\n if preview_edits_cache:\n sd = row.get(\"source_data\") or {}\n if sd:\n kh = _compute_key_hash(sd)\n pe = preview_edits_cache.get(kh)\n if pe:\n fe = next(iter(pe.values()), None)\n if fe:\n row[\"approved_translation\"] = fe\n pre_rows.append(row)\n continue\n llm_rows.append(row)\n return llm_rows, pre_rows\n\n def _persist_pre(self, pre_rows, bid, run_id, tls):\n count = 0\n for row in pre_rows:\n # ★ Same-language row: source language = target → no translation needed\n if row.get(\"_same_language\"):\n dl = str(row[\"_detected_lang\"])\n source_text = row.get(\"source_text\", \"\")\n rec = TranslationRecord(\n id=str(uuid.uuid4()), batch_id=bid, run_id=run_id,\n source_sql=source_text, target_sql=source_text,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(rec)\n # One TranslationLanguage for the detected (same) language\n self.db.add(TranslationLanguage(\n id=str(uuid.uuid4()), record_id=rec.id, language_code=dl,\n source_language_detected=dl, translated_value=source_text,\n final_value=source_text, status=\"translated\", needs_review=False,\n ))\n count += 1\n continue\n\n # Existing: cached / approved rows\n cl = row.get(\"_cached_lang_values\")\n detected_lang = row.get(\"_detected_lang\", \"und\") or \"und\"\n rec = TranslationRecord(\n id=str(uuid.uuid4()), batch_id=bid, run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"), target_sql=row.get(\"approved_translation\", \"\"),\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(rec)\n for lc in tls:\n fv = cl[lc] if (cl and lc in cl) else row.get(\"approved_translation\", \"\")\n self.db.add(TranslationLanguage(\n id=str(uuid.uuid4()), record_id=rec.id, language_code=lc,\n source_language_detected=detected_lang, translated_value=fv,\n final_value=fv, status=\"translated\", needs_review=False,\n ))\n count += 1\n return count\n\n def _process_llm(self, job, run_id, rows_for_llm, dict_matches, bid, tls):\n provider_model = None\n if job.provider_id:\n try:\n p = LLMProviderService(self.db).get_provider(job.provider_id)\n if p:\n provider_model = p.default_model or \"gpt-4o-mini\"\n except Exception:\n provider_model = None\n\n tb = estimate_token_budget(\n source_rows=rows_for_llm, target_languages=tls,\n source_column=\"source_text\", context_columns=None,\n dictionary_entries=dict_matches, batch_size=len(rows_for_llm),\n provider_info=provider_model,\n )\n if tb[\"warning\"]:\n logger.explore(\"Token budget warning\", {\"batch_id\": bid, \"warning\": tb[\"warning\"]})\n\n return self._llm_service.call_llm_for_batch(\n job=job, run_id=run_id, batch_rows=rows_for_llm,\n dict_matches=dict_matches, batch_id=bid,\n max_tokens=tb[\"max_output_needed\"],\n )\n\n # -- Batch insert (delegation) --\n def insert_batch_to_target(self, job: TranslationJob, batch_id: str, run_id: str) -> None:\n insert_batch_to_target(self.db, self.config_manager, job, batch_id, run_id)\n# #endregion BatchProcessingService\n# #endregion BatchProcessingService\n"
},
{
"contract_id": "process_batch",
@@ -36275,7 +36385,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region AdaptiveBatchSizer [C:3] [TYPE Module] [SEMANTICS translate, batch, sizing, token-budget]\n# @BRIEF Adaptive batch sizing for LLM translation — splits source rows into variable-sized\n# batches based on actual content length and token budget estimates.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [estimate_token_budget]\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [TranslationJob]\n# @RATIONALE Extracted from TranslationExecutor to comply with INV_7 (module < 400 lines).\n# Fixed batch_size of 50 wastes LLM context for short rows and overflows for\n# long rows. Variable sizing maximizes throughput while preventing truncation.\n# @REJECTED Fixed batch_size of 50 — causes truncation on long-content rows.\n# Single monolithic batch — would lose all progress on any failure.\n\nimport time\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationJob\nfrom ...services.llm_provider import LLMProviderService\nfrom ._token_budget import (\n JSON_OVERHEAD_PER_ROW,\n MAX_OUTPUT_HEADROOM,\n OUTPUT_PER_ROW_PER_LANG,\n PROMPT_BASE_TOKENS,\n REASONING_OVERHEAD,\n estimate_token_budget,\n)\nfrom .[EXT:internal:_utils] import estimate_row_tokens\n\n\n# #region AdaptiveBatchSizer [C:3] [TYPE Class]\n# @BRIEF Split source rows into auto-sized batches based on token budget estimates.\nclass AdaptiveBatchSizer:\n \"\"\"Split source rows into auto-sized batches based on token budget estimates.\n\n Each batch is sized so that its total estimated tokens fit within the\n available context window (input budget), accounting for prompt overhead,\n dictionary entries, and output tokens.\n \"\"\"\n\n def __init__(self, db: Session, config_manager: ConfigManager) -> None:\n self.db = db\n self.config_manager = config_manager\n\n # #region resolve_provider_model [C:2] [TYPE Function] [SEMANTICS llm, provider, model]\n # @BRIEF Resolve the LLM provider model name for token budget estimation.\n # @POST Returns model name string or None if resolution fails.\n # @SIDE_EFFECT DB query to LLM provider table.\n def resolve_provider_model(self, job: TranslationJob) -> str | None:\n \"\"\"Resolve the provider model name for token budget estimation.\"\"\"\n if not job.provider_id:\n return None\n try:\n p_svc = LLMProviderService(self.db)\n p = p_svc.get_provider(job.provider_id)\n if p:\n return p.default_model or \"gpt-4o-mini\"\n except Exception:\n pass\n return None\n # #endregion resolve_provider_model\n\n # #region auto_size_batches [C:3] [TYPE Function] [SEMANTICS translate, batch, sizing]\n # @BRIEF Split source rows into variable-sized batches based on content length.\n # @PRE source_rows is non-empty. job has valid config.\n # @POST Returns list of batches, each batch is a list of row dicts.\n # Each batch fits within the estimated token budget for its rows.\n # @SIDE_EFFECT DB query to resolve provider model. Logs batch statistics.\n def auto_size_batches(\n self,\n job: TranslationJob,\n source_rows: list[dict],\n target_languages: list[str],\n provider_info: str | None = None,\n ) -> list[list[dict]]:\n \"\"\"Split source rows into auto-sized batches based on content length.\n\n Each batch is sized so that its total estimated tokens fit within the\n available context window (input budget), accounting for prompt overhead,\n dictionary entries, and output tokens.\n \"\"\"\n with belief_scope(\"AdaptiveBatchSizer.auto_size_batches\"):\n if not source_rows:\n return []\n\n if provider_info is None:\n provider_info = self.resolve_provider_model(job)\n\n # 1. Estimate per-row token counts\n row_tokens: list[int] = []\n for row in source_rows:\n source_text = row.get(\"source_text\", \"\")\n source_data = row.get(\"source_data\")\n tokens = estimate_row_tokens(source_text, source_data, job)\n row_tokens.append(tokens)\n\n # 2. Get budget recommendation\n budget = estimate_token_budget(\n source_rows=source_rows,\n target_languages=target_languages,\n source_column=job.translation_column or \"source_text\",\n context_columns=job.context_columns,\n batch_size=len(source_rows),\n provider_info=provider_info,\n )\n\n recommended = budget.get(\"batch_size_adjusted\", 0)\n\n # Fallback: if budget calculation fails, use fixed size\n if recommended <= 0:\n fallback_size = job.batch_size or 50\n logger.explore(\"Token budget returned zero — falling back to fixed batch size\", {\n \"fallback_size\": fallback_size,\n \"total_rows\": len(source_rows),\n })\n return [\n source_rows[i:i + fallback_size]\n for i in range(0, len(source_rows), fallback_size)\n ]\n\n # 3. Compute per-batch row-content budget\n # Use the ACTUAL available input capacity (context_window - max_output_tokens),\n # NOT the sum of the first N rows. This prevents long rows from being\n # incorrectly placed in 1-row batches when the context window has plenty of room.\n available_input = budget.get(\"available_input_budget\")\n if available_input is not None:\n # New-style: use actual available input capacity\n per_batch_budget = available_input - PROMPT_BASE_TOKENS\n else:\n # Fallback for tests: use estimated_input (sum of first N rows)\n estimated_input = budget.get(\"estimated_input_tokens\", 50000)\n per_batch_budget = estimated_input - PROMPT_BASE_TOKENS\n\n if per_batch_budget <= 0:\n fallback_size = job.batch_size or 50\n logger.explore(\"Per-batch budget collapsed — falling back to fixed batch size\", {\n \"per_batch_budget\": per_batch_budget,\n \"fallback_size\": fallback_size,\n \"total_rows\": len(source_rows),\n })\n return [\n source_rows[i:i + fallback_size]\n for i in range(0, len(source_rows), fallback_size)\n ]\n\n # 4. Greedy batch splitting\n # Compute max rows per batch from OUTPUT constraint.\n # This prevents output truncation (finish_reason=length) when batching\n # many short rows within the large input budget.\n num_languages = len(target_languages)\n max_output_tokens_val = budget.get(\"max_output_tokens\")\n if max_output_tokens_val is not None:\n output_per_row = num_languages * OUTPUT_PER_ROW_PER_LANG + JSON_OVERHEAD_PER_ROW\n available_output = max_output_tokens_val - REASONING_OVERHEAD - MAX_OUTPUT_HEADROOM\n max_rows_by_output = max(available_output // output_per_row, 1) if output_per_row > 0 else 20\n max_rows_hard_cap = max_rows_by_output\n else:\n # Fallback for tests: old formula\n max_rows_hard_cap = max(recommended * 2, 20)\n\n # 5. Respect job.batch_size as the absolute maximum rows per batch.\n # User-configured batch_size overrides model-based estimates to\n # prevent LLM quality degradation on large batches.\n if job.batch_size:\n max_rows_hard_cap = min(max_rows_hard_cap, job.batch_size)\n\n batches: list[list[dict]] = []\n current_batch: list[dict] = []\n current_tokens = 0\n\n for i, row in enumerate(source_rows):\n rt = row_tokens[i]\n\n if rt > per_batch_budget:\n if current_batch:\n batches.append(current_batch)\n current_batch = []\n current_tokens = 0\n logger.reason(\"Single row exceeds per-batch token budget — placing in own batch\", {\n \"row_index\": i,\n \"row_tokens\": rt,\n \"per_batch_budget\": per_batch_budget,\n })\n batches.append([row])\n continue\n\n should_split = bool(\n current_batch\n and (current_tokens + rt > per_batch_budget\n or len(current_batch) >= max_rows_hard_cap)\n )\n\n if should_split:\n batches.append(current_batch)\n current_batch = [row]\n current_tokens = rt\n else:\n current_batch.append(row)\n current_tokens += rt\n\n if current_batch:\n batches.append(current_batch)\n\n # 5. Log adaptive batch statistics\n if batches:\n avg_size = sum(len(b) for b in batches) / max(1, len(batches))\n max_size = max(len(b) for b in batches)\n logger.reason(\"Auto-sized batches\", {\n \"total_rows\": len(source_rows),\n \"num_batches\": len(batches),\n \"avg_batch_size\": round(avg_size, 1),\n \"max_batch_size\": max_size,\n \"recommended_batch_size\": recommended,\n \"per_batch_budget\": per_batch_budget,\n })\n\n return batches\n # #endregion auto_size_batches\n# #endregion AdaptiveBatchSizer\n# #endregion AdaptiveBatchSizer\n"
+ "body": "# #region AdaptiveBatchSizer [C:3] [TYPE Module] [SEMANTICS translate, batch, sizing, token-budget]\n# @BRIEF Adaptive batch sizing for LLM translation — splits source rows into variable-sized\n# batches based on actual content length and token budget estimates.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [estimate_token_budget]\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [TranslationJob]\n# @RATIONALE Extracted from TranslationExecutor to comply with INV_7 (module < 400 lines).\n# Fixed batch_size of 50 wastes LLM context for short rows and overflows for\n# long rows. Variable sizing maximizes throughput while preventing truncation.\n# @REJECTED Fixed batch_size of 50 — causes truncation on long-content rows.\n# Single monolithic batch — would lose all progress on any failure.\n\nimport time\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationJob\nfrom ...services.llm_provider import LLMProviderService\nfrom ._token_budget import (\n JSON_OVERHEAD_PER_ROW,\n MAX_OUTPUT_HEADROOM,\n OUTPUT_PER_ROW_PER_LANG,\n PROMPT_BASE_TOKENS,\n REASONING_OVERHEAD,\n estimate_token_budget,\n)\nfrom ._utils import estimate_row_tokens\n\n\n# #region AdaptiveBatchSizer [C:3] [TYPE Class]\n# @BRIEF Split source rows into auto-sized batches based on token budget estimates.\nclass AdaptiveBatchSizer:\n \"\"\"Split source rows into auto-sized batches based on token budget estimates.\n\n Each batch is sized so that its total estimated tokens fit within the\n available context window (input budget), accounting for prompt overhead,\n dictionary entries, and output tokens.\n \"\"\"\n\n def __init__(self, db: Session, config_manager: ConfigManager) -> None:\n self.db = db\n self.config_manager = config_manager\n\n # #region resolve_provider_model [C:2] [TYPE Function] [SEMANTICS llm, provider, model]\n # @BRIEF Resolve the LLM provider model name for token budget estimation.\n # @POST Returns model name string or None if resolution fails.\n # @SIDE_EFFECT DB query to LLM provider table.\n def resolve_provider_model(self, job: TranslationJob) -> str | None:\n \"\"\"Resolve the provider model name for token budget estimation.\"\"\"\n if not job.provider_id:\n return None\n try:\n p_svc = LLMProviderService(self.db)\n p = p_svc.get_provider(job.provider_id)\n if p:\n return p.default_model or \"gpt-4o-mini\"\n except Exception:\n pass\n return None\n # #endregion resolve_provider_model\n\n # #region auto_size_batches [C:3] [TYPE Function] [SEMANTICS translate, batch, sizing]\n # @BRIEF Split source rows into variable-sized batches based on content length.\n # @PRE source_rows is non-empty. job has valid config.\n # @POST Returns list of batches, each batch is a list of row dicts.\n # Each batch fits within the estimated token budget for its rows.\n # @SIDE_EFFECT DB query to resolve provider model. Logs batch statistics.\n def auto_size_batches(\n self,\n job: TranslationJob,\n source_rows: list[dict],\n target_languages: list[str],\n provider_info: str | None = None,\n ) -> list[list[dict]]:\n \"\"\"Split source rows into auto-sized batches based on content length.\n\n Each batch is sized so that its total estimated tokens fit within the\n available context window (input budget), accounting for prompt overhead,\n dictionary entries, and output tokens.\n \"\"\"\n with belief_scope(\"AdaptiveBatchSizer.auto_size_batches\"):\n if not source_rows:\n return []\n\n if provider_info is None:\n provider_info = self.resolve_provider_model(job)\n\n # 1. Estimate per-row token counts\n row_tokens: list[int] = []\n for row in source_rows:\n source_text = row.get(\"source_text\", \"\")\n source_data = row.get(\"source_data\")\n tokens = estimate_row_tokens(source_text, source_data, job)\n row_tokens.append(tokens)\n\n # 2. Get budget recommendation\n budget = estimate_token_budget(\n source_rows=source_rows,\n target_languages=target_languages,\n source_column=job.translation_column or \"source_text\",\n context_columns=job.context_columns,\n batch_size=len(source_rows),\n provider_info=provider_info,\n )\n\n recommended = budget.get(\"batch_size_adjusted\", 0)\n\n # Fallback: if budget calculation fails, use fixed size\n if recommended <= 0:\n fallback_size = job.batch_size or 50\n logger.explore(\"Token budget returned zero — falling back to fixed batch size\", {\n \"fallback_size\": fallback_size,\n \"total_rows\": len(source_rows),\n })\n return [\n source_rows[i:i + fallback_size]\n for i in range(0, len(source_rows), fallback_size)\n ]\n\n # 3. Compute per-batch row-content budget\n # Use the ACTUAL available input capacity (context_window - max_output_tokens),\n # NOT the sum of the first N rows. This prevents long rows from being\n # incorrectly placed in 1-row batches when the context window has plenty of room.\n available_input = budget.get(\"available_input_budget\")\n if available_input is not None:\n # New-style: use actual available input capacity\n per_batch_budget = available_input - PROMPT_BASE_TOKENS\n else:\n # Fallback for tests: use estimated_input (sum of first N rows)\n estimated_input = budget.get(\"estimated_input_tokens\", 50000)\n per_batch_budget = estimated_input - PROMPT_BASE_TOKENS\n\n if per_batch_budget <= 0:\n fallback_size = job.batch_size or 50\n logger.explore(\"Per-batch budget collapsed — falling back to fixed batch size\", {\n \"per_batch_budget\": per_batch_budget,\n \"fallback_size\": fallback_size,\n \"total_rows\": len(source_rows),\n })\n return [\n source_rows[i:i + fallback_size]\n for i in range(0, len(source_rows), fallback_size)\n ]\n\n # 4. Greedy batch splitting\n # Compute max rows per batch from OUTPUT constraint.\n # This prevents output truncation (finish_reason=length) when batching\n # many short rows within the large input budget.\n num_languages = len(target_languages)\n max_output_tokens_val = budget.get(\"max_output_tokens\")\n if max_output_tokens_val is not None:\n output_per_row = num_languages * OUTPUT_PER_ROW_PER_LANG + JSON_OVERHEAD_PER_ROW\n available_output = max_output_tokens_val - REASONING_OVERHEAD - MAX_OUTPUT_HEADROOM\n max_rows_by_output = max(available_output // output_per_row, 1) if output_per_row > 0 else 20\n max_rows_hard_cap = max_rows_by_output\n else:\n # Fallback for tests: old formula\n max_rows_hard_cap = max(recommended * 2, 20)\n\n # 5. Respect job.batch_size as the absolute maximum rows per batch.\n # User-configured batch_size overrides model-based estimates to\n # prevent LLM quality degradation on large batches.\n if job.batch_size:\n max_rows_hard_cap = min(max_rows_hard_cap, job.batch_size)\n\n batches: list[list[dict]] = []\n current_batch: list[dict] = []\n current_tokens = 0\n\n for i, row in enumerate(source_rows):\n rt = row_tokens[i]\n\n if rt > per_batch_budget:\n if current_batch:\n batches.append(current_batch)\n current_batch = []\n current_tokens = 0\n logger.reason(\"Single row exceeds per-batch token budget — placing in own batch\", {\n \"row_index\": i,\n \"row_tokens\": rt,\n \"per_batch_budget\": per_batch_budget,\n })\n batches.append([row])\n continue\n\n should_split = bool(\n current_batch\n and (current_tokens + rt > per_batch_budget\n or len(current_batch) >= max_rows_hard_cap)\n )\n\n if should_split:\n batches.append(current_batch)\n current_batch = [row]\n current_tokens = rt\n else:\n current_batch.append(row)\n current_tokens += rt\n\n if current_batch:\n batches.append(current_batch)\n\n # 5. Log adaptive batch statistics\n if batches:\n avg_size = sum(len(b) for b in batches) / max(1, len(batches))\n max_size = max(len(b) for b in batches)\n logger.reason(\"Auto-sized batches\", {\n \"total_rows\": len(source_rows),\n \"num_batches\": len(batches),\n \"avg_batch_size\": round(avg_size, 1),\n \"max_batch_size\": max_size,\n \"recommended_batch_size\": recommended,\n \"per_batch_budget\": per_batch_budget,\n })\n\n return batches\n # #endregion auto_size_batches\n# #endregion AdaptiveBatchSizer\n# #endregion AdaptiveBatchSizer\n"
},
{
"contract_id": "resolve_provider_model",
@@ -36479,7 +36589,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region LLMTranslationService [C:4] [TYPE Module] [SEMANTICS translate, llm, call, orchestrate, retry]\n# @BRIEF LLM interaction for batch translation: call provider with retry, handle truncation\n# by recursive splitting, enforce dictionary post-processing. Orchestrates HTTP calls\n# (_llm_http) and response parsing (_llm_parse).\n# Language detection is now handled locally (lingua) — LLM prompt no longer\n# requests detected_source_language; local _detected_lang takes priority.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [TranslationRecord], [TranslationLanguage]\n# @RELATION DEPENDS_ON -> [ContextAwarePromptBuilder]\n# @RELATION DEPENDS_ON -> [EXT:method:_llm_http], [_llm_parse]\n# @PRE DB session is available. LLM provider is configured on the job.\n# @POST TranslationRecord rows created for LLM-processed rows (success/fail/skip).\n# @SIDE_EFFECT HTTP calls to LLM provider API; DB writes.\n# @RATIONALE Core orchestration logic — HTTP and parse logic extracted to _llm_http.py and\n# _llm_parse.py to meet INV_7 module limit (< 400 lines).\n# @REJECTED Single monolithic call_llm_for_batch at 327 lines — split into focused sub-methods.\n\nfrom datetime import UTC, datetime\nimport json\nimport time\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationBatch, TranslationJob, TranslationLanguage, TranslationRecord\nfrom ...services.llm_prompt_templates import render_prompt\nfrom ...services.llm_provider import LLMProviderService\nfrom ._llm_http import call_openai_compatible\nfrom ._llm_parse import parse_llm_response\nfrom ._token_budget import estimate_token_budget\nfrom .[EXT:internal:_utils] import _enforce_dictionary\nfrom .preview import DEFAULT_EXECUTION_PROMPT_TEMPLATE\nfrom .prompt_builder import ContextAwarePromptBuilder\n\nMAX_RETRIES_PER_BATCH = 3\n\n\n# #region LLMTranslationService [C:4] [TYPE Class]\n# @BRIEF Call LLM, handle retry/truncation, parse response, persist records.\nclass LLMTranslationService:\n \"\"\"LLM interaction for batch translation with retry, truncation handling, and parsing.\"\"\"\n\n def __init__(self, db: Session) -> None:\n self.db = db\n\n # #region call_llm_for_batch [C:3] [TYPE Function] [SEMANTICS translate, llm, batch, orchestrate]\n # @BRIEF Call LLM for a batch of rows requiring translation. Parse and persist results.\n # @PRE job has valid provider_id. batch_rows is non-empty.\n # @POST Returns dict with successful/failed/skipped counts.\n # @SIDE_EFFECT HTTP call to LLM provider; DB writes.\n def call_llm_for_batch(\n self, job: TranslationJob, run_id: str,\n batch_rows: list[dict[str, Any]], dict_matches: list[dict[str, Any]],\n batch_id: str, max_tokens: int = 8192, _recursion_depth: int = 0,\n ) -> dict[str, int]:\n \"\"\"Call LLM for a batch of rows; parse response; create records.\"\"\"\n with belief_scope(\"LLMTranslationService.call_llm_for_batch\"):\n dictionary_section = self._build_dictionary_section(dict_matches, batch_rows)\n target_languages = self._resolve_target_languages(job)\n prompt = self._build_prompt(job, batch_rows, dictionary_section, target_languages)\n\n llm_response, finish_reason, retries, last_error = self._call_llm_with_retry(\n job, prompt, batch_id, max_tokens,\n )\n if llm_response is None:\n return self._handle_llm_failure(batch_rows, run_id, batch_id, retries, last_error)\n\n if finish_reason == \"length\" and len(batch_rows) >= 2 and run_id:\n if _recursion_depth < MAX_RETRIES_PER_BATCH:\n return self._split_and_retry(job, run_id, batch_rows, dict_matches,\n batch_id, max_tokens, _recursion_depth, retries)\n logger.explore(\"Truncation recursion depth exceeded\", {\"batch_id\": batch_id, \"depth\": _recursion_depth})\n\n try:\n translations = parse_llm_response(llm_response, len(batch_rows), target_languages=target_languages)\n except ValueError as e:\n return self._handle_parse_failure(batch_rows, run_id, batch_id, retries, e)\n\n return self._create_records_from_translations(\n batch_rows, run_id, batch_id, target_languages, translations, dict_matches, retries,\n )\n # #endregion call_llm_for_batch\n\n def _build_dictionary_section(self, dict_matches, batch_rows) -> str:\n if not dict_matches:\n return \"\"\n row_context = batch_rows[0].get(\"source_data\") if batch_rows else None\n annotated = ContextAwarePromptBuilder.build_context_entries(dict_matches, row_context)\n return \"Terminology dictionary (use these translations when applicable):\\n\" + \\\n \"\\n\".join(f\"- {a}\" for a in annotated) + \"\\n\\n\"\n\n @staticmethod\n def _resolve_target_languages(job):\n langs = job.target_languages or [job.target_dialect or \"en\"]\n return [str(langs)] if not isinstance(langs, list) else langs\n\n @staticmethod\n def _build_prompt(job, batch_rows, dictionary_section, target_languages):\n target_languages_str = \", \".join(target_languages)\n rows_json = json.dumps([\n {\"row_id\": str(row.get(\"row_index\", idx)), \"text\": row.get(\"source_text\", \"\")}\n for idx, row in enumerate(batch_rows)\n ], indent=2)\n return render_prompt(DEFAULT_EXECUTION_PROMPT_TEMPLATE, {\n \"source_language\": job.source_dialect or \"SQL\",\n \"target_language\": target_languages_str,\n \"target_languages\": target_languages_str,\n \"source_dialect\": job.source_dialect or \"\",\n \"target_dialect\": job.target_dialect or \"\",\n \"translation_column\": job.translation_column or \"\",\n \"dictionary_section\": dictionary_section,\n \"rows_json\": rows_json,\n \"row_count\": str(len(batch_rows)),\n })\n\n def _call_llm_with_retry(self, job, prompt, batch_id, max_tokens):\n llm_response = None\n last_error = None\n retries = 0\n finish_reason = None\n for attempt in range(1, MAX_RETRIES_PER_BATCH + 1):\n try:\n llm_response, finish_reason = self.call_llm(job, prompt, max_tokens=max_tokens)\n break\n except Exception as e:\n last_error = str(e)\n retries += 1\n logger.explore(f\"LLM call failed (attempt {attempt})\", {\"batch_id\": batch_id, \"error\": last_error})\n if attempt < MAX_RETRIES_PER_BATCH:\n time.sleep(2 ** attempt)\n return llm_response, finish_reason, retries, last_error\n\n def _handle_llm_failure(self, batch_rows, run_id, batch_id, retries, last_error):\n for row in batch_rows:\n self.db.add(TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"), target_sql=None,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), status=\"FAILED\",\n error_message=f\"LLM call failed after {retries} retries: {last_error}\",\n ))\n return {\"successful\": 0, \"failed\": len(batch_rows), \"skipped\": 0, \"retries\": retries}\n\n def _split_and_retry(self, job, run_id, batch_rows, dict_matches, batch_id, max_tokens, depth, retries):\n mid = len(batch_rows) // 2\n logger.explore(\"LLM output truncated — splitting batch\",\n {\"batch_id\": batch_id, \"batch_size\": len(batch_rows), \"split_at\": mid, \"depth\": depth})\n\n # Create proper TranslationBatch rows for child halves (fixes FK violation\n # where _L/_R string suffixes referenced non-existent translation_batches rows).\n # @RATIONALE Previous code appended \"_L\"/\"_R\" to batch_id string, violating\n # FK translation_records.batch_id → translation_batches.id.\n # @REJECTED Continuing with string-suffixed batch_ids — causes FK violation\n # when any child record is flushed.\n left_batch = TranslationBatch(\n id=str(uuid.uuid4()), run_id=run_id, batch_index=-1,\n status=\"RUNNING\", total_records=len(batch_rows[:mid]),\n started_at=datetime.now(UTC),\n )\n right_batch = TranslationBatch(\n id=str(uuid.uuid4()), run_id=run_id, batch_index=-1,\n status=\"RUNNING\", total_records=len(batch_rows[mid:]),\n started_at=datetime.now(UTC),\n )\n self.db.add_all([left_batch, right_batch])\n self.db.flush()\n\n left = self.call_llm_for_batch(job, run_id, batch_rows[:mid], dict_matches,\n left_batch.id, max_tokens, depth + 1)\n right = self.call_llm_for_batch(job, run_id, batch_rows[mid:], dict_matches,\n right_batch.id, max_tokens, depth + 1)\n\n # Finalise child batch stats\n left_batch.completed_at = datetime.now(UTC)\n right_batch.completed_at = datetime.now(UTC)\n left_batch.successful_records = left[\"successful\"]\n right_batch.successful_records = right[\"successful\"]\n left_batch.failed_records = left[\"failed\"]\n right_batch.failed_records = right[\"failed\"]\n left_batch.status = \"COMPLETED\" if left[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n right_batch.status = \"COMPLETED\" if right[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n self.db.flush()\n\n return {\"successful\": left[\"successful\"] + right[\"successful\"],\n \"failed\": left[\"failed\"] + right[\"failed\"],\n \"skipped\": left[\"skipped\"] + right[\"skipped\"],\n \"retries\": retries + left.get(\"retries\", 0) + right.get(\"retries\", 0)}\n\n def _handle_parse_failure(self, batch_rows, run_id, batch_id, retries, error):\n for row in batch_rows:\n self.db.add(TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"), target_sql=None,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), status=\"SKIPPED\",\n error_message=f\"LLM parse failure: {error}\",\n ))\n return {\"successful\": 0, \"failed\": 0, \"skipped\": len(batch_rows), \"retries\": retries}\n\n def _create_records_from_translations(self, batch_rows, run_id, batch_id, target_languages, translations, dict_matches, retries):\n successful = failed = skipped = 0\n for row in batch_rows:\n row_id = str(row.get(\"row_index\", \"\"))\n td = translations.get(row_id)\n source_text = row.get(\"source_text\", \"\")\n # ★ Local detection (from _batch_proc._detect_languages) takes priority.\n # Fallback to LLM response field for backward compatibility.\n detected_lang = row.get(\"_detected_lang\", \"und\") or \"und\"\n if detected_lang == \"und\" and td:\n detected_lang = td.get(\"detected_source_language\", \"und\") or \"und\"\n if td is None:\n skipped += 1\n self._add_skipped(row, run_id, batch_id, source_text, \"NULL translation\")\n continue\n plv = self._extract_per_lang_values(td, target_languages)\n if dict_matches and source_text:\n _enforce_dictionary(source_text, plv, dict_matches, batch_id, row_id)\n if not plv:\n skipped += 1\n self._add_skipped(row, run_id, batch_id, source_text, \"Empty translation\")\n continue\n successful += 1\n primary = next(iter(plv.values()), \"\")\n record = TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=source_text, target_sql=primary,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(record)\n for lang_code in target_languages:\n if detected_lang != \"und\" and str(lang_code).lower() == str(detected_lang).lower():\n continue\n val = plv.get(lang_code, \"\")\n needs_review = (detected_lang == \"und\")\n if needs_review:\n logger.explore(\"undetected language\", {\"record_id\": row_id, \"language_code\": lang_code, \"text\": source_text[:100]})\n self.db.add(TranslationLanguage(\n id=str(uuid.uuid4()), record_id=record.id, language_code=lang_code,\n source_language_detected=detected_lang, translated_value=val or \"\",\n final_value=val or \"\", status=\"translated\", needs_review=needs_review,\n ))\n return {\"successful\": successful, \"failed\": failed, \"skipped\": skipped, \"retries\": retries}\n\n @staticmethod\n def _extract_per_lang_values(td, target_languages):\n plv = {}\n has_any = False\n for lc in target_languages:\n lv = td.get(lc)\n if lv is not None and str(lv).strip():\n plv[lc] = str(lv)\n has_any = True\n if not has_any:\n t = td.get(\"translation\", \"\")\n if t.strip():\n plv[target_languages[0]] = t\n has_any = True\n return plv if has_any else {}\n\n def _add_skipped(self, row, run_id, batch_id, source_text, reason):\n self.db.add(TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=source_text, target_sql=\"\",\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), status=\"SKIPPED\",\n error_message=reason,\n ))\n\n # #region call_llm [C:3] [TYPE Function] [SEMANTICS translate, llm, call]\n # @BRIEF Route to provider-specific LLM call implementation.\n def call_llm(self, job: TranslationJob, prompt: str, max_tokens: int = 8192) -> tuple[str, str | None]:\n \"\"\"Call the configured LLM provider with the batch prompt.\"\"\"\n with belief_scope(\"LLMTranslationService.call_llm\"):\n if not job.provider_id:\n raise ValueError(\"Job has no LLM provider configured\")\n provider_svc = LLMProviderService(self.db)\n provider = provider_svc.get_provider(job.provider_id)\n if not provider:\n raise ValueError(f\"LLM provider '{job.provider_id}' not found\")\n api_key = provider_svc.get_decrypted_api_key(job.provider_id)\n if not api_key:\n raise ValueError(f\"Could not decrypt API key for provider '{job.provider_id}'\")\n model = provider.default_model or \"gpt-4o-mini\"\n provider_type = provider.provider_type.lower() if provider.provider_type else \"openai\"\n disable_reasoning = getattr(job, 'disable_reasoning', False)\n\n if provider_type not in (\"openai\", \"openai_compatible\", \"openrouter\", \"kilo\", \"litellm\"):\n raise ValueError(f\"Unsupported provider type '{provider_type}'\")\n return call_openai_compatible(\n base_url=provider.base_url, api_key=api_key, model=model, prompt=prompt,\n provider_type=provider_type, max_tokens=max_tokens, disable_reasoning=disable_reasoning,\n )\n # #endregion call_llm\n\n # -- Static methods delegated to sub-modules for backward compat --\n @staticmethod\n def call_openai_compatible(*a, **kw):\n return call_openai_compatible(*a, **kw)\n\n @staticmethod\n def _parse_llm_response(*a, **kw):\n return parse_llm_response(*a, **kw)\n# #endregion LLMTranslationService\n# #endregion LLMTranslationService\n"
+ "body": "# #region LLMTranslationService [C:4] [TYPE Module] [SEMANTICS translate, llm, call, orchestrate, retry]\n# @BRIEF LLM interaction for batch translation: call provider with retry, handle truncation\n# by recursive splitting, enforce dictionary post-processing. Orchestrates HTTP calls\n# (_llm_http) and response parsing (_llm_parse).\n# Language detection is now handled locally (lingua) — LLM prompt no longer\n# requests detected_source_language; local _detected_lang takes priority.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [LLMProviderService]\n# @RELATION DEPENDS_ON -> [TranslationRecord], [TranslationLanguage]\n# @RELATION DEPENDS_ON -> [ContextAwarePromptBuilder]\n# @RELATION DEPENDS_ON -> [EXT:method:_llm_http], [_llm_parse]\n# @PRE DB session is available. LLM provider is configured on the job.\n# @POST TranslationRecord rows created for LLM-processed rows (success/fail/skip).\n# @SIDE_EFFECT HTTP calls to LLM provider API; DB writes.\n# @RATIONALE Core orchestration logic — HTTP and parse logic extracted to _llm_http.py and\n# _llm_parse.py to meet INV_7 module limit (< 400 lines).\n# @REJECTED Single monolithic call_llm_for_batch at 327 lines — split into focused sub-methods.\n\nfrom datetime import UTC, datetime\nimport json\nimport time\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import TranslationBatch, TranslationJob, TranslationLanguage, TranslationRecord\nfrom ...services.llm_prompt_templates import render_prompt\nfrom ...services.llm_provider import LLMProviderService\nfrom ._llm_http import call_openai_compatible\nfrom ._llm_parse import parse_llm_response\nfrom ._token_budget import estimate_token_budget\nfrom ._utils import _enforce_dictionary\nfrom .preview import DEFAULT_EXECUTION_PROMPT_TEMPLATE\nfrom .prompt_builder import ContextAwarePromptBuilder\n\nMAX_RETRIES_PER_BATCH = 3\n\n\n# #region LLMTranslationService [C:4] [TYPE Class]\n# @BRIEF Call LLM, handle retry/truncation, parse response, persist records.\nclass LLMTranslationService:\n \"\"\"LLM interaction for batch translation with retry, truncation handling, and parsing.\"\"\"\n\n def __init__(self, db: Session) -> None:\n self.db = db\n\n # #region call_llm_for_batch [C:3] [TYPE Function] [SEMANTICS translate, llm, batch, orchestrate]\n # @BRIEF Call LLM for a batch of rows requiring translation. Parse and persist results.\n # @PRE job has valid provider_id. batch_rows is non-empty.\n # @POST Returns dict with successful/failed/skipped counts.\n # @SIDE_EFFECT HTTP call to LLM provider; DB writes.\n def call_llm_for_batch(\n self, job: TranslationJob, run_id: str,\n batch_rows: list[dict[str, Any]], dict_matches: list[dict[str, Any]],\n batch_id: str, max_tokens: int = 8192, _recursion_depth: int = 0,\n ) -> dict[str, int]:\n \"\"\"Call LLM for a batch of rows; parse response; create records.\"\"\"\n with belief_scope(\"LLMTranslationService.call_llm_for_batch\"):\n dictionary_section = self._build_dictionary_section(dict_matches, batch_rows)\n target_languages = self._resolve_target_languages(job)\n prompt = self._build_prompt(job, batch_rows, dictionary_section, target_languages)\n\n llm_response, finish_reason, retries, last_error = self._call_llm_with_retry(\n job, prompt, batch_id, max_tokens,\n )\n if llm_response is None:\n return self._handle_llm_failure(batch_rows, run_id, batch_id, retries, last_error)\n\n if finish_reason == \"length\" and len(batch_rows) >= 2 and run_id:\n if _recursion_depth < MAX_RETRIES_PER_BATCH:\n return self._split_and_retry(job, run_id, batch_rows, dict_matches,\n batch_id, max_tokens, _recursion_depth, retries)\n logger.explore(\"Truncation recursion depth exceeded\", {\"batch_id\": batch_id, \"depth\": _recursion_depth})\n\n try:\n translations = parse_llm_response(llm_response, len(batch_rows), target_languages=target_languages)\n except ValueError as e:\n return self._handle_parse_failure(batch_rows, run_id, batch_id, retries, e)\n\n return self._create_records_from_translations(\n batch_rows, run_id, batch_id, target_languages, translations, dict_matches, retries,\n )\n # #endregion call_llm_for_batch\n\n def _build_dictionary_section(self, dict_matches, batch_rows) -> str:\n if not dict_matches:\n return \"\"\n row_context = batch_rows[0].get(\"source_data\") if batch_rows else None\n annotated = ContextAwarePromptBuilder.build_context_entries(dict_matches, row_context)\n return \"Terminology dictionary (use these translations when applicable):\\n\" + \\\n \"\\n\".join(f\"- {a}\" for a in annotated) + \"\\n\\n\"\n\n @staticmethod\n def _resolve_target_languages(job):\n langs = job.target_languages or [job.target_dialect or \"en\"]\n return [str(langs)] if not isinstance(langs, list) else langs\n\n @staticmethod\n def _build_prompt(job, batch_rows, dictionary_section, target_languages):\n target_languages_str = \", \".join(target_languages)\n rows_json = json.dumps([\n {\"row_id\": str(row.get(\"row_index\", idx)), \"text\": row.get(\"source_text\", \"\")}\n for idx, row in enumerate(batch_rows)\n ], indent=2)\n return render_prompt(DEFAULT_EXECUTION_PROMPT_TEMPLATE, {\n \"source_language\": job.source_dialect or \"SQL\",\n \"target_language\": target_languages_str,\n \"target_languages\": target_languages_str,\n \"source_dialect\": job.source_dialect or \"\",\n \"target_dialect\": job.target_dialect or \"\",\n \"translation_column\": job.translation_column or \"\",\n \"dictionary_section\": dictionary_section,\n \"rows_json\": rows_json,\n \"row_count\": str(len(batch_rows)),\n })\n\n def _call_llm_with_retry(self, job, prompt, batch_id, max_tokens):\n llm_response = None\n last_error = None\n retries = 0\n finish_reason = None\n for attempt in range(1, MAX_RETRIES_PER_BATCH + 1):\n try:\n llm_response, finish_reason = self.call_llm(job, prompt, max_tokens=max_tokens)\n break\n except Exception as e:\n last_error = str(e)\n retries += 1\n logger.explore(f\"LLM call failed (attempt {attempt})\", {\"batch_id\": batch_id, \"error\": last_error})\n if attempt < MAX_RETRIES_PER_BATCH:\n time.sleep(2 ** attempt)\n return llm_response, finish_reason, retries, last_error\n\n def _handle_llm_failure(self, batch_rows, run_id, batch_id, retries, last_error):\n for row in batch_rows:\n self.db.add(TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"), target_sql=None,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), status=\"FAILED\",\n error_message=f\"LLM call failed after {retries} retries: {last_error}\",\n ))\n return {\"successful\": 0, \"failed\": len(batch_rows), \"skipped\": 0, \"retries\": retries}\n\n def _split_and_retry(self, job, run_id, batch_rows, dict_matches, batch_id, max_tokens, depth, retries):\n mid = len(batch_rows) // 2\n logger.explore(\"LLM output truncated — splitting batch\",\n {\"batch_id\": batch_id, \"batch_size\": len(batch_rows), \"split_at\": mid, \"depth\": depth})\n\n # Create proper TranslationBatch rows for child halves (fixes FK violation\n # where _L/_R string suffixes referenced non-existent translation_batches rows).\n # @RATIONALE Previous code appended \"_L\"/\"_R\" to batch_id string, violating\n # FK translation_records.batch_id → translation_batches.id.\n # @REJECTED Continuing with string-suffixed batch_ids — causes FK violation\n # when any child record is flushed.\n left_batch = TranslationBatch(\n id=str(uuid.uuid4()), run_id=run_id, batch_index=-1,\n status=\"RUNNING\", total_records=len(batch_rows[:mid]),\n started_at=datetime.now(UTC),\n )\n right_batch = TranslationBatch(\n id=str(uuid.uuid4()), run_id=run_id, batch_index=-1,\n status=\"RUNNING\", total_records=len(batch_rows[mid:]),\n started_at=datetime.now(UTC),\n )\n self.db.add_all([left_batch, right_batch])\n self.db.flush()\n\n left = self.call_llm_for_batch(job, run_id, batch_rows[:mid], dict_matches,\n left_batch.id, max_tokens, depth + 1)\n right = self.call_llm_for_batch(job, run_id, batch_rows[mid:], dict_matches,\n right_batch.id, max_tokens, depth + 1)\n\n # Finalise child batch stats\n left_batch.completed_at = datetime.now(UTC)\n right_batch.completed_at = datetime.now(UTC)\n left_batch.successful_records = left[\"successful\"]\n right_batch.successful_records = right[\"successful\"]\n left_batch.failed_records = left[\"failed\"]\n right_batch.failed_records = right[\"failed\"]\n left_batch.status = \"COMPLETED\" if left[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n right_batch.status = \"COMPLETED\" if right[\"failed\"] == 0 else \"COMPLETED_WITH_ERRORS\"\n self.db.flush()\n\n return {\"successful\": left[\"successful\"] + right[\"successful\"],\n \"failed\": left[\"failed\"] + right[\"failed\"],\n \"skipped\": left[\"skipped\"] + right[\"skipped\"],\n \"retries\": retries + left.get(\"retries\", 0) + right.get(\"retries\", 0)}\n\n def _handle_parse_failure(self, batch_rows, run_id, batch_id, retries, error):\n for row in batch_rows:\n self.db.add(TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=row.get(\"source_text\", \"\"), target_sql=None,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), status=\"SKIPPED\",\n error_message=f\"LLM parse failure: {error}\",\n ))\n return {\"successful\": 0, \"failed\": 0, \"skipped\": len(batch_rows), \"retries\": retries}\n\n def _create_records_from_translations(self, batch_rows, run_id, batch_id, target_languages, translations, dict_matches, retries):\n successful = failed = skipped = 0\n for row in batch_rows:\n row_id = str(row.get(\"row_index\", \"\"))\n td = translations.get(row_id)\n source_text = row.get(\"source_text\", \"\")\n # ★ Local detection (from _batch_proc._detect_languages) takes priority.\n # Fallback to LLM response field for backward compatibility.\n detected_lang = row.get(\"_detected_lang\", \"und\") or \"und\"\n if detected_lang == \"und\" and td:\n detected_lang = td.get(\"detected_source_language\", \"und\") or \"und\"\n if td is None:\n skipped += 1\n self._add_skipped(row, run_id, batch_id, source_text, \"NULL translation\")\n continue\n plv = self._extract_per_lang_values(td, target_languages)\n if dict_matches and source_text:\n _enforce_dictionary(source_text, plv, dict_matches, batch_id, row_id)\n if not plv:\n skipped += 1\n self._add_skipped(row, run_id, batch_id, source_text, \"Empty translation\")\n continue\n successful += 1\n primary = next(iter(plv.values()), \"\")\n record = TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=source_text, target_sql=primary,\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), source_hash=row.get(\"_source_hash\"),\n status=\"SUCCESS\",\n )\n self.db.add(record)\n for lang_code in target_languages:\n if detected_lang != \"und\" and str(lang_code).lower() == str(detected_lang).lower():\n continue\n val = plv.get(lang_code, \"\")\n needs_review = (detected_lang == \"und\")\n if needs_review:\n logger.explore(\"undetected language\", {\"record_id\": row_id, \"language_code\": lang_code, \"text\": source_text[:100]})\n self.db.add(TranslationLanguage(\n id=str(uuid.uuid4()), record_id=record.id, language_code=lang_code,\n source_language_detected=detected_lang, translated_value=val or \"\",\n final_value=val or \"\", status=\"translated\", needs_review=needs_review,\n ))\n return {\"successful\": successful, \"failed\": failed, \"skipped\": skipped, \"retries\": retries}\n\n @staticmethod\n def _extract_per_lang_values(td, target_languages):\n plv = {}\n has_any = False\n for lc in target_languages:\n lv = td.get(lc)\n if lv is not None and str(lv).strip():\n plv[lc] = str(lv)\n has_any = True\n if not has_any:\n t = td.get(\"translation\", \"\")\n if t.strip():\n plv[target_languages[0]] = t\n has_any = True\n return plv if has_any else {}\n\n def _add_skipped(self, row, run_id, batch_id, source_text, reason):\n self.db.add(TranslationRecord(\n id=str(uuid.uuid4()), batch_id=batch_id, run_id=run_id,\n source_sql=source_text, target_sql=\"\",\n source_object_type=\"table_row\", source_object_id=row.get(\"row_index\"),\n source_object_name=row.get(\"source_object_name\", \"\"),\n source_data=row.get(\"source_data\"), status=\"SKIPPED\",\n error_message=reason,\n ))\n\n # #region call_llm [C:3] [TYPE Function] [SEMANTICS translate, llm, call]\n # @BRIEF Route to provider-specific LLM call implementation.\n def call_llm(self, job: TranslationJob, prompt: str, max_tokens: int = 8192) -> tuple[str, str | None]:\n \"\"\"Call the configured LLM provider with the batch prompt.\"\"\"\n with belief_scope(\"LLMTranslationService.call_llm\"):\n if not job.provider_id:\n raise ValueError(\"Job has no LLM provider configured\")\n provider_svc = LLMProviderService(self.db)\n provider = provider_svc.get_provider(job.provider_id)\n if not provider:\n raise ValueError(f\"LLM provider '{job.provider_id}' not found\")\n api_key = provider_svc.get_decrypted_api_key(job.provider_id)\n if not api_key:\n raise ValueError(f\"Could not decrypt API key for provider '{job.provider_id}'\")\n model = provider.default_model or \"gpt-4o-mini\"\n provider_type = provider.provider_type.lower() if provider.provider_type else \"openai\"\n disable_reasoning = getattr(job, 'disable_reasoning', False)\n\n if provider_type not in (\"openai\", \"openai_compatible\", \"openrouter\", \"kilo\", \"litellm\"):\n raise ValueError(f\"Unsupported provider type '{provider_type}'\")\n return call_openai_compatible(\n base_url=provider.base_url, api_key=api_key, model=model, prompt=prompt,\n provider_type=provider_type, max_tokens=max_tokens, disable_reasoning=disable_reasoning,\n )\n # #endregion call_llm\n\n # -- Static methods delegated to sub-modules for backward compat --\n @staticmethod\n def call_openai_compatible(*a, **kw):\n return call_openai_compatible(*a, **kw)\n\n @staticmethod\n def _parse_llm_response(*a, **kw):\n return parse_llm_response(*a, **kw)\n# #endregion LLMTranslationService\n# #endregion LLMTranslationService\n"
},
{
"contract_id": "call_llm_for_batch",
@@ -37253,7 +37363,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DictionaryCorrectionService [C:3] [TYPE Class] [SEMANTICS dictionary, correction, bulk]\n# @BRIEF Submit term corrections and bulk corrections to dictionaries with conflict detection.\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [TerminologyDictionary]\n\nfrom typing import Any\n\nfrom sqlalchemy import or_\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TerminologyDictionary\nfrom .[EXT:internal:_utils] import _normalize_term\n\n\nclass DictionaryCorrectionService:\n \"\"\"Submit term corrections to dictionaries with conflict detection and bulk support.\"\"\"\n\n # region submit_correction [TYPE Function]\n # @PURPOSE: Submit a term correction from a run result.\n @staticmethod\n def submit_correction(\n db: Session,\n dict_id: str,\n source_term: str,\n incorrect_target_term: str,\n corrected_target_term: str,\n origin_run_id: str | None = None,\n origin_row_key: str | None = None,\n origin_user_id: str | None = None,\n on_conflict: str = \"overwrite\",\n context_data: dict[str, Any] | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryCorrectionService.submit_correction\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n effective_context = context_data\n effective_context_source = \"auto\"\n if not keep_context:\n effective_context = None\n effective_context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n entry_src_lang = dictionary.source_dialect or \"und\"\n entry_tgt_lang = dictionary.target_dialect or \"und\"\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == entry_src_lang) & (DictionaryEntry.target_language == entry_tgt_lang),\n (DictionaryEntry.source_language == \"und\") & (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n result: dict[str, Any] = {\"source_term\": source_term, \"target_term\": corrected_target_term, \"action\": \"created\", \"entry_id\": None, \"conflict\": None, \"message\": None}\n\n if existing:\n if on_conflict == \"keep_existing\":\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target_term, \"action\": \"keep_existing\"}\n result[\"message\"] = f\"Existing entry kept: '{existing.target_term}'\"\n return result\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target_term.strip()\n if origin_run_id:\n existing.origin_run_id = origin_run_id\n if origin_row_key:\n existing.origin_row_key = origin_row_key\n if origin_user_id:\n existing.origin_user_id = origin_user_id\n if context_data is not None or not keep_context:\n existing.context_data = effective_context\n existing.has_context = bool(effective_context)\n existing.context_source = effective_context_source\n if usage_notes is not None:\n existing.usage_notes = usage_notes\n db.flush()\n result[\"action\"] = \"updated\"\n result[\"entry_id\"] = existing.id\n result[\"message\"] = f\"Entry updated from '{existing.target_term}' to '{corrected_target_term}'\"\n else:\n result[\"action\"] = \"skipped\"\n result[\"conflict\"] = {\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target_term, \"action\": \"cancel\"}\n result[\"message\"] = \"Correction cancelled by conflict mode\"\n return result\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id, source_term=source_term.strip(),\n source_term_normalized=normalized, target_term=corrected_target_term.strip(),\n source_language=entry_src_lang, target_language=entry_tgt_lang,\n context_data=effective_context, usage_notes=usage_notes,\n has_context=bool(effective_context), context_source=effective_context_source if effective_context else None,\n origin_run_id=origin_run_id, origin_row_key=origin_row_key, origin_user_id=origin_user_id,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = f\"Entry created for '{source_term}' -> '{corrected_target_term}'\"\n\n db.commit()\n logger.reflect(\"Correction processed\", result)\n return result\n # endregion submit_correction\n\n # region submit_bulk_corrections [TYPE Function]\n # @PURPOSE: Submit multiple term corrections atomically.\n @staticmethod\n def submit_bulk_corrections(\n db: Session,\n dict_id: str,\n corrections: list[dict[str, Any]],\n origin_user_id: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryCorrectionService.submit_bulk_corrections\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n results: list[dict[str, Any]] = []\n conflicts: list[dict[str, Any]] = []\n all_ok = True\n\n for corr in corrections:\n source_term = corr.get(\"source_term\", \"\").strip()\n corrected_target = corr.get(\"corrected_target_term\", \"\").strip()\n\n if not source_term or not corrected_target:\n results.append({\"source_term\": source_term, \"action\": \"error\", \"message\": \"source_term and corrected_target_term are required\"})\n all_ok = False\n continue\n\n normalized = _normalize_term(source_term)\n bulk_src_lang = dictionary.source_dialect or \"und\"\n bulk_tgt_lang = dictionary.target_dialect or \"und\"\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == bulk_src_lang) & (DictionaryEntry.target_language == bulk_tgt_lang),\n (DictionaryEntry.source_language == \"und\") & (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n if existing:\n on_conflict = corr.get(\"on_conflict\", \"overwrite\")\n if on_conflict == \"keep_existing\":\n conflicts.append({\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target, \"action\": \"keep_existing\"})\n results.append({\"source_term\": source_term, \"action\": \"conflict_detected\", \"message\": f\"Existing entry kept: '{existing.target_term}'\"})\n continue\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target\n existing.origin_user_id = origin_user_id\n results.append({\"source_term\": source_term, \"action\": \"updated\", \"entry_id\": existing.id, \"message\": f\"Updated to '{corrected_target}'\"})\n else:\n conflicts.append({\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target, \"action\": \"cancel\"})\n results.append({\"source_term\": source_term, \"action\": \"skipped\", \"message\": \"Cancelled by conflict mode\"})\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id, source_term=source_term, source_term_normalized=normalized,\n target_term=corrected_target, source_language=bulk_src_lang, target_language=bulk_tgt_lang,\n origin_run_id=corr.get(\"origin_run_id\"), origin_row_key=corr.get(\"origin_row_key\"),\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n results.append({\"source_term\": source_term, \"action\": \"created\", \"message\": f\"Entry created for '{source_term}' -> '{corrected_target}'\"})\n\n if conflicts and not all_ok:\n db.rollback()\n return {\"status\": \"conflicts\", \"results\": results, \"conflicts\": conflicts, \"message\": \"Conflicts detected. Resolve before retrying.\"}\n\n db.commit()\n return {\n \"status\": \"completed\", \"results\": results, \"conflicts\": conflicts,\n \"total\": len(corrections), \"applied\": sum(1 for r in results if r[\"action\"] in (\"created\", \"updated\")),\n }\n # endregion submit_bulk_corrections\n\n# #endregion DictionaryCorrectionService\n"
+ "body": "# #region DictionaryCorrectionService [C:3] [TYPE Class] [SEMANTICS dictionary, correction, bulk]\n# @BRIEF Submit term corrections and bulk corrections to dictionaries with conflict detection.\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [TerminologyDictionary]\n\nfrom typing import Any\n\nfrom sqlalchemy import or_\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TerminologyDictionary\nfrom ._utils import _normalize_term\n\n\nclass DictionaryCorrectionService:\n \"\"\"Submit term corrections to dictionaries with conflict detection and bulk support.\"\"\"\n\n # region submit_correction [TYPE Function]\n # @PURPOSE: Submit a term correction from a run result.\n @staticmethod\n def submit_correction(\n db: Session,\n dict_id: str,\n source_term: str,\n incorrect_target_term: str,\n corrected_target_term: str,\n origin_run_id: str | None = None,\n origin_row_key: str | None = None,\n origin_user_id: str | None = None,\n on_conflict: str = \"overwrite\",\n context_data: dict[str, Any] | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryCorrectionService.submit_correction\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n effective_context = context_data\n effective_context_source = \"auto\"\n if not keep_context:\n effective_context = None\n effective_context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n entry_src_lang = dictionary.source_dialect or \"und\"\n entry_tgt_lang = dictionary.target_dialect or \"und\"\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == entry_src_lang) & (DictionaryEntry.target_language == entry_tgt_lang),\n (DictionaryEntry.source_language == \"und\") & (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n result: dict[str, Any] = {\"source_term\": source_term, \"target_term\": corrected_target_term, \"action\": \"created\", \"entry_id\": None, \"conflict\": None, \"message\": None}\n\n if existing:\n if on_conflict == \"keep_existing\":\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target_term, \"action\": \"keep_existing\"}\n result[\"message\"] = f\"Existing entry kept: '{existing.target_term}'\"\n return result\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target_term.strip()\n if origin_run_id:\n existing.origin_run_id = origin_run_id\n if origin_row_key:\n existing.origin_row_key = origin_row_key\n if origin_user_id:\n existing.origin_user_id = origin_user_id\n if context_data is not None or not keep_context:\n existing.context_data = effective_context\n existing.has_context = bool(effective_context)\n existing.context_source = effective_context_source\n if usage_notes is not None:\n existing.usage_notes = usage_notes\n db.flush()\n result[\"action\"] = \"updated\"\n result[\"entry_id\"] = existing.id\n result[\"message\"] = f\"Entry updated from '{existing.target_term}' to '{corrected_target_term}'\"\n else:\n result[\"action\"] = \"skipped\"\n result[\"conflict\"] = {\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target_term, \"action\": \"cancel\"}\n result[\"message\"] = \"Correction cancelled by conflict mode\"\n return result\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id, source_term=source_term.strip(),\n source_term_normalized=normalized, target_term=corrected_target_term.strip(),\n source_language=entry_src_lang, target_language=entry_tgt_lang,\n context_data=effective_context, usage_notes=usage_notes,\n has_context=bool(effective_context), context_source=effective_context_source if effective_context else None,\n origin_run_id=origin_run_id, origin_row_key=origin_row_key, origin_user_id=origin_user_id,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = f\"Entry created for '{source_term}' -> '{corrected_target_term}'\"\n\n db.commit()\n logger.reflect(\"Correction processed\", result)\n return result\n # endregion submit_correction\n\n # region submit_bulk_corrections [TYPE Function]\n # @PURPOSE: Submit multiple term corrections atomically.\n @staticmethod\n def submit_bulk_corrections(\n db: Session,\n dict_id: str,\n corrections: list[dict[str, Any]],\n origin_user_id: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryCorrectionService.submit_bulk_corrections\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary '{dict_id}' not found\")\n\n results: list[dict[str, Any]] = []\n conflicts: list[dict[str, Any]] = []\n all_ok = True\n\n for corr in corrections:\n source_term = corr.get(\"source_term\", \"\").strip()\n corrected_target = corr.get(\"corrected_target_term\", \"\").strip()\n\n if not source_term or not corrected_target:\n results.append({\"source_term\": source_term, \"action\": \"error\", \"message\": \"source_term and corrected_target_term are required\"})\n all_ok = False\n continue\n\n normalized = _normalize_term(source_term)\n bulk_src_lang = dictionary.source_dialect or \"und\"\n bulk_tgt_lang = dictionary.target_dialect or \"und\"\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n or_(\n (DictionaryEntry.source_language == bulk_src_lang) & (DictionaryEntry.target_language == bulk_tgt_lang),\n (DictionaryEntry.source_language == \"und\") & (DictionaryEntry.target_language == \"und\"),\n ),\n )\n .first()\n )\n\n if existing:\n on_conflict = corr.get(\"on_conflict\", \"overwrite\")\n if on_conflict == \"keep_existing\":\n conflicts.append({\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target, \"action\": \"keep_existing\"})\n results.append({\"source_term\": source_term, \"action\": \"conflict_detected\", \"message\": f\"Existing entry kept: '{existing.target_term}'\"})\n continue\n elif on_conflict == \"overwrite\":\n existing.target_term = corrected_target\n existing.origin_user_id = origin_user_id\n results.append({\"source_term\": source_term, \"action\": \"updated\", \"entry_id\": existing.id, \"message\": f\"Updated to '{corrected_target}'\"})\n else:\n conflicts.append({\"source_term\": source_term, \"existing_target_term\": existing.target_term, \"submitted_target_term\": corrected_target, \"action\": \"cancel\"})\n results.append({\"source_term\": source_term, \"action\": \"skipped\", \"message\": \"Cancelled by conflict mode\"})\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id, source_term=source_term, source_term_normalized=normalized,\n target_term=corrected_target, source_language=bulk_src_lang, target_language=bulk_tgt_lang,\n origin_run_id=corr.get(\"origin_run_id\"), origin_row_key=corr.get(\"origin_row_key\"),\n origin_user_id=origin_user_id,\n )\n db.add(entry)\n results.append({\"source_term\": source_term, \"action\": \"created\", \"message\": f\"Entry created for '{source_term}' -> '{corrected_target}'\"})\n\n if conflicts and not all_ok:\n db.rollback()\n return {\"status\": \"conflicts\", \"results\": results, \"conflicts\": conflicts, \"message\": \"Conflicts detected. Resolve before retrying.\"}\n\n db.commit()\n return {\n \"status\": \"completed\", \"results\": results, \"conflicts\": conflicts,\n \"total\": len(corrections), \"applied\": sum(1 for r in results if r[\"action\"] in (\"created\", \"updated\")),\n }\n # endregion submit_bulk_corrections\n\n# #endregion DictionaryCorrectionService\n"
},
{
"contract_id": "DictionaryCRUD",
@@ -37321,7 +37431,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DictionaryEntryCRUD [C:3] [TYPE Class] [SEMANTICS dictionary, entries, crud]\n# @BRIEF CRUD operations for DictionaryEntry records.\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [TerminologyDictionary]\n\nfrom sqlalchemy import func\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TerminologyDictionary\nfrom .[EXT:internal:_utils] import _normalize_term\nfrom .dictionary_validation import _validate_bcp47\n\n\nclass DictionaryEntryCRUD:\n \"\"\"CRUD operations for dictionary entries.\"\"\"\n\n # region add_entry [TYPE Function]\n # @PURPOSE: Add an entry to a dictionary with language-pair-aware uniqueness validation.\n @staticmethod\n def add_entry(\n db: Session, dict_id: str, source_term: str, target_term: str,\n context_notes: str | None = None,\n source_language: str = \"und\", target_language: str = \"und\",\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryEntryCRUD.add_entry\"):\n _validate_bcp47(source_language, \"source_language\")\n _validate_bcp47(target_language, \"target_language\")\n\n normalized = _normalize_term(source_term)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' (lang: {source_language}→{target_language}) \"\n f\"already exists in this dictionary (id={existing.id}). \"\n \"Use overwrite or keep_existing conflict mode.\"\n )\n\n logger.reason(\"Adding dictionary entry\", {\"dict_id\": dict_id, \"term\": source_term})\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=target_term.strip(),\n context_notes=context_notes.strip() if context_notes else None,\n source_language=source_language.strip(),\n target_language=target_language.strip(),\n )\n db.add(entry)\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id})\n return entry\n # endregion add_entry\n\n # region edit_entry [TYPE Function]\n # @PURPOSE: Edit an existing dictionary entry with language-pair-aware duplicate check.\n @staticmethod\n def edit_entry(\n db: Session, entry_id: str, source_term: str | None = None,\n target_term: str | None = None, context_notes: str | None = None,\n source_language: str | None = None, target_language: str | None = None,\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryEntryCRUD.edit_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Editing dictionary entry\", {\"entry_id\": entry_id})\n\n if source_language is not None:\n _validate_bcp47(source_language, \"source_language\")\n entry.source_language = source_language.strip()\n if target_language is not None:\n _validate_bcp47(target_language, \"target_language\")\n entry.target_language = target_language.strip()\n\n if source_term is not None:\n normalized = _normalize_term(source_term)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == entry.dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == entry.source_language,\n DictionaryEntry.target_language == entry.target_language,\n DictionaryEntry.id != entry_id,\n )\n .first()\n )\n if existing:\n raise ValueError(f\"Duplicate entry: '{source_term}' already exists in this dictionary (id={existing.id}).\")\n entry.source_term = source_term.strip()\n entry.source_term_normalized = normalized\n if target_term is not None:\n entry.target_term = target_term.strip()\n if context_notes is not None:\n entry.context_notes = context_notes.strip() if context_notes else None\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry updated\", {\"entry_id\": entry.id})\n return entry\n # endregion edit_entry\n\n # region delete_entry [TYPE Function]\n # @PURPOSE: Delete a single dictionary entry.\n @staticmethod\n def delete_entry(db: Session, entry_id: str) -> None:\n with belief_scope(\"DictionaryEntryCRUD.delete_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Deleting dictionary entry\", {\"entry_id\": entry_id})\n db.delete(entry)\n db.commit()\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n # endregion delete_entry\n\n # region clear_entries [TYPE Function]\n # @PURPOSE: Delete all entries for a dictionary.\n @staticmethod\n def clear_entries(db: Session, dict_id: str) -> int:\n with belief_scope(\"DictionaryEntryCRUD.clear_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Clearing all entries\", {\"dict_id\": dict_id})\n deleted = db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.commit()\n logger.reflect(\"Entries cleared\", {\"dict_id\": dict_id, \"count\": deleted})\n return deleted\n # endregion clear_entries\n\n # region list_entries [TYPE Function]\n # @PURPOSE: List entries for a dictionary with pagination.\n @staticmethod\n def list_entries(\n db: Session, dict_id: str, page: int = 1, page_size: int = 50,\n ) -> tuple[list[DictionaryEntry], int]:\n total = (\n db.query(func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .scalar() or 0\n )\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return entries, total\n # endregion list_entries\n\n# #endregion DictionaryEntryCRUD\n"
+ "body": "# #region DictionaryEntryCRUD [C:3] [TYPE Class] [SEMANTICS dictionary, entries, crud]\n# @BRIEF CRUD operations for DictionaryEntry records.\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [TerminologyDictionary]\n\nfrom sqlalchemy import func\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TerminologyDictionary\nfrom ._utils import _normalize_term\nfrom .dictionary_validation import _validate_bcp47\n\n\nclass DictionaryEntryCRUD:\n \"\"\"CRUD operations for dictionary entries.\"\"\"\n\n # region add_entry [TYPE Function]\n # @PURPOSE: Add an entry to a dictionary with language-pair-aware uniqueness validation.\n @staticmethod\n def add_entry(\n db: Session, dict_id: str, source_term: str, target_term: str,\n context_notes: str | None = None,\n source_language: str = \"und\", target_language: str = \"und\",\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryEntryCRUD.add_entry\"):\n _validate_bcp47(source_language, \"source_language\")\n _validate_bcp47(target_language, \"target_language\")\n\n normalized = _normalize_term(source_term)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n if existing:\n raise ValueError(\n f\"Duplicate entry: '{source_term}' (lang: {source_language}→{target_language}) \"\n f\"already exists in this dictionary (id={existing.id}). \"\n \"Use overwrite or keep_existing conflict mode.\"\n )\n\n logger.reason(\"Adding dictionary entry\", {\"dict_id\": dict_id, \"term\": source_term})\n entry = DictionaryEntry(\n dictionary_id=dict_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=target_term.strip(),\n context_notes=context_notes.strip() if context_notes else None,\n source_language=source_language.strip(),\n target_language=target_language.strip(),\n )\n db.add(entry)\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry added\", {\"entry_id\": entry.id})\n return entry\n # endregion add_entry\n\n # region edit_entry [TYPE Function]\n # @PURPOSE: Edit an existing dictionary entry with language-pair-aware duplicate check.\n @staticmethod\n def edit_entry(\n db: Session, entry_id: str, source_term: str | None = None,\n target_term: str | None = None, context_notes: str | None = None,\n source_language: str | None = None, target_language: str | None = None,\n ) -> DictionaryEntry:\n with belief_scope(\"DictionaryEntryCRUD.edit_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Editing dictionary entry\", {\"entry_id\": entry_id})\n\n if source_language is not None:\n _validate_bcp47(source_language, \"source_language\")\n entry.source_language = source_language.strip()\n if target_language is not None:\n _validate_bcp47(target_language, \"target_language\")\n entry.target_language = target_language.strip()\n\n if source_term is not None:\n normalized = _normalize_term(source_term)\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == entry.dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == entry.source_language,\n DictionaryEntry.target_language == entry.target_language,\n DictionaryEntry.id != entry_id,\n )\n .first()\n )\n if existing:\n raise ValueError(f\"Duplicate entry: '{source_term}' already exists in this dictionary (id={existing.id}).\")\n entry.source_term = source_term.strip()\n entry.source_term_normalized = normalized\n if target_term is not None:\n entry.target_term = target_term.strip()\n if context_notes is not None:\n entry.context_notes = context_notes.strip() if context_notes else None\n db.commit()\n db.refresh(entry)\n logger.reflect(\"Entry updated\", {\"entry_id\": entry.id})\n return entry\n # endregion edit_entry\n\n # region delete_entry [TYPE Function]\n # @PURPOSE: Delete a single dictionary entry.\n @staticmethod\n def delete_entry(db: Session, entry_id: str) -> None:\n with belief_scope(\"DictionaryEntryCRUD.delete_entry\"):\n entry = db.query(DictionaryEntry).filter(DictionaryEntry.id == entry_id).first()\n if not entry:\n raise ValueError(f\"Entry not found: {entry_id}\")\n logger.reason(\"Deleting dictionary entry\", {\"entry_id\": entry_id})\n db.delete(entry)\n db.commit()\n logger.reflect(\"Entry deleted\", {\"entry_id\": entry_id})\n # endregion delete_entry\n\n # region clear_entries [TYPE Function]\n # @PURPOSE: Delete all entries for a dictionary.\n @staticmethod\n def clear_entries(db: Session, dict_id: str) -> int:\n with belief_scope(\"DictionaryEntryCRUD.clear_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n logger.reason(\"Clearing all entries\", {\"dict_id\": dict_id})\n deleted = db.query(DictionaryEntry).filter(DictionaryEntry.dictionary_id == dict_id).delete()\n db.commit()\n logger.reflect(\"Entries cleared\", {\"dict_id\": dict_id, \"count\": deleted})\n return deleted\n # endregion clear_entries\n\n # region list_entries [TYPE Function]\n # @PURPOSE: List entries for a dictionary with pagination.\n @staticmethod\n def list_entries(\n db: Session, dict_id: str, page: int = 1, page_size: int = 50,\n ) -> tuple[list[DictionaryEntry], int]:\n total = (\n db.query(func.count(DictionaryEntry.id))\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .scalar() or 0\n )\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .offset((page - 1) * page_size)\n .limit(page_size)\n .all()\n )\n return entries, total\n # endregion list_entries\n\n# #endregion DictionaryEntryCRUD\n"
},
{
"contract_id": "DictionaryBatchFilter",
@@ -37395,7 +37505,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region DictionaryImportExport [C:3] [TYPE Class] [SEMANTICS dictionary, import, export, csv, migration]\n# @BRIEF Import/export entries as CSV/TSV with conflict detection, and migration of old entries.\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [TerminologyDictionary]\n\nimport csv\nimport io\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TerminologyDictionary\nfrom .[EXT:internal:_utils] import _detect_delimiter, _normalize_term\n\n\nclass DictionaryImportExport:\n \"\"\"Import/export dictionary entries as CSV/TSV, and migrate old-style entries.\"\"\"\n\n # region import_entries [TYPE Function]\n # @PURPOSE: Import entries from CSV/TSV content with duplicate detection and conflict resolution.\n @staticmethod\n def import_entries(\n db: Session, dict_id: str, content: str,\n delimiter: str | None = None,\n on_conflict: str = \"overwrite\",\n preview_only: bool = False,\n default_source_language: str | None = None,\n default_target_language: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryImportExport.import_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n if not delimiter:\n delimiter = _detect_delimiter(content)\n logger.reason(\"Detected delimiter\", {\"delimiter\": repr(delimiter)})\n\n if delimiter not in (\",\", \"\\t\"):\n raise ValueError(f\"Unsupported delimiter: {delimiter!r}. Use ',' or '\\\\t'.\")\n\n reader = csv.DictReader(io.StringIO(content), delimiter=delimiter)\n required_fields = {\"source_term\", \"target_term\"}\n if not reader.fieldnames or not required_fields.issubset(reader.fieldnames):\n raise ValueError(\n f\"CSV/TSV must have at least 'source_term' and 'target_term' columns. \"\n f\"Got: {reader.fieldnames}\"\n )\n\n result: dict[str, Any] = {\"total\": 0, \"created\": 0, \"updated\": 0, \"skipped\": 0, \"errors\": [], \"preview\": []}\n rows = list(reader)\n result[\"total\"] = len(rows)\n\n for row_idx, row in enumerate(rows):\n try:\n source_term = row.get(\"source_term\", \"\").strip()\n target_term = row.get(\"target_term\", \"\").strip()\n context_notes = row.get(\"context_notes\", \"\").strip() or None\n source_language = row.get(\"source_language\", \"\").strip() or default_source_language or \"und\"\n target_language = row.get(\"target_language\", \"\").strip() or default_target_language or \"und\"\n\n if not source_term or not target_term:\n result[\"errors\"].append({\"line\": row_idx + 2, \"error\": \"Both source_term and target_term are required\", \"row\": row})\n continue\n\n normalized = _normalize_term(source_term)\n\n if preview_only:\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n result[\"preview\"].append({\n \"line\": row_idx + 2, \"source_term\": source_term, \"target_term\": target_term,\n \"context_notes\": context_notes, \"source_language\": source_language,\n \"target_language\": target_language, \"is_conflict\": existing is not None,\n \"existing_target_term\": existing.target_term if existing else None,\n })\n continue\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n if existing:\n if on_conflict == \"overwrite\":\n existing.source_term = source_term\n existing.target_term = target_term\n existing.context_notes = context_notes\n existing.source_language = source_language\n existing.target_language = target_language\n result[\"updated\"] += 1\n elif on_conflict == \"keep_existing\":\n result[\"skipped\"] += 1\n else:\n result[\"errors\"].append({\"line\": row_idx + 2, \"error\": f\"Conflict on '{source_term}' and on_conflict='cancel'\", \"row\": row})\n continue\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id, source_term=source_term,\n source_term_normalized=normalized, target_term=target_term,\n context_notes=context_notes, source_language=source_language,\n target_language=target_language,\n )\n db.add(entry)\n result[\"created\"] += 1\n except Exception as e:\n result[\"errors\"].append({\"line\": row_idx + 2, \"error\": str(e), \"row\": row})\n\n if not preview_only:\n db.commit()\n\n logger.reflect(\"Import complete\", {\"dict_id\": dict_id, \"total\": result[\"total\"], \"created\": result[\"created\"]})\n return result\n # endregion import_entries\n\n # region export_entries [TYPE Function]\n # @PURPOSE: Export all entries as CSV string with language columns.\n @staticmethod\n def export_entries(db: Session, dict_id: str, delimiter: str = \",\") -> str:\n with belief_scope(\"DictionaryImportExport.export_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n output = io.StringIO()\n fieldnames = [\"source_term\", \"target_term\", \"source_language\", \"target_language\", \"context_notes\", \"context_data\", \"usage_notes\"]\n writer = csv.DictWriter(output, fieldnames=fieldnames, delimiter=delimiter)\n writer.writeheader()\n for entry in entries:\n writer.writerow({\n \"source_term\": entry.source_term, \"target_term\": entry.target_term,\n \"source_language\": entry.source_language, \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes or \"\", \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes or \"\",\n })\n\n result = output.getvalue()\n logger.reflect(\"Entries exported\", {\"dict_id\": dict_id, \"count\": len(entries)})\n return result\n # endregion export_entries\n\n # region migrate_old_entries [TYPE Function]\n # @PURPOSE: Migrate existing single-language dictionary entries to populate source_language and target_language.\n @staticmethod\n def migrate_old_entries(db: Session) -> dict[str, int]:\n with belief_scope(\"DictionaryImportExport.migrate_old_entries\"):\n logger.reason(\"Starting migration of old dictionary entries\")\n migrated_source = 0\n migrated_target = 0\n skipped = 0\n\n entries = (\n db.query(DictionaryEntry)\n .filter(\n (DictionaryEntry.source_language == \"und\") |\n (DictionaryEntry.target_language == \"und\")\n )\n .all()\n )\n\n for entry in entries:\n if entry.source_language == \"und\":\n if entry.origin_source_language:\n entry.source_language = entry.origin_source_language\n migrated_source += 1\n if entry.source_language == \"und\" and entry.target_language == \"und\":\n skipped += 1\n\n db.commit()\n logger.reflect(\"Migration complete\", {\"migrated_source\": migrated_source, \"total_processed\": len(entries)})\n return {\"migrated_source\": migrated_source, \"migrated_target\": migrated_target, \"skipped\": skipped, \"total_processed\": len(entries)}\n # endregion migrate_old_entries\n\n# #endregion DictionaryImportExport\n"
+ "body": "# #region DictionaryImportExport [C:3] [TYPE Class] [SEMANTICS dictionary, import, export, csv, migration]\n# @BRIEF Import/export entries as CSV/TSV with conflict detection, and migration of old entries.\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [TerminologyDictionary]\n\nimport csv\nimport io\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TerminologyDictionary\nfrom ._utils import _detect_delimiter, _normalize_term\n\n\nclass DictionaryImportExport:\n \"\"\"Import/export dictionary entries as CSV/TSV, and migrate old-style entries.\"\"\"\n\n # region import_entries [TYPE Function]\n # @PURPOSE: Import entries from CSV/TSV content with duplicate detection and conflict resolution.\n @staticmethod\n def import_entries(\n db: Session, dict_id: str, content: str,\n delimiter: str | None = None,\n on_conflict: str = \"overwrite\",\n preview_only: bool = False,\n default_source_language: str | None = None,\n default_target_language: str | None = None,\n ) -> dict[str, Any]:\n with belief_scope(\"DictionaryImportExport.import_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n if not delimiter:\n delimiter = _detect_delimiter(content)\n logger.reason(\"Detected delimiter\", {\"delimiter\": repr(delimiter)})\n\n if delimiter not in (\",\", \"\\t\"):\n raise ValueError(f\"Unsupported delimiter: {delimiter!r}. Use ',' or '\\\\t'.\")\n\n reader = csv.DictReader(io.StringIO(content), delimiter=delimiter)\n required_fields = {\"source_term\", \"target_term\"}\n if not reader.fieldnames or not required_fields.issubset(reader.fieldnames):\n raise ValueError(\n f\"CSV/TSV must have at least 'source_term' and 'target_term' columns. \"\n f\"Got: {reader.fieldnames}\"\n )\n\n result: dict[str, Any] = {\"total\": 0, \"created\": 0, \"updated\": 0, \"skipped\": 0, \"errors\": [], \"preview\": []}\n rows = list(reader)\n result[\"total\"] = len(rows)\n\n for row_idx, row in enumerate(rows):\n try:\n source_term = row.get(\"source_term\", \"\").strip()\n target_term = row.get(\"target_term\", \"\").strip()\n context_notes = row.get(\"context_notes\", \"\").strip() or None\n source_language = row.get(\"source_language\", \"\").strip() or default_source_language or \"und\"\n target_language = row.get(\"target_language\", \"\").strip() or default_target_language or \"und\"\n\n if not source_term or not target_term:\n result[\"errors\"].append({\"line\": row_idx + 2, \"error\": \"Both source_term and target_term are required\", \"row\": row})\n continue\n\n normalized = _normalize_term(source_term)\n\n if preview_only:\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n result[\"preview\"].append({\n \"line\": row_idx + 2, \"source_term\": source_term, \"target_term\": target_term,\n \"context_notes\": context_notes, \"source_language\": source_language,\n \"target_language\": target_language, \"is_conflict\": existing is not None,\n \"existing_target_term\": existing.target_term if existing else None,\n })\n continue\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dict_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n if existing:\n if on_conflict == \"overwrite\":\n existing.source_term = source_term\n existing.target_term = target_term\n existing.context_notes = context_notes\n existing.source_language = source_language\n existing.target_language = target_language\n result[\"updated\"] += 1\n elif on_conflict == \"keep_existing\":\n result[\"skipped\"] += 1\n else:\n result[\"errors\"].append({\"line\": row_idx + 2, \"error\": f\"Conflict on '{source_term}' and on_conflict='cancel'\", \"row\": row})\n continue\n else:\n entry = DictionaryEntry(\n dictionary_id=dict_id, source_term=source_term,\n source_term_normalized=normalized, target_term=target_term,\n context_notes=context_notes, source_language=source_language,\n target_language=target_language,\n )\n db.add(entry)\n result[\"created\"] += 1\n except Exception as e:\n result[\"errors\"].append({\"line\": row_idx + 2, \"error\": str(e), \"row\": row})\n\n if not preview_only:\n db.commit()\n\n logger.reflect(\"Import complete\", {\"dict_id\": dict_id, \"total\": result[\"total\"], \"created\": result[\"created\"]})\n return result\n # endregion import_entries\n\n # region export_entries [TYPE Function]\n # @PURPOSE: Export all entries as CSV string with language columns.\n @staticmethod\n def export_entries(db: Session, dict_id: str, delimiter: str = \",\") -> str:\n with belief_scope(\"DictionaryImportExport.export_entries\"):\n dictionary = db.query(TerminologyDictionary).filter(TerminologyDictionary.id == dict_id).first()\n if not dictionary:\n raise ValueError(f\"Dictionary not found: {dict_id}\")\n\n entries = (\n db.query(DictionaryEntry)\n .filter(DictionaryEntry.dictionary_id == dict_id)\n .order_by(DictionaryEntry.source_term.asc())\n .all()\n )\n\n output = io.StringIO()\n fieldnames = [\"source_term\", \"target_term\", \"source_language\", \"target_language\", \"context_notes\", \"context_data\", \"usage_notes\"]\n writer = csv.DictWriter(output, fieldnames=fieldnames, delimiter=delimiter)\n writer.writeheader()\n for entry in entries:\n writer.writerow({\n \"source_term\": entry.source_term, \"target_term\": entry.target_term,\n \"source_language\": entry.source_language, \"target_language\": entry.target_language,\n \"context_notes\": entry.context_notes or \"\", \"context_data\": entry.context_data,\n \"usage_notes\": entry.usage_notes or \"\",\n })\n\n result = output.getvalue()\n logger.reflect(\"Entries exported\", {\"dict_id\": dict_id, \"count\": len(entries)})\n return result\n # endregion export_entries\n\n # region migrate_old_entries [TYPE Function]\n # @PURPOSE: Migrate existing single-language dictionary entries to populate source_language and target_language.\n @staticmethod\n def migrate_old_entries(db: Session) -> dict[str, int]:\n with belief_scope(\"DictionaryImportExport.migrate_old_entries\"):\n logger.reason(\"Starting migration of old dictionary entries\")\n migrated_source = 0\n migrated_target = 0\n skipped = 0\n\n entries = (\n db.query(DictionaryEntry)\n .filter(\n (DictionaryEntry.source_language == \"und\") |\n (DictionaryEntry.target_language == \"und\")\n )\n .all()\n )\n\n for entry in entries:\n if entry.source_language == \"und\":\n if entry.origin_source_language:\n entry.source_language = entry.origin_source_language\n migrated_source += 1\n if entry.source_language == \"und\" and entry.target_language == \"und\":\n skipped += 1\n\n db.commit()\n logger.reflect(\"Migration complete\", {\"migrated_source\": migrated_source, \"total_processed\": len(entries)})\n return {\"migrated_source\": migrated_source, \"migrated_target\": migrated_target, \"skipped\": skipped, \"total_processed\": len(entries)}\n # endregion migrate_old_entries\n\n# #endregion DictionaryImportExport\n"
},
{
"contract_id": "_validate_bcp47",
@@ -37470,7 +37580,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TranslationExecutor [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, orchestration]\n# @BRIEF Process translation in batches: fetch source rows, call LLM, persist TranslationBatch\n# and TranslationRecord rows. Thin orchestrator — delegates to focused sub-services.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationBatch], [TranslationRecord], [TranslationRun]\n# @RELATION DEPENDS_ON -> [LLMProviderService], [DictionaryManager], [TranslationPreview]\n# @RELATION DEPENDS_ON -> [RunExecutionService], [BatchProcessingService]\n# @RELATION DEPENDS_ON -> [LLMTranslationService], [AdaptiveBatchSizer]\n# @PRE Valid TranslationRun with job configuration. DB session is available.\n# @POST TranslationBatch and TranslationRecord rows are created. Run status is updated.\n# @SIDE_EFFECT Calls LLM provider; creates DB rows; updates run statistics.\n# @DATA_CONTRACT Input: TranslationRun + Job -> Output: updated Run with batch/record rows\n# @INVARIANT Batch processing is independent — one batch failure does not affect others.\n# @RATIONALE Extracted from monolithic executor.py (1974 lines) into thin orchestrator\n# to comply with INV_7. Sub-services in _run_service, _batch_proc, _llm_call, _batch_sizer.\n# Module-level helpers moved to [EXT:internal:_utils].py.\n# @REJECTED Keeping monolithic executor.py at 1974 lines — violates INV_7 by +1574 lines.\n# Single monolithic LLM call — would lose all progress on any failure.\n\nfrom collections.abc import Callable\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import logger\nfrom ...models.translate import TranslationJob, TranslationRun, TranslationRunLanguageStats\nfrom ...services.llm_provider import LLMProviderService\nfrom ._run_service import RunExecutionService\nfrom ._token_budget import estimate_token_budget\nfrom .[EXT:internal:_utils] import _check_translation_cache, _compute_source_hash, _enforce_dictionary, estimate_row_tokens\n\n__all__ = [\n \"TranslationExecutor\", \"estimate_row_tokens\",\n \"_enforce_dictionary\", \"_compute_source_hash\", \"_check_translation_cache\",\n]\n\n\nclass TranslationExecutor:\n \"\"\"Process translation batches. Thin orchestrator delegating to sub-services.\"\"\"\n\n def __init__(\n self, db: Session, config_manager: ConfigManager,\n current_user: str | None = None,\n on_batch_progress: Callable[[str, int, int, int, int], None] | None = None,\n ):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.on_batch_progress = on_batch_progress\n self._preview_edits_cache: dict[str, dict[str, str]] | None = None\n self._run_service = RunExecutionService(db, config_manager, current_user, on_batch_progress)\n\n # region execute_run [C:3] [TYPE Function] [SEMANTICS translate, run, orchestrate]\n # @BRIEF Run full translation execution. Logic on self for test-patch compatibility.\n # @PRE run is in PENDING or RUNNING status with valid job config.\n # @POST Run is populated with batches and records.\n # @SIDE_EFFECT LLM API calls; DB batch writes.\n def execute_run(\n self, run: TranslationRun,\n llm_progress_callback: Callable[[str, int, int, int], None] | None = None,\n language_stats_map: dict[str, TranslationRunLanguageStats] | None = None,\n ) -> TranslationRun:\n \"\"\"Execute full translation run. Logic on self for test-patch compatibility.\"\"\"\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found for run '{run.id}'\")\n logger.reason(\"Starting translation execution\", {\"run_id\": run.id, \"job_id\": job.id})\n\n run, source_rows, job = self._prepare_run(run, job)\n if run.status != \"RUNNING\":\n return run\n\n target_languages, batches = self._prepare_batches(job, source_rows, run.id)\n run.total_records = len(source_rows)\n logger.reason(f\"Processing {len(batches)} batches\", {\"run_id\": run.id, \"total_rows\": run.total_records})\n\n return self._process_batches(run, job, batches, target_languages, language_stats_map)\n # endregion execute_run\n\n # region _prepare_run [C:2] [TYPE Function]\n def _prepare_run(self, run: TranslationRun, job: TranslationJob) -> tuple:\n \"\"\"Prepare run: load preview edits, fetch source rows, filter new keys.\"\"\"\n self._load_preview_edits(job.id)\n run.status = \"RUNNING\"\n run.started_at = datetime.now(UTC)\n self.db.flush()\n\n full_translation = False\n if run.config_snapshot and isinstance(run.config_snapshot, dict):\n full_translation = run.config_snapshot.get(\"full_translation\", False)\n\n source_rows = self._fetch_source_rows(job.id, run.id)\n if not source_rows:\n logger.explore(\"No source rows to translate\", {\"run_id\": run.id})\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n return run, [], job\n\n if run.trigger_type == \"new_key_only\" or (not full_translation and run.trigger_type == \"manual\"):\n source_rows = self._filter_new_keys(job, run.id, source_rows)\n if not source_rows:\n logger.reason(\"run_noop — no new rows to translate\", {\"job_id\": job.id, \"run_id\": run.id})\n run.status = \"COMPLETED\"\n run.insert_status = \"skipped\"\n run.total_records = 0\n run.completed_at = datetime.now(UTC)\n self.db.commit()\n return run, [], job\n return run, source_rows, job\n # endregion _prepare_run\n\n # region _prepare_batches [C:2] [TYPE Function]\n def _prepare_batches(self, job: TranslationJob, source_rows: list, run_id: str) -> tuple:\n \"\"\"Resolve target languages and create auto-sized batches.\"\"\"\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n batches = self._auto_size_batches(job=job, source_rows=source_rows, target_languages=target_languages)\n return target_languages, batches\n # endregion _prepare_batches\n\n # region _process_batches [C:3] [TYPE Function]\n def _process_batches(self, run: TranslationRun, job: TranslationJob, batches: list,\n target_languages: list[str],\n language_stats_map: dict[str, TranslationRunLanguageStats] | None = None) -> TranslationRun:\n \"\"\"Process all batches: execute, insert to target, check cancellation.\"\"\"\n successful_records = failed_records = skipped_records = 0\n for batch_idx, batch_rows in enumerate(batches):\n batch_result = self._process_batch(\n job=job, run_id=run.id, batch_index=batch_idx, batch_rows=batch_rows,\n dict_snapshot_hash=run.dict_snapshot_hash, config_hash=run.config_hash,\n )\n successful_records += batch_result.get(\"successful\", 0)\n failed_records += batch_result.get(\"failed\", 0)\n skipped_records += batch_result.get(\"skipped\", 0)\n run.successful_records = successful_records\n run.failed_records = failed_records\n run.skipped_records = skipped_records\n self.db.commit()\n\n batch_id = batch_result.get(\"batch_id\")\n if batch_id and batch_result.get(\"successful\", 0) > 0:\n try:\n self._insert_batch_to_target(job, batch_id, run.id)\n except Exception as e:\n logger.explore(\"Batch INSERT failed (non-fatal)\", {\"batch_id\": batch_id, \"error\": str(e)})\n\n self.db.refresh(run)\n if run.error_message == \"CANCEL_REQUESTED\":\n logger.reason(\"Cancellation requested — stopping\", {\"run_id\": run.id, \"batch_index\": batch_idx})\n run.status = \"CANCELLED\"\n run.completed_at = datetime.now(UTC)\n run.error_message = None\n self.db.commit()\n return run\n\n if language_stats_map and batch_result.get(\"successful\", 0) > 0:\n try:\n self._update_language_stats_incremental(run.id, language_stats_map)\n except Exception as e:\n logger.explore(\"Language stats update failed (non-fatal)\", {\"batch_id\": batch_id, \"error\": str(e)})\n if self.on_batch_progress:\n self.on_batch_progress(run.id, batch_idx + 1, len(batches), successful_records, run.total_records or 0)\n\n return self._finalize_run(run, successful_records, failed_records, skipped_records)\n # endregion _process_batches\n\n @staticmethod\n def _finalize_run(run: TranslationRun, s: int, f: int, sk: int) -> TranslationRun:\n if f == 0 and sk == 0:\n run.status = \"COMPLETED\"\n elif s == 0:\n run.status = \"FAILED\"\n run.error_message = f\"All {f} record(s) failed — see individual record errors for details\"\n else:\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n logger.reflect(\"Translation execution complete\", {\"run_id\": run.id, \"status\": run.status,\n \"successful\": s, \"failed\": f, \"skipped\": sk})\n return run\n\n # -- Delegation methods (thin wrappers for test-patch compatibility) --\n def _fetch_source_rows(self, job_id: str, run_id: str) -> list[dict[str, Any]]:\n return self._run_service._fetch_source_rows(job_id, run_id)\n\n def _filter_new_keys(self, job, run_id: str, source_rows: list) -> list:\n return self._run_service._filter_new_keys(job, run_id, source_rows)\n\n @staticmethod\n def _extract_chart_data_rows(response: dict[str, Any]) -> list[dict[str, Any]]:\n return RunExecutionService._extract_chart_data_rows(response)\n\n def _load_preview_edits(self, job_id: str) -> None:\n self._run_service._load_preview_edits(job_id)\n self._preview_edits_cache = self._run_service._preview_edits_cache\n\n @staticmethod\n def _compute_key_hash(source_data: dict) -> str:\n return RunExecutionService._compute_key_hash(source_data)\n\n def _update_language_stats_incremental(self, run_id: str, language_stats_map) -> None:\n self._run_service._update_language_stats_incremental(run_id, language_stats_map)\n\n def _resolve_provider_model(self, job) -> str | None:\n \"\"\"Resolve the LLM provider model name for token budget estimation.\"\"\"\n if not job.provider_id:\n return None\n try:\n p_svc = LLMProviderService(self.db)\n p = p_svc.get_provider(job.provider_id)\n if p:\n return p.default_model or \"gpt-4o-mini\"\n except Exception:\n pass\n return None\n\n def _auto_size_batches(self, job, source_rows, target_languages, provider_info=None) -> list:\n \"\"\"Split source rows into auto-sized batches based on content length.\"\"\"\n from ._batch_sizer import AdaptiveBatchSizer\n if provider_info is None:\n provider_info = self._resolve_provider_model(job)\n return AdaptiveBatchSizer(self.db, self.config_manager).auto_size_batches(\n job, source_rows, target_languages, provider_info)\n\n def _process_batch(self, job, run_id, batch_index, batch_rows, dict_snapshot_hash=None, config_hash=None) -> dict:\n from ._batch_proc import BatchProcessingService\n return BatchProcessingService(self.db, self.config_manager).process_batch(\n job, run_id, batch_index, batch_rows, dict_snapshot_hash, config_hash,\n preview_edits_cache=self._preview_edits_cache)\n\n def _insert_batch_to_target(self, job, batch_id, run_id) -> None:\n from ._batch_proc import BatchProcessingService\n BatchProcessingService(self.db, self.config_manager).insert_batch_to_target(job, batch_id, run_id)\n\n def _call_llm_for_batch(self, job, run_id, batch_rows, dict_matches, batch_id, max_tokens=8192, _recursion_depth=0) -> dict:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService(self.db).call_llm_for_batch(\n job, run_id, batch_rows, dict_matches, batch_id, max_tokens, _recursion_depth)\n\n def _call_llm(self, job, prompt, max_tokens=8192) -> tuple:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService(self.db).call_llm(job, prompt, max_tokens)\n\n @staticmethod\n def _call_openai_compatible(base_url, api_key, model, prompt, provider_type=\"openai\", max_tokens=8192, disable_reasoning=False) -> tuple:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService.call_openai_compatible(base_url, api_key, model, prompt, provider_type, max_tokens, disable_reasoning)\n\n @staticmethod\n def _parse_llm_response(response_text, expected_count, target_languages=None, finish_reason=None) -> dict:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService._parse_llm_response(response_text, expected_count, target_languages, finish_reason)\n# #endregion TranslationExecutor\n"
+ "body": "# #region TranslationExecutor [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, orchestration]\n# @BRIEF Process translation in batches: fetch source rows, call LLM, persist TranslationBatch\n# and TranslationRecord rows. Thin orchestrator — delegates to focused sub-services.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationBatch], [TranslationRecord], [TranslationRun]\n# @RELATION DEPENDS_ON -> [LLMProviderService], [DictionaryManager], [TranslationPreview]\n# @RELATION DEPENDS_ON -> [RunExecutionService], [BatchProcessingService]\n# @RELATION DEPENDS_ON -> [LLMTranslationService], [AdaptiveBatchSizer]\n# @PRE Valid TranslationRun with job configuration. DB session is available.\n# @POST TranslationBatch and TranslationRecord rows are created. Run status is updated.\n# @SIDE_EFFECT Calls LLM provider; creates DB rows; updates run statistics.\n# @DATA_CONTRACT Input: TranslationRun + Job -> Output: updated Run with batch/record rows\n# @INVARIANT Batch processing is independent — one batch failure does not affect others.\n# @RATIONALE Extracted from monolithic executor.py (1974 lines) into thin orchestrator\n# to comply with INV_7. Sub-services in _run_service, _batch_proc, _llm_call, _batch_sizer.\n# Module-level helpers moved to _utils.py.\n# @REJECTED Keeping monolithic executor.py at 1974 lines — violates INV_7 by +1574 lines.\n# Single monolithic LLM call — would lose all progress on any failure.\n\nfrom collections.abc import Callable\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import logger\nfrom ...models.translate import TranslationJob, TranslationRun, TranslationRunLanguageStats\nfrom ...services.llm_provider import LLMProviderService\nfrom ._run_service import RunExecutionService\nfrom ._token_budget import estimate_token_budget\nfrom ._utils import _check_translation_cache, _compute_source_hash, _enforce_dictionary, estimate_row_tokens\n\n__all__ = [\n \"TranslationExecutor\", \"estimate_row_tokens\",\n \"_enforce_dictionary\", \"_compute_source_hash\", \"_check_translation_cache\",\n]\n\n\nclass TranslationExecutor:\n \"\"\"Process translation batches. Thin orchestrator delegating to sub-services.\"\"\"\n\n def __init__(\n self, db: Session, config_manager: ConfigManager,\n current_user: str | None = None,\n on_batch_progress: Callable[[str, int, int, int, int], None] | None = None,\n ):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n self.on_batch_progress = on_batch_progress\n self._preview_edits_cache: dict[str, dict[str, str]] | None = None\n self._run_service = RunExecutionService(db, config_manager, current_user, on_batch_progress)\n\n # region execute_run [C:3] [TYPE Function] [SEMANTICS translate, run, orchestrate]\n # @BRIEF Run full translation execution. Logic on self for test-patch compatibility.\n # @PRE run is in PENDING or RUNNING status with valid job config.\n # @POST Run is populated with batches and records.\n # @SIDE_EFFECT LLM API calls; DB batch writes.\n def execute_run(\n self, run: TranslationRun,\n llm_progress_callback: Callable[[str, int, int, int], None] | None = None,\n language_stats_map: dict[str, TranslationRunLanguageStats] | None = None,\n ) -> TranslationRun:\n \"\"\"Execute full translation run. Logic on self for test-patch compatibility.\"\"\"\n job = self.db.query(TranslationJob).filter(TranslationJob.id == run.job_id).first()\n if not job:\n raise ValueError(f\"Job '{run.job_id}' not found for run '{run.id}'\")\n logger.reason(\"Starting translation execution\", {\"run_id\": run.id, \"job_id\": job.id})\n\n run, source_rows, job = self._prepare_run(run, job)\n if run.status != \"RUNNING\":\n return run\n\n target_languages, batches = self._prepare_batches(job, source_rows, run.id)\n run.total_records = len(source_rows)\n logger.reason(f\"Processing {len(batches)} batches\", {\"run_id\": run.id, \"total_rows\": run.total_records})\n\n return self._process_batches(run, job, batches, target_languages, language_stats_map)\n # endregion execute_run\n\n # region _prepare_run [C:2] [TYPE Function]\n def _prepare_run(self, run: TranslationRun, job: TranslationJob) -> tuple:\n \"\"\"Prepare run: load preview edits, fetch source rows, filter new keys.\"\"\"\n self._load_preview_edits(job.id)\n run.status = \"RUNNING\"\n run.started_at = datetime.now(UTC)\n self.db.flush()\n\n full_translation = False\n if run.config_snapshot and isinstance(run.config_snapshot, dict):\n full_translation = run.config_snapshot.get(\"full_translation\", False)\n\n source_rows = self._fetch_source_rows(job.id, run.id)\n if not source_rows:\n logger.explore(\"No source rows to translate\", {\"run_id\": run.id})\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n self.db.flush()\n return run, [], job\n\n if run.trigger_type == \"new_key_only\" or (not full_translation and run.trigger_type == \"manual\"):\n source_rows = self._filter_new_keys(job, run.id, source_rows)\n if not source_rows:\n logger.reason(\"run_noop — no new rows to translate\", {\"job_id\": job.id, \"run_id\": run.id})\n run.status = \"COMPLETED\"\n run.insert_status = \"skipped\"\n run.total_records = 0\n run.completed_at = datetime.now(UTC)\n self.db.commit()\n return run, [], job\n return run, source_rows, job\n # endregion _prepare_run\n\n # region _prepare_batches [C:2] [TYPE Function]\n def _prepare_batches(self, job: TranslationJob, source_rows: list, run_id: str) -> tuple:\n \"\"\"Resolve target languages and create auto-sized batches.\"\"\"\n target_languages = job.target_languages or [job.target_dialect or \"en\"]\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n batches = self._auto_size_batches(job=job, source_rows=source_rows, target_languages=target_languages)\n return target_languages, batches\n # endregion _prepare_batches\n\n # region _process_batches [C:3] [TYPE Function]\n def _process_batches(self, run: TranslationRun, job: TranslationJob, batches: list,\n target_languages: list[str],\n language_stats_map: dict[str, TranslationRunLanguageStats] | None = None) -> TranslationRun:\n \"\"\"Process all batches: execute, insert to target, check cancellation.\"\"\"\n successful_records = failed_records = skipped_records = 0\n for batch_idx, batch_rows in enumerate(batches):\n batch_result = self._process_batch(\n job=job, run_id=run.id, batch_index=batch_idx, batch_rows=batch_rows,\n dict_snapshot_hash=run.dict_snapshot_hash, config_hash=run.config_hash,\n )\n successful_records += batch_result.get(\"successful\", 0)\n failed_records += batch_result.get(\"failed\", 0)\n skipped_records += batch_result.get(\"skipped\", 0)\n run.successful_records = successful_records\n run.failed_records = failed_records\n run.skipped_records = skipped_records\n self.db.commit()\n\n batch_id = batch_result.get(\"batch_id\")\n if batch_id and batch_result.get(\"successful\", 0) > 0:\n try:\n self._insert_batch_to_target(job, batch_id, run.id)\n except Exception as e:\n logger.explore(\"Batch INSERT failed (non-fatal)\", {\"batch_id\": batch_id, \"error\": str(e)})\n\n self.db.refresh(run)\n if run.error_message == \"CANCEL_REQUESTED\":\n logger.reason(\"Cancellation requested — stopping\", {\"run_id\": run.id, \"batch_index\": batch_idx})\n run.status = \"CANCELLED\"\n run.completed_at = datetime.now(UTC)\n run.error_message = None\n self.db.commit()\n return run\n\n if language_stats_map and batch_result.get(\"successful\", 0) > 0:\n try:\n self._update_language_stats_incremental(run.id, language_stats_map)\n except Exception as e:\n logger.explore(\"Language stats update failed (non-fatal)\", {\"batch_id\": batch_id, \"error\": str(e)})\n if self.on_batch_progress:\n self.on_batch_progress(run.id, batch_idx + 1, len(batches), successful_records, run.total_records or 0)\n\n return self._finalize_run(run, successful_records, failed_records, skipped_records)\n # endregion _process_batches\n\n @staticmethod\n def _finalize_run(run: TranslationRun, s: int, f: int, sk: int) -> TranslationRun:\n if f == 0 and sk == 0:\n run.status = \"COMPLETED\"\n elif s == 0:\n run.status = \"FAILED\"\n run.error_message = f\"All {f} record(s) failed — see individual record errors for details\"\n else:\n run.status = \"COMPLETED\"\n run.completed_at = datetime.now(UTC)\n logger.reflect(\"Translation execution complete\", {\"run_id\": run.id, \"status\": run.status,\n \"successful\": s, \"failed\": f, \"skipped\": sk})\n return run\n\n # -- Delegation methods (thin wrappers for test-patch compatibility) --\n def _fetch_source_rows(self, job_id: str, run_id: str) -> list[dict[str, Any]]:\n return self._run_service._fetch_source_rows(job_id, run_id)\n\n def _filter_new_keys(self, job, run_id: str, source_rows: list) -> list:\n return self._run_service._filter_new_keys(job, run_id, source_rows)\n\n @staticmethod\n def _extract_chart_data_rows(response: dict[str, Any]) -> list[dict[str, Any]]:\n return RunExecutionService._extract_chart_data_rows(response)\n\n def _load_preview_edits(self, job_id: str) -> None:\n self._run_service._load_preview_edits(job_id)\n self._preview_edits_cache = self._run_service._preview_edits_cache\n\n @staticmethod\n def _compute_key_hash(source_data: dict) -> str:\n return RunExecutionService._compute_key_hash(source_data)\n\n def _update_language_stats_incremental(self, run_id: str, language_stats_map) -> None:\n self._run_service._update_language_stats_incremental(run_id, language_stats_map)\n\n def _resolve_provider_model(self, job) -> str | None:\n \"\"\"Resolve the LLM provider model name for token budget estimation.\"\"\"\n if not job.provider_id:\n return None\n try:\n p_svc = LLMProviderService(self.db)\n p = p_svc.get_provider(job.provider_id)\n if p:\n return p.default_model or \"gpt-4o-mini\"\n except Exception:\n pass\n return None\n\n def _auto_size_batches(self, job, source_rows, target_languages, provider_info=None) -> list:\n \"\"\"Split source rows into auto-sized batches based on content length.\"\"\"\n from ._batch_sizer import AdaptiveBatchSizer\n if provider_info is None:\n provider_info = self._resolve_provider_model(job)\n return AdaptiveBatchSizer(self.db, self.config_manager).auto_size_batches(\n job, source_rows, target_languages, provider_info)\n\n def _process_batch(self, job, run_id, batch_index, batch_rows, dict_snapshot_hash=None, config_hash=None) -> dict:\n from ._batch_proc import BatchProcessingService\n return BatchProcessingService(self.db, self.config_manager).process_batch(\n job, run_id, batch_index, batch_rows, dict_snapshot_hash, config_hash,\n preview_edits_cache=self._preview_edits_cache)\n\n def _insert_batch_to_target(self, job, batch_id, run_id) -> None:\n from ._batch_proc import BatchProcessingService\n BatchProcessingService(self.db, self.config_manager).insert_batch_to_target(job, batch_id, run_id)\n\n def _call_llm_for_batch(self, job, run_id, batch_rows, dict_matches, batch_id, max_tokens=8192, _recursion_depth=0) -> dict:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService(self.db).call_llm_for_batch(\n job, run_id, batch_rows, dict_matches, batch_id, max_tokens, _recursion_depth)\n\n def _call_llm(self, job, prompt, max_tokens=8192) -> tuple:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService(self.db).call_llm(job, prompt, max_tokens)\n\n @staticmethod\n def _call_openai_compatible(base_url, api_key, model, prompt, provider_type=\"openai\", max_tokens=8192, disable_reasoning=False) -> tuple:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService.call_openai_compatible(base_url, api_key, model, prompt, provider_type, max_tokens, disable_reasoning)\n\n @staticmethod\n def _parse_llm_response(response_text, expected_count, target_languages=None, finish_reason=None) -> dict:\n from ._llm_call import LLMTranslationService\n return LLMTranslationService._parse_llm_response(response_text, expected_count, target_languages, finish_reason)\n# #endregion TranslationExecutor\n"
},
{
"contract_id": "TranslationMetrics",
@@ -38230,7 +38340,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TranslatePlugin [C:2] [TYPE Module] [SEMANTICS clickhouse, translate, sql, dashboard, dialect]\n# @BRIEF TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.\n# @LAYER Domain\n# @RELATION INHERITS -> [PluginBase]\n# @RATIONALE Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines).\n# @REJECTED Extending LLMAnalysisPlugin would conflate two distinct feature domains.\n\nfrom typing import Any\n\nfrom ...core.plugin_base import PluginBase\n\n\n# #region TranslatePlugin [TYPE Class]\n# @BRIEF Plugin for translating SQL queries and dashboard definitions across database dialects.\n# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]\nclass TranslatePlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"translate\"\n\n @property\n def name(self) -> str:\n return \"LLM Table Translation\"\n\n @property\n def description(self) -> str:\n return \"Cross-dialect SQL and dashboard translation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"source_dialect\": {\n \"type\": \"string\",\n \"title\": \"Source Dialect\",\n \"description\": \"Source database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"target_dialect\": {\n \"type\": \"string\",\n \"title\": \"Target Dialect\",\n \"description\": \"Target database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"job_id\": {\n \"type\": \"string\",\n \"title\": \"Translation Job ID\",\n \"description\": \"Existing translation job to execute\",\n },\n },\n \"required\": [\"job_id\"],\n }\n\n async def execute(self, params: dict[str, Any], context: Any | None = None):\n \"\"\"Execute a translation job — implementation deferred to later phases.\"\"\"\n raise NotImplementedError(\"TranslatePlugin.execute not yet implemented\")\n# #endregion TranslatePlugin\n\n# #endregion TranslatePlugin\n"
+ "body": "# #region TranslatePlugin [C:2] [TYPE Module] [SEMANTICS clickhouse, translate, sql, dashboard, dialect]\n# @BRIEF TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.\n# @LAYER Domain\n# @RELATION INHERITS -> [PluginBase]\n# @RATIONALE Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines).\n# @REJECTED Extending LLMAnalysisPlugin would conflate two distinct feature domains.\n\nfrom typing import Any\n\nfrom ...core.plugin_base import PluginBase\n\n\n# #region TranslatePlugin [TYPE Class]\n# @BRIEF Plugin for translating SQL queries and dashboard definitions across database dialects.\n# @RELATION IMPLEMENTS -> [PluginBase]\nclass TranslatePlugin(PluginBase):\n @property\n def id(self) -> str:\n return \"translate\"\n\n @property\n def name(self) -> str:\n return \"LLM Table Translation\"\n\n @property\n def description(self) -> str:\n return \"Cross-dialect SQL and dashboard translation using LLMs.\"\n\n @property\n def version(self) -> str:\n return \"1.0.0\"\n\n def get_schema(self) -> dict[str, Any]:\n return {\n \"type\": \"object\",\n \"properties\": {\n \"source_dialect\": {\n \"type\": \"string\",\n \"title\": \"Source Dialect\",\n \"description\": \"Source database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"target_dialect\": {\n \"type\": \"string\",\n \"title\": \"Target Dialect\",\n \"description\": \"Target database dialect (e.g. PostgreSQL, ClickHouse)\",\n },\n \"job_id\": {\n \"type\": \"string\",\n \"title\": \"Translation Job ID\",\n \"description\": \"Existing translation job to execute\",\n },\n },\n \"required\": [\"job_id\"],\n }\n\n async def execute(self, params: dict[str, Any], context: Any | None = None):\n \"\"\"Execute a translation job — implementation deferred to later phases.\"\"\"\n raise NotImplementedError(\"TranslatePlugin.execute not yet implemented\")\n# #endregion TranslatePlugin\n\n# #endregion TranslatePlugin\n"
},
{
"contract_id": "DEFAULT_EXECUTION_PROMPT_TEMPLATE",
@@ -38846,7 +38956,7 @@
"POST": "Translation jobs are created/updated/deleted with column validation and dialect caching.",
"PRE": "Database session and config manager are available.",
"RATIONALE": "Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.",
- "REJECTED": "Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service[EXT:internal:_utils].",
+ "REJECTED": "Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service_utils.",
"SIDE_EFFECT": "Queries Superset for column metadata and database dialect at save time."
},
"relations": [
@@ -38872,7 +38982,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TranslateJobService [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, job, datasource, dialect]\n# @BRIEF Service layer for translation job CRUD with datasource column validation and database dialect detection.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationJob]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @PRE Database session and config manager are available.\n# @POST Translation jobs are created/updated/deleted with column validation and dialect caching.\n# @SIDE_EFFECT Queries Superset for column metadata and database dialect at save time.\n# @RATIONALE Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.\n# @REJECTED Invalidating in-progress runs on config edit would break scheduled run continuity.\n# @REJECTED Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service[EXT:internal:_utils].\n\nfrom datetime import UTC, datetime\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import logger\nfrom ...models.translate import TranslationJob, TranslationJobDictionary\nfrom ...schemas.translate import TranslateJobCreate, TranslateJobUpdate\nfrom .dictionary import _validate_bcp47\nfrom .service_datasource import fetch_datasource_metadata\nfrom .service[EXT:internal:_utils] import _extract_dialect, job_to_response\n\n\n# #region TranslateJobService [TYPE Class]\n# @BRIEF Service for translation job CRUD with validation and Superset integration.\nclass TranslateJobService:\n \"\"\"CRUD service for translation jobs with Superset datasource integration.\"\"\"\n\n def __init__(self, db: Session, config_manager: ConfigManager, current_user: str | None = None):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n\n # region list_jobs [TYPE Function]\n # @PURPOSE: List translation jobs with optional status filter and pagination.\n def list_jobs(\n self,\n page: int = 1,\n page_size: int = 20,\n status_filter: str | None = None,\n ) -> tuple[int, list[TranslationJob]]:\n query = self.db.query(TranslationJob)\n if status_filter:\n query = query.filter(TranslationJob.status == status_filter)\n total = query.count()\n offset = (page - 1) * page_size\n jobs = query.order_by(TranslationJob.created_at.desc()).offset(offset).limit(page_size).all()\n return total, jobs\n # endregion list_jobs\n\n # region get_job [TYPE Function]\n # @PURPOSE: Get a single translation job by ID.\n def get_job(self, job_id: str) -> TranslationJob:\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n if not job:\n raise ValueError(f\"Translation job '{job_id}' not found\")\n return job\n # endregion get_job\n\n # region create_job [TYPE Function]\n # @PURPOSE: Create a new translation job with column validation.\n # @SIDE_EFFECT Validates columns via SupersetClient; caches database_dialect.\n def create_job(self, payload: TranslateJobCreate) -> TranslationJob:\n logger.info(f\"[TranslateJobService] Creating job '{payload.name}'\")\n if payload.source_datasource_id and not payload.translation_column:\n raise ValueError(\"A translation column is required when a datasource is selected\")\n valid_strategies = {\"MERGE\", \"INSERT\", \"UPDATE\"}\n if payload.upsert_strategy not in valid_strategies:\n raise ValueError(\n f\"Invalid upsert_strategy '{payload.upsert_strategy}'. \"\n f\"Must be one of: {', '.join(sorted(valid_strategies))}\"\n )\n\n dialect = payload.database_dialect\n if payload.source_datasource_id and (payload.environment_id or payload.source_dialect):\n if not dialect:\n try:\n env_id = payload.environment_id or payload.source_dialect\n _, detected_dialect = fetch_datasource_metadata(\n int(payload.source_datasource_id), env_id, self.config_manager,\n )\n dialect = detected_dialect\n except Exception as e:\n logger.warning(f\"[TranslateJobService] Dialect detection failed: {e}\")\n dialect = payload.source_dialect\n\n target_languages = payload.target_languages\n if not target_languages and payload.target_language:\n target_languages = [payload.target_language]\n if target_languages:\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n for lang in target_languages:\n _validate_bcp47(lang, \"target_languages\")\n\n job = TranslationJob(\n id=str(uuid.uuid4()), name=payload.name, description=payload.description,\n source_dialect=payload.source_dialect, target_dialect=payload.target_dialect,\n database_dialect=dialect, source_datasource_id=payload.source_datasource_id,\n source_table=payload.source_table, target_schema=payload.target_schema,\n target_table=payload.target_table, source_key_cols=payload.source_key_cols or [],\n target_key_cols=payload.target_key_cols or [],\n translation_column=payload.translation_column, target_column=payload.target_column,\n target_language_column=payload.target_language_column,\n target_source_column=payload.target_source_column,\n target_source_language_column=payload.target_source_language_column,\n context_columns=payload.context_columns or [], target_languages=target_languages,\n provider_id=payload.provider_id, batch_size=payload.batch_size,\n upsert_strategy=payload.upsert_strategy, environment_id=payload.environment_id,\n target_database_id=payload.target_database_id,\n status=\"DRAFT\", created_by=self.current_user,\n )\n self.db.add(job)\n self.db.flush()\n\n if payload.dictionary_ids:\n for dict_id in payload.dictionary_ids:\n self.db.add(TranslationJobDictionary(\n id=str(uuid.uuid4()), job_id=job.id, dictionary_id=dict_id,\n ))\n\n self.db.commit()\n self.db.refresh(job)\n logger.info(f\"[TranslateJobService] Created job '{job.id}'\")\n return job\n # endregion create_job\n\n # region update_job [TYPE Function]\n # @PURPOSE: Update an existing translation job.\n # @SIDE_EFFECT Re-detects database_dialect if source_datasource_id changed.\n def update_job(self, job_id: str, payload: TranslateJobUpdate) -> TranslationJob:\n logger.info(f\"[TranslateJobService] Updating job '{job_id}'\")\n job = self.get_job(job_id)\n update_data = payload.model_dump(exclude_unset=True)\n dict_ids = update_data.pop(\"dictionary_ids\", None)\n\n if \"target_language\" in update_data:\n tl = update_data.pop(\"target_language\")\n if tl and \"target_languages\" not in update_data:\n update_data[\"target_languages\"] = [tl]\n\n if update_data.get(\"target_languages\"):\n if not isinstance(update_data[\"target_languages\"], list):\n update_data[\"target_languages\"] = [str(update_data[\"target_languages\"])]\n for lang in update_data[\"target_languages\"]:\n _validate_bcp47(lang, \"target_languages\")\n\n for field, value in update_data.items():\n if hasattr(job, field):\n setattr(job, field, value)\n\n if payload.source_datasource_id and not payload.database_dialect:\n try:\n env_id = (payload.environment_id or payload.source_dialect or job.environment_id or job.source_dialect)\n _, detected_dialect = fetch_datasource_metadata(\n int(payload.source_datasource_id), env_id, self.config_manager,\n )\n job.database_dialect = detected_dialect\n except Exception as e:\n logger.warning(f\"[TranslateJobService] Dialect re-detection failed: {e}\")\n\n job.updated_at = datetime.now(UTC)\n\n if dict_ids is not None:\n self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).delete()\n for dict_id in dict_ids:\n self.db.add(TranslationJobDictionary(\n id=str(uuid.uuid4()), job_id=job_id, dictionary_id=dict_id,\n ))\n\n self.db.commit()\n self.db.refresh(job)\n logger.info(f\"[TranslateJobService] Updated job '{job_id}'\")\n return job\n # endregion update_job\n\n # region delete_job [TYPE Function]\n # @PURPOSE: Delete a translation job and its associations.\n def delete_job(self, job_id: str) -> None:\n logger.info(f\"[TranslateJobService] Deleting job '{job_id}'\")\n job = self.get_job(job_id)\n self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).delete()\n self.db.delete(job)\n self.db.commit()\n logger.info(f\"[TranslateJobService] Deleted job '{job_id}'\")\n # endregion delete_job\n\n # region duplicate_job [TYPE Function]\n # @PURPOSE: Duplicate a translation job with a new name.\n def duplicate_job(self, job_id: str, new_name: str | None = None) -> TranslationJob:\n logger.info(f\"[TranslateJobService] Duplicating job '{job_id}'\")\n source = self.get_job(job_id)\n new_job = TranslationJob(\n id=str(uuid.uuid4()), name=new_name or f\"{source.name} (Copy)\",\n description=source.description, source_dialect=source.source_dialect,\n target_dialect=source.target_dialect, database_dialect=source.database_dialect,\n source_datasource_id=source.source_datasource_id, source_table=source.source_table,\n target_schema=source.target_schema, target_table=source.target_table,\n source_key_cols=source.source_key_cols, target_key_cols=source.target_key_cols,\n translation_column=source.translation_column, target_column=source.target_column,\n target_language_column=source.target_language_column,\n target_source_column=source.target_source_column,\n target_source_language_column=source.target_source_language_column,\n context_columns=source.context_columns, target_languages=source.target_languages,\n provider_id=source.provider_id, batch_size=source.batch_size,\n upsert_strategy=source.upsert_strategy, status=\"DRAFT\",\n created_by=self.current_user,\n )\n self.db.add(new_job)\n self.db.flush()\n\n old_dicts = self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).all()\n for assoc in old_dicts:\n self.db.add(TranslationJobDictionary(\n id=str(uuid.uuid4()), job_id=new_job.id, dictionary_id=assoc.dictionary_id,\n ))\n\n self.db.commit()\n self.db.refresh(new_job)\n logger.info(f\"[TranslateJobService] Duplicated job '{job_id}' -> '{new_job.id}'\")\n return new_job\n # endregion duplicate_job\n\n # region get_job_dictionary_ids [TYPE Function]\n # @PURPOSE: Get dictionary IDs attached to a job.\n def get_job_dictionary_ids(self, job_id: str) -> list[str]:\n assocs = self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).all()\n return [a.dictionary_id for a in assocs]\n # endregion get_job_dictionary_ids\n\n # region fetch_available_datasources [TYPE Function]\n # @PURPOSE: List available Superset datasets for translation job creation.\n def fetch_available_datasources(self, env_id: str, search: str | None = None) -> list:\n from ...core.superset_client import SupersetClient\n env = self.config_manager.get_environment(env_id)\n if not env:\n raise ValueError(f\"Environment '{env_id}' not found\")\n client = SupersetClient(env)\n _, datasets = client.get_datasets()\n result = []\n for ds in datasets:\n name = ds.get(\"table_name\", \"\")\n if search and search.lower() not in name.lower():\n continue\n db_info = ds.get(\"database\", {})\n backend = db_info.get(\"backend\", \"\")\n dialect = _extract_dialect(backend)\n result.append({\n \"id\": ds.get(\"id\"),\n \"table_name\": name,\n \"schema\": ds.get(\"schema\"),\n \"database_name\": db_info.get(\"database_name\", \"Unknown\"),\n \"database_dialect\": dialect,\n \"description\": ds.get(\"description\", \"\"),\n })\n return result\n # endregion fetch_available_datasources\n# #endregion TranslateJobService\n\n\n# Re-exports for backward compatibility\nfrom .service_bulk_replace import BulkFindReplaceService # noqa: E402, F401\nfrom .service_datasource import ( # noqa: E402, F401\n detect_virtual_columns,\n fetch_datasource_metadata,\n get_datasource_columns,\n get_dialect_from_database,\n)\nfrom .service_inline_correction import InlineCorrectionService # noqa: E402, F401\nfrom .service[EXT:internal:_utils] import _extract_dialect, job_to_response # noqa: E402, F401\n# #endregion TranslateJobService\n"
+ "body": "# #region TranslateJobService [C:4] [TYPE Module] [SEMANTICS sqlalchemy, translate, job, datasource, dialect]\n# @BRIEF Service layer for translation job CRUD with datasource column validation and database dialect detection.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [TranslationJob]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [ConfigManager]\n# @PRE Database session and config manager are available.\n# @POST Translation jobs are created/updated/deleted with column validation and dialect caching.\n# @SIDE_EFFECT Queries Superset for column metadata and database dialect at save time.\n# @RATIONALE Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.\n# @REJECTED Invalidating in-progress runs on config edit would break scheduled run continuity.\n# @REJECTED Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service_utils.\n\nfrom datetime import UTC, datetime\nfrom typing import Any\nimport uuid\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.config_manager import ConfigManager\nfrom ...core.logger import logger\nfrom ...models.translate import TranslationJob, TranslationJobDictionary\nfrom ...schemas.translate import TranslateJobCreate, TranslateJobUpdate\nfrom .dictionary import _validate_bcp47\nfrom .service_datasource import fetch_datasource_metadata\nfrom .service_utils import _extract_dialect, job_to_response\n\n\n# #region TranslateJobService [TYPE Class]\n# @BRIEF Service for translation job CRUD with validation and Superset integration.\nclass TranslateJobService:\n \"\"\"CRUD service for translation jobs with Superset datasource integration.\"\"\"\n\n def __init__(self, db: Session, config_manager: ConfigManager, current_user: str | None = None):\n self.db = db\n self.config_manager = config_manager\n self.current_user = current_user\n\n # region list_jobs [TYPE Function]\n # @PURPOSE: List translation jobs with optional status filter and pagination.\n def list_jobs(\n self,\n page: int = 1,\n page_size: int = 20,\n status_filter: str | None = None,\n ) -> tuple[int, list[TranslationJob]]:\n query = self.db.query(TranslationJob)\n if status_filter:\n query = query.filter(TranslationJob.status == status_filter)\n total = query.count()\n offset = (page - 1) * page_size\n jobs = query.order_by(TranslationJob.created_at.desc()).offset(offset).limit(page_size).all()\n return total, jobs\n # endregion list_jobs\n\n # region get_job [TYPE Function]\n # @PURPOSE: Get a single translation job by ID.\n def get_job(self, job_id: str) -> TranslationJob:\n job = self.db.query(TranslationJob).filter(TranslationJob.id == job_id).first()\n if not job:\n raise ValueError(f\"Translation job '{job_id}' not found\")\n return job\n # endregion get_job\n\n # region create_job [TYPE Function]\n # @PURPOSE: Create a new translation job with column validation.\n # @SIDE_EFFECT Validates columns via SupersetClient; caches database_dialect.\n def create_job(self, payload: TranslateJobCreate) -> TranslationJob:\n logger.info(f\"[TranslateJobService] Creating job '{payload.name}'\")\n if payload.source_datasource_id and not payload.translation_column:\n raise ValueError(\"A translation column is required when a datasource is selected\")\n valid_strategies = {\"MERGE\", \"INSERT\", \"UPDATE\"}\n if payload.upsert_strategy not in valid_strategies:\n raise ValueError(\n f\"Invalid upsert_strategy '{payload.upsert_strategy}'. \"\n f\"Must be one of: {', '.join(sorted(valid_strategies))}\"\n )\n\n dialect = payload.database_dialect\n if payload.source_datasource_id and (payload.environment_id or payload.source_dialect):\n if not dialect:\n try:\n env_id = payload.environment_id or payload.source_dialect\n _, detected_dialect = fetch_datasource_metadata(\n int(payload.source_datasource_id), env_id, self.config_manager,\n )\n dialect = detected_dialect\n except Exception as e:\n logger.warning(f\"[TranslateJobService] Dialect detection failed: {e}\")\n dialect = payload.source_dialect\n\n target_languages = payload.target_languages\n if not target_languages and payload.target_language:\n target_languages = [payload.target_language]\n if target_languages:\n if not isinstance(target_languages, list):\n target_languages = [str(target_languages)]\n for lang in target_languages:\n _validate_bcp47(lang, \"target_languages\")\n\n job = TranslationJob(\n id=str(uuid.uuid4()), name=payload.name, description=payload.description,\n source_dialect=payload.source_dialect, target_dialect=payload.target_dialect,\n database_dialect=dialect, source_datasource_id=payload.source_datasource_id,\n source_table=payload.source_table, target_schema=payload.target_schema,\n target_table=payload.target_table, source_key_cols=payload.source_key_cols or [],\n target_key_cols=payload.target_key_cols or [],\n translation_column=payload.translation_column, target_column=payload.target_column,\n target_language_column=payload.target_language_column,\n target_source_column=payload.target_source_column,\n target_source_language_column=payload.target_source_language_column,\n context_columns=payload.context_columns or [], target_languages=target_languages,\n provider_id=payload.provider_id, batch_size=payload.batch_size,\n upsert_strategy=payload.upsert_strategy, environment_id=payload.environment_id,\n target_database_id=payload.target_database_id,\n status=\"DRAFT\", created_by=self.current_user,\n )\n self.db.add(job)\n self.db.flush()\n\n if payload.dictionary_ids:\n for dict_id in payload.dictionary_ids:\n self.db.add(TranslationJobDictionary(\n id=str(uuid.uuid4()), job_id=job.id, dictionary_id=dict_id,\n ))\n\n self.db.commit()\n self.db.refresh(job)\n logger.info(f\"[TranslateJobService] Created job '{job.id}'\")\n return job\n # endregion create_job\n\n # region update_job [TYPE Function]\n # @PURPOSE: Update an existing translation job.\n # @SIDE_EFFECT Re-detects database_dialect if source_datasource_id changed.\n def update_job(self, job_id: str, payload: TranslateJobUpdate) -> TranslationJob:\n logger.info(f\"[TranslateJobService] Updating job '{job_id}'\")\n job = self.get_job(job_id)\n update_data = payload.model_dump(exclude_unset=True)\n dict_ids = update_data.pop(\"dictionary_ids\", None)\n\n if \"target_language\" in update_data:\n tl = update_data.pop(\"target_language\")\n if tl and \"target_languages\" not in update_data:\n update_data[\"target_languages\"] = [tl]\n\n if update_data.get(\"target_languages\"):\n if not isinstance(update_data[\"target_languages\"], list):\n update_data[\"target_languages\"] = [str(update_data[\"target_languages\"])]\n for lang in update_data[\"target_languages\"]:\n _validate_bcp47(lang, \"target_languages\")\n\n for field, value in update_data.items():\n if hasattr(job, field):\n setattr(job, field, value)\n\n if payload.source_datasource_id and not payload.database_dialect:\n try:\n env_id = (payload.environment_id or payload.source_dialect or job.environment_id or job.source_dialect)\n _, detected_dialect = fetch_datasource_metadata(\n int(payload.source_datasource_id), env_id, self.config_manager,\n )\n job.database_dialect = detected_dialect\n except Exception as e:\n logger.warning(f\"[TranslateJobService] Dialect re-detection failed: {e}\")\n\n job.updated_at = datetime.now(UTC)\n\n if dict_ids is not None:\n self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).delete()\n for dict_id in dict_ids:\n self.db.add(TranslationJobDictionary(\n id=str(uuid.uuid4()), job_id=job_id, dictionary_id=dict_id,\n ))\n\n self.db.commit()\n self.db.refresh(job)\n logger.info(f\"[TranslateJobService] Updated job '{job_id}'\")\n return job\n # endregion update_job\n\n # region delete_job [TYPE Function]\n # @PURPOSE: Delete a translation job and its associations.\n def delete_job(self, job_id: str) -> None:\n logger.info(f\"[TranslateJobService] Deleting job '{job_id}'\")\n job = self.get_job(job_id)\n self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).delete()\n self.db.delete(job)\n self.db.commit()\n logger.info(f\"[TranslateJobService] Deleted job '{job_id}'\")\n # endregion delete_job\n\n # region duplicate_job [TYPE Function]\n # @PURPOSE: Duplicate a translation job with a new name.\n def duplicate_job(self, job_id: str, new_name: str | None = None) -> TranslationJob:\n logger.info(f\"[TranslateJobService] Duplicating job '{job_id}'\")\n source = self.get_job(job_id)\n new_job = TranslationJob(\n id=str(uuid.uuid4()), name=new_name or f\"{source.name} (Copy)\",\n description=source.description, source_dialect=source.source_dialect,\n target_dialect=source.target_dialect, database_dialect=source.database_dialect,\n source_datasource_id=source.source_datasource_id, source_table=source.source_table,\n target_schema=source.target_schema, target_table=source.target_table,\n source_key_cols=source.source_key_cols, target_key_cols=source.target_key_cols,\n translation_column=source.translation_column, target_column=source.target_column,\n target_language_column=source.target_language_column,\n target_source_column=source.target_source_column,\n target_source_language_column=source.target_source_language_column,\n context_columns=source.context_columns, target_languages=source.target_languages,\n provider_id=source.provider_id, batch_size=source.batch_size,\n upsert_strategy=source.upsert_strategy, status=\"DRAFT\",\n created_by=self.current_user,\n )\n self.db.add(new_job)\n self.db.flush()\n\n old_dicts = self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).all()\n for assoc in old_dicts:\n self.db.add(TranslationJobDictionary(\n id=str(uuid.uuid4()), job_id=new_job.id, dictionary_id=assoc.dictionary_id,\n ))\n\n self.db.commit()\n self.db.refresh(new_job)\n logger.info(f\"[TranslateJobService] Duplicated job '{job_id}' -> '{new_job.id}'\")\n return new_job\n # endregion duplicate_job\n\n # region get_job_dictionary_ids [TYPE Function]\n # @PURPOSE: Get dictionary IDs attached to a job.\n def get_job_dictionary_ids(self, job_id: str) -> list[str]:\n assocs = self.db.query(TranslationJobDictionary).filter(TranslationJobDictionary.job_id == job_id).all()\n return [a.dictionary_id for a in assocs]\n # endregion get_job_dictionary_ids\n\n # region fetch_available_datasources [TYPE Function]\n # @PURPOSE: List available Superset datasets for translation job creation.\n def fetch_available_datasources(self, env_id: str, search: str | None = None) -> list:\n from ...core.superset_client import SupersetClient\n env = self.config_manager.get_environment(env_id)\n if not env:\n raise ValueError(f\"Environment '{env_id}' not found\")\n client = SupersetClient(env)\n _, datasets = client.get_datasets()\n result = []\n for ds in datasets:\n name = ds.get(\"table_name\", \"\")\n if search and search.lower() not in name.lower():\n continue\n db_info = ds.get(\"database\", {})\n backend = db_info.get(\"backend\", \"\")\n dialect = _extract_dialect(backend)\n result.append({\n \"id\": ds.get(\"id\"),\n \"table_name\": name,\n \"schema\": ds.get(\"schema\"),\n \"database_name\": db_info.get(\"database_name\", \"Unknown\"),\n \"database_dialect\": dialect,\n \"description\": ds.get(\"description\", \"\"),\n })\n return result\n # endregion fetch_available_datasources\n# #endregion TranslateJobService\n\n\n# Re-exports for backward compatibility\nfrom .service_bulk_replace import BulkFindReplaceService # noqa: E402, F401\nfrom .service_datasource import ( # noqa: E402, F401\n detect_virtual_columns,\n fetch_datasource_metadata,\n get_datasource_columns,\n get_dialect_from_database,\n)\nfrom .service_inline_correction import InlineCorrectionService # noqa: E402, F401\nfrom .service_utils import _extract_dialect, job_to_response # noqa: E402, F401\n# #endregion TranslateJobService\n"
},
{
"contract_id": "BulkFindReplaceService",
@@ -39043,7 +39153,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region InlineCorrectionService [C:4] [TYPE Class] [SEMANTICS translate, correction, inline, dictionary]\n# @BRIEF Service for inline editing translated values and submitting corrections to dictionaries.\n# @PRE Database session is available.\n# @POST Inline edits applied with optional dictionary submission.\n# @SIDE_EFFECT Modifies TranslationLanguage entries; optionally creates DictionaryEntry rows.\n# @RELATION DEPENDS_ON -> [TranslationLanguage]\n# @RELATION DEPENDS_ON -> [TranslationRecord]\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [_normalize_term]\n\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TranslationLanguage, TranslationRecord\nfrom .[EXT:internal:_utils] import _normalize_term\n\n\nclass InlineCorrectionService:\n \"\"\"Handle inline correction of translated values with optional dictionary submission.\"\"\"\n\n @staticmethod\n def apply_inline_edit(\n db: Session,\n run_id: str,\n record_id: str,\n language_code: str,\n final_value: str,\n submit_to_dictionary: bool = False,\n dictionary_id: str | None = None,\n current_user: str | None = None,\n context_data_override: dict | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict:\n \"\"\"Apply an inline edit to a TranslationLanguage entry.\n\n Updates final_value and user_edit fields. Optionally submits to dictionary.\n Returns the updated TranslationLanguage data as a dict.\n\n Args:\n context_data_override: If provided, overrides auto-captured context data.\n usage_notes: Usage notes for the dictionary entry.\n keep_context: If False, clear context on the dictionary entry.\n \"\"\"\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise ValueError(f\"Language entry '{language_code}' not found for record '{record_id}'\")\n\n record = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.id == record_id,\n TranslationRecord.run_id == run_id,\n )\n .first()\n )\n if not record:\n raise ValueError(f\"Translation record '{record_id}' not found in run '{run_id}'\")\n\n lang_entry.final_value = final_value\n lang_entry.user_edit = final_value\n if lang_entry.status in (\"pending\", \"translated\"):\n lang_entry.status = \"edited\"\n db.flush()\n\n dict_result = None\n if submit_to_dictionary and dictionary_id:\n try:\n dict_result = InlineCorrectionService.submit_correction_to_dict(\n db=db, record_id=record_id, language_code=language_code,\n dictionary_id=dictionary_id, corrected_value=final_value,\n current_user=current_user, context_data_override=context_data_override,\n usage_notes=usage_notes, keep_context=keep_context,\n )\n except Exception as e:\n dict_result = {\"error\": str(e), \"action\": \"failed\"}\n\n db.commit()\n db.refresh(lang_entry)\n\n from ...schemas.translate import TranslationLanguageResponse\n response = TranslationLanguageResponse.model_validate(lang_entry)\n result = response.model_dump()\n if dict_result:\n result[\"dictionary_result\"] = dict_result\n return result\n\n @staticmethod\n def submit_correction_to_dict(\n db: Session,\n record_id: str,\n language_code: str,\n dictionary_id: str,\n corrected_value: str,\n current_user: str | None = None,\n context_data_override: dict | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict:\n \"\"\"Submit a correction from an inline edit to the dictionary.\n\n Fetches the TranslationLanguage entry, auto-captures source text and context,\n and creates/updates a DictionaryEntry.\n\n Args:\n context_data_override: If provided, overrides auto-captured context_data.\n usage_notes: Optional usage notes to store on the dictionary entry.\n keep_context: If False, sets has_context=False and clears context_data.\n \"\"\"\n with belief_scope(\"InlineCorrectionService.submit_correction_to_dict\"):\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise ValueError(f\"Language entry '{language_code}' not found for record '{record_id}'\")\n\n record = (\n db.query(TranslationRecord)\n .filter(TranslationRecord.id == record_id)\n .first()\n )\n if not record:\n raise ValueError(f\"Translation record '{record_id}' not found\")\n\n source_term = record.source_sql or record.source_object_name or \"\"\n if not source_term:\n raise ValueError(\"No source text available for this record\")\n\n source_language = lang_entry.source_language_detected or \"und\"\n target_language = language_code\n\n context_data = {}\n if record.source_data:\n context_data[\"source_data\"] = record.source_data\n if record.source_object_type:\n context_data[\"source_object_type\"] = record.source_object_type\n if record.source_object_name:\n context_data[\"source_object_name\"] = record.source_object_name\n if record.source_object_id:\n context_data[\"source_object_id\"] = record.source_object_id\n\n if context_data_override is not None:\n context_data = context_data_override\n context_source = \"manual\"\n else:\n context_source = \"auto\"\n\n if not keep_context:\n context_data = None\n context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n result = {\"action\": \"created\", \"entry_id\": None, \"conflict\": None, \"message\": None}\n\n if existing:\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_value,\n \"action\": \"keep_existing\",\n }\n result[\"message\"] = (\n f\"Existing entry found: '{existing.target_term}' \"\n f\"for source '{source_term}' ({source_language} → {target_language})\"\n )\n logger.reason(\"Correction conflict detected\", result)\n return result\n\n entry = DictionaryEntry(\n dictionary_id=dictionary_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=corrected_value.strip(),\n source_language=source_language,\n target_language=target_language,\n context_data=context_data if context_data else None,\n context_notes=None,\n has_context=bool(context_data) and keep_context,\n context_source=context_source,\n usage_notes=usage_notes,\n origin_source_language=source_language,\n origin_run_id=record.run_id,\n origin_row_key=record.id,\n origin_user_id=current_user,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = (\n f\"Entry created for '{source_term}' ({source_language}) → \"\n f\"'{corrected_value}' ({target_language})\"\n )\n logger.reflect(\"Dictionary entry created from correction\", result)\n return result\n# #endregion InlineCorrectionService\n"
+ "body": "# #region InlineCorrectionService [C:4] [TYPE Class] [SEMANTICS translate, correction, inline, dictionary]\n# @BRIEF Service for inline editing translated values and submitting corrections to dictionaries.\n# @PRE Database session is available.\n# @POST Inline edits applied with optional dictionary submission.\n# @SIDE_EFFECT Modifies TranslationLanguage entries; optionally creates DictionaryEntry rows.\n# @RELATION DEPENDS_ON -> [TranslationLanguage]\n# @RELATION DEPENDS_ON -> [TranslationRecord]\n# @RELATION DEPENDS_ON -> [DictionaryEntry]\n# @RELATION DEPENDS_ON -> [_normalize_term]\n\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ...core.logger import belief_scope, logger\nfrom ...models.translate import DictionaryEntry, TranslationLanguage, TranslationRecord\nfrom ._utils import _normalize_term\n\n\nclass InlineCorrectionService:\n \"\"\"Handle inline correction of translated values with optional dictionary submission.\"\"\"\n\n @staticmethod\n def apply_inline_edit(\n db: Session,\n run_id: str,\n record_id: str,\n language_code: str,\n final_value: str,\n submit_to_dictionary: bool = False,\n dictionary_id: str | None = None,\n current_user: str | None = None,\n context_data_override: dict | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict:\n \"\"\"Apply an inline edit to a TranslationLanguage entry.\n\n Updates final_value and user_edit fields. Optionally submits to dictionary.\n Returns the updated TranslationLanguage data as a dict.\n\n Args:\n context_data_override: If provided, overrides auto-captured context data.\n usage_notes: Usage notes for the dictionary entry.\n keep_context: If False, clear context on the dictionary entry.\n \"\"\"\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise ValueError(f\"Language entry '{language_code}' not found for record '{record_id}'\")\n\n record = (\n db.query(TranslationRecord)\n .filter(\n TranslationRecord.id == record_id,\n TranslationRecord.run_id == run_id,\n )\n .first()\n )\n if not record:\n raise ValueError(f\"Translation record '{record_id}' not found in run '{run_id}'\")\n\n lang_entry.final_value = final_value\n lang_entry.user_edit = final_value\n if lang_entry.status in (\"pending\", \"translated\"):\n lang_entry.status = \"edited\"\n db.flush()\n\n dict_result = None\n if submit_to_dictionary and dictionary_id:\n try:\n dict_result = InlineCorrectionService.submit_correction_to_dict(\n db=db, record_id=record_id, language_code=language_code,\n dictionary_id=dictionary_id, corrected_value=final_value,\n current_user=current_user, context_data_override=context_data_override,\n usage_notes=usage_notes, keep_context=keep_context,\n )\n except Exception as e:\n dict_result = {\"error\": str(e), \"action\": \"failed\"}\n\n db.commit()\n db.refresh(lang_entry)\n\n from ...schemas.translate import TranslationLanguageResponse\n response = TranslationLanguageResponse.model_validate(lang_entry)\n result = response.model_dump()\n if dict_result:\n result[\"dictionary_result\"] = dict_result\n return result\n\n @staticmethod\n def submit_correction_to_dict(\n db: Session,\n record_id: str,\n language_code: str,\n dictionary_id: str,\n corrected_value: str,\n current_user: str | None = None,\n context_data_override: dict | None = None,\n usage_notes: str | None = None,\n keep_context: bool = True,\n ) -> dict:\n \"\"\"Submit a correction from an inline edit to the dictionary.\n\n Fetches the TranslationLanguage entry, auto-captures source text and context,\n and creates/updates a DictionaryEntry.\n\n Args:\n context_data_override: If provided, overrides auto-captured context_data.\n usage_notes: Optional usage notes to store on the dictionary entry.\n keep_context: If False, sets has_context=False and clears context_data.\n \"\"\"\n with belief_scope(\"InlineCorrectionService.submit_correction_to_dict\"):\n lang_entry = (\n db.query(TranslationLanguage)\n .filter(\n TranslationLanguage.record_id == record_id,\n TranslationLanguage.language_code == language_code,\n )\n .first()\n )\n if not lang_entry:\n raise ValueError(f\"Language entry '{language_code}' not found for record '{record_id}'\")\n\n record = (\n db.query(TranslationRecord)\n .filter(TranslationRecord.id == record_id)\n .first()\n )\n if not record:\n raise ValueError(f\"Translation record '{record_id}' not found\")\n\n source_term = record.source_sql or record.source_object_name or \"\"\n if not source_term:\n raise ValueError(\"No source text available for this record\")\n\n source_language = lang_entry.source_language_detected or \"und\"\n target_language = language_code\n\n context_data = {}\n if record.source_data:\n context_data[\"source_data\"] = record.source_data\n if record.source_object_type:\n context_data[\"source_object_type\"] = record.source_object_type\n if record.source_object_name:\n context_data[\"source_object_name\"] = record.source_object_name\n if record.source_object_id:\n context_data[\"source_object_id\"] = record.source_object_id\n\n if context_data_override is not None:\n context_data = context_data_override\n context_source = \"manual\"\n else:\n context_source = \"auto\"\n\n if not keep_context:\n context_data = None\n context_source = \"manual\"\n\n normalized = _normalize_term(source_term)\n\n existing = (\n db.query(DictionaryEntry)\n .filter(\n DictionaryEntry.dictionary_id == dictionary_id,\n DictionaryEntry.source_term_normalized == normalized,\n DictionaryEntry.source_language == source_language,\n DictionaryEntry.target_language == target_language,\n )\n .first()\n )\n\n result = {\"action\": \"created\", \"entry_id\": None, \"conflict\": None, \"message\": None}\n\n if existing:\n result[\"action\"] = \"conflict_detected\"\n result[\"conflict\"] = {\n \"source_term\": source_term,\n \"existing_target_term\": existing.target_term,\n \"submitted_target_term\": corrected_value,\n \"action\": \"keep_existing\",\n }\n result[\"message\"] = (\n f\"Existing entry found: '{existing.target_term}' \"\n f\"for source '{source_term}' ({source_language} → {target_language})\"\n )\n logger.reason(\"Correction conflict detected\", result)\n return result\n\n entry = DictionaryEntry(\n dictionary_id=dictionary_id,\n source_term=source_term.strip(),\n source_term_normalized=normalized,\n target_term=corrected_value.strip(),\n source_language=source_language,\n target_language=target_language,\n context_data=context_data if context_data else None,\n context_notes=None,\n has_context=bool(context_data) and keep_context,\n context_source=context_source,\n usage_notes=usage_notes,\n origin_source_language=source_language,\n origin_run_id=record.run_id,\n origin_row_key=record.id,\n origin_user_id=current_user,\n )\n db.add(entry)\n db.flush()\n result[\"entry_id\"] = entry.id\n result[\"message\"] = (\n f\"Entry created for '{source_term}' ({source_language}) → \"\n f\"'{corrected_value}' ({target_language})\"\n )\n logger.reflect(\"Dictionary entry created from correction\", result)\n return result\n# #endregion InlineCorrectionService\n"
},
{
"contract_id": "TargetSchemaValidation",
@@ -39528,4938 +39638,6 @@
"tier_source": "AutoCalculated",
"body": "# #region test_dashboard_health_item_status_accepts_only_whitelisted_values [TYPE Function]\n# @RELATION BINDS_TO -> TestSettingsAndHealthSchemas\n# @BRIEF Verify strict grouped regex only accepts PASS/WARN/FAIL/UNKNOWN exact statuses.\ndef test_dashboard_health_item_status_accepts_only_whitelisted_values():\n valid = DashboardHealthItem(\n dashboard_id=\"dash-1\",\n environment_id=\"env-1\",\n status=\"PASS\",\n last_check=\"2026-03-10T10:00:00\",\n )\n assert valid.status == \"PASS\"\n with pytest.raises(ValidationError):\n DashboardHealthItem(\n dashboard_id=\"dash-1\",\n environment_id=\"env-1\",\n status=\"PASSING\",\n last_check=\"2026-03-10T10:00:00\",\n )\n with pytest.raises(ValidationError):\n DashboardHealthItem(\n dashboard_id=\"dash-1\",\n environment_id=\"env-1\",\n status=\"FAIL \",\n last_check=\"2026-03-10T10:00:00\",\n )\n# #endregion test_dashboard_health_item_status_accepts_only_whitelisted_values\n"
},
- {
- "contract_id": "ExternalStubs",
- "contract_type": "Module",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1,
- "end_line": 774,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Stub contract references for external libraries, frontend stores, Python stdlib,",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region ExternalStubs [C:1] [TYPE Module] [SEMANTICS external,stubs,contracts]\n# @BRIEF Stub contract references for external libraries, frontend stores, Python stdlib,\n# file paths, and other targets that exist outside the GRACE-Poly contract network.\n# @RATIONALE These are placeholder contracts that allow @RELATION edges to resolve.\n# The EXT: prefix categorizes the external target type (Python stdlib, Library,\n# frontend store, file path, method reference, etc.).\n# @REJECTED Leaving unresolved_relation warnings was rejected — every @RELATION edge\n# MUST point to a valid contract ID. These stubs provide the target.\n\n# #region EXT:FastAPI:TestClient [C:1] [TYPE External]\n# @BRIEF External reference: TestClient\n# #endregion EXT:FastAPI:TestClient\n\n# #region EXT:Library:SQLAlchemy.Base [C:1] [TYPE External]\n# @BRIEF External library: SQLAlchemy.Base\n# #endregion EXT:Library:SQLAlchemy.Base\n\n# #region EXT:Library:authlib [C:1] [TYPE External]\n# @BRIEF External library: authlib\n# #endregion EXT:Library:authlib\n\n# #region EXT:Library:fastapi.APIRouter [C:1] [TYPE External]\n# @BRIEF External library: fastapi.APIRouter\n# #endregion EXT:Library:fastapi.APIRouter\n\n# #region EXT:Library:pydantic [C:1] [TYPE External]\n# @BRIEF External library: pydantic\n# #endregion EXT:Library:pydantic\n\n# #region EXT:Library:pytest [C:1] [TYPE External]\n# @BRIEF External library: pytest\n# #endregion EXT:Library:pytest\n\n# #region EXT:Library:sqlalchemy [C:1] [TYPE External]\n# @BRIEF External library: sqlalchemy\n# #endregion EXT:Library:sqlalchemy\n\n# #region EXT:Library:sqlalchemy.orm.Session [C:1] [TYPE External]\n# @BRIEF External library: sqlalchemy.orm.Session\n# #endregion EXT:Library:sqlalchemy.orm.Session\n\n# #region EXT:Library:yaml [C:1] [TYPE External]\n# @BRIEF External library: yaml\n# #endregion EXT:Library:yaml\n\n# #region EXT:Python:Exception [C:1] [TYPE External]\n# @BRIEF Python standard library module: Exception\n# #endregion EXT:Python:Exception\n\n# #region EXT:Python:hashlib [C:1] [TYPE External]\n# @BRIEF Python standard library module: hashlib\n# #endregion EXT:Python:hashlib\n\n# #region EXT:Python:hashlib.sha256 [C:1] [TYPE External]\n# @BRIEF Python standard library module: hashlib.sha256\n# #endregion EXT:Python:hashlib.sha256\n\n# #region EXT:Python:json [C:1] [TYPE External]\n# @BRIEF Python standard library module: json\n# #endregion EXT:Python:json\n\n# #region EXT:Python:secrets [C:1] [TYPE External]\n# @BRIEF Python standard library module: secrets\n# #endregion EXT:Python:secrets\n\n# #region EXT:Python:secrets.token_urlsafe [C:1] [TYPE External]\n# @BRIEF Python standard library module: secrets.token_urlsafe\n# #endregion EXT:Python:secrets.token_urlsafe\n\n# #region EXT:Python:uuid [C:1] [TYPE External]\n# @BRIEF Python standard library module: uuid\n# #endregion EXT:Python:uuid\n\n# #region EXT:build.sh [C:1] [TYPE External]\n# @BRIEF External reference: build.sh\n# #endregion EXT:build.sh\n\n# #region EXT:code:has_permission(\"admin:settings\", \"WRITE\") [C:1] [TYPE External]\n# @BRIEF Code expression: has_permission(\"admin:settings\", \"WRITE\")\n# #endregion EXT:code:has_permission(\"admin:settings\", \"WRITE\")\n\n# #region EXT:code:has_permission(\"maintenance\", \"READ\") [C:1] [TYPE External]\n# @BRIEF Code expression: has_permission(\"maintenance\", \"READ\")\n# #endregion EXT:code:has_permission(\"maintenance\", \"READ\")\n\n# #region EXT:code:has_permission(\"maintenance\", \"WRITE\") [C:1] [TYPE External]\n# @BRIEF Code expression: has_permission(\"maintenance\", \"WRITE\")\n# #endregion EXT:code:has_permission(\"maintenance\", \"WRITE\")\n\n# #region EXT:frontend:AssistantChatPanel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: AssistantChatPanel\n# #endregion EXT:frontend:AssistantChatPanel\n\n# #region EXT:frontend:AssistantFirstMessageIntegrationTest [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: AssistantFirstMessageIntegrationTest\n# #endregion EXT:frontend:AssistantFirstMessageIntegrationTest\n\n# #region EXT:frontend:BranchSelector [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: BranchSelector\n# #endregion EXT:frontend:BranchSelector\n\n# #region EXT:frontend:Breadcrumbs [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: Breadcrumbs\n# #endregion EXT:frontend:Breadcrumbs\n\n# #region EXT:frontend:ConflictResolver [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ConflictResolver\n# #endregion EXT:frontend:ConflictResolver\n\n# #region EXT:frontend:DashboardHub [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: DashboardHub\n# #endregion EXT:frontend:DashboardHub\n\n# #region EXT:frontend:DashboardValidationService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: DashboardValidationService\n# #endregion EXT:frontend:DashboardValidationService\n\n# #region EXT:frontend:DeploymentModal [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: DeploymentModal\n# #endregion EXT:frontend:DeploymentModal\n\n# #region EXT:frontend:EnvironmentsTab [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: EnvironmentsTab\n# #endregion EXT:frontend:EnvironmentsTab\n\n# #region EXT:frontend:GitApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: GitApi\n# #endregion EXT:frontend:GitApi\n\n# #region EXT:frontend:GitSettingsPage [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: GitSettingsPage\n# #endregion EXT:frontend:GitSettingsPage\n\n# #region EXT:frontend:LocaleEn [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: LocaleEn\n# #endregion EXT:frontend:LocaleEn\n\n# #region EXT:frontend:LocaleRu [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: LocaleRu\n# #endregion EXT:frontend:LocaleRu\n\n# #region EXT:frontend:MaintenanceEventsTable [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: MaintenanceEventsTable\n# #endregion EXT:frontend:MaintenanceEventsTable\n\n# #region EXT:frontend:MaintenanceServiceModule [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: MaintenanceServiceModule\n# #endregion EXT:frontend:MaintenanceServiceModule\n\n# #region EXT:frontend:MaintenanceSettingsPanel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: MaintenanceSettingsPanel\n# #endregion EXT:frontend:MaintenanceSettingsPanel\n\n# #region EXT:frontend:PluginLoaderCore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: PluginLoaderCore\n# #endregion EXT:frontend:PluginLoaderCore\n\n# #region EXT:frontend:ProfilePageBindAccountFlowTests [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ProfilePageBindAccountFlowTests\n# #endregion EXT:frontend:ProfilePageBindAccountFlowTests\n\n# #region EXT:frontend:ProtectedRoute [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ProtectedRoute\n# #endregion EXT:frontend:ProtectedRoute\n\n# #region EXT:frontend:ProviderConfigIntegrationTest [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ProviderConfigIntegrationTest\n# #endregion EXT:frontend:ProviderConfigIntegrationTest\n\n# #region EXT:frontend:ReportCard [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportCard\n# #endregion EXT:frontend:ReportCard\n\n# #region EXT:frontend:ReportDetailPanel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportDetailPanel\n# #endregion EXT:frontend:ReportDetailPanel\n\n# #region EXT:frontend:ReportModel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportModel\n# #endregion EXT:frontend:ReportModel\n\n# #region EXT:frontend:ReportsList [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportsList\n# #endregion EXT:frontend:ReportsList\n\n# #region EXT:frontend:RepositoryDashboardGrid [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: RepositoryDashboardGrid\n# #endregion EXT:frontend:RepositoryDashboardGrid\n\n# #region EXT:frontend:RoutePages [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: RoutePages\n# #endregion EXT:frontend:RoutePages\n\n# #region EXT:frontend:SessionRepositoryTests [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: SessionRepositoryTests\n# #endregion EXT:frontend:SessionRepositoryTests\n\n# #region EXT:frontend:SettingsUtils [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: SettingsUtils\n# #endregion EXT:frontend:SettingsUtils\n\n# #region EXT:frontend:SidebarNavigation [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: SidebarNavigation\n# #endregion EXT:frontend:SidebarNavigation\n\n# #region EXT:frontend:TaskModel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskModel\n# #endregion EXT:frontend:TaskModel\n\n# #region EXT:frontend:TaskPersistenceService.delete_tasks [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskPersistenceService.delete_tasks\n# #endregion EXT:frontend:TaskPersistenceService.delete_tasks\n\n# #region EXT:frontend:TaskPersistenceService.load_tasks [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskPersistenceService.load_tasks\n# #endregion EXT:frontend:TaskPersistenceService.load_tasks\n\n# #region EXT:frontend:TaskRunner [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskRunner\n# #endregion EXT:frontend:TaskRunner\n\n# #region EXT:frontend:TasksModule [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TasksModule\n# #endregion EXT:frontend:TasksModule\n\n# #region EXT:frontend:TestPolicyResolutionService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TestPolicyResolutionService\n# #endregion EXT:frontend:TestPolicyResolutionService\n\n# #region EXT:frontend:TestResourceService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TestResourceService\n# #endregion EXT:frontend:TestResourceService\n\n# #region EXT:frontend:TestScreenshotService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TestScreenshotService\n# #endregion EXT:frontend:TestScreenshotService\n\n# #region EXT:frontend:TopNavbar [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TopNavbar\n# #endregion EXT:frontend:TopNavbar\n\n# #region EXT:frontend:TypeProfiles [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TypeProfiles\n# #endregion EXT:frontend:TypeProfiles\n\n# #region EXT:frontend:activity [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: activity\n# #endregion EXT:frontend:activity\n\n# #region EXT:frontend:activityStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: activityStore\n# #endregion EXT:frontend:activityStore\n\n# #region EXT:frontend:addToast [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: addToast\n# #endregion EXT:frontend:addToast\n\n# #region EXT:frontend:api [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: api\n# #endregion EXT:frontend:api\n\n# #region EXT:frontend:api.client [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: api.client\n# #endregion EXT:frontend:api.client\n\n# #region EXT:frontend:api_module [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: api_module\n# #endregion EXT:frontend:api_module\n\n# #region EXT:frontend:assistantChat [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: assistantChat\n# #endregion EXT:frontend:assistantChat\n\n# #region EXT:frontend:assistantChatStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: assistantChatStore\n# #endregion EXT:frontend:assistantChatStore\n\n# #region EXT:frontend:authStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: authStore\n# #endregion EXT:frontend:authStore\n\n# #region EXT:frontend:checkTargetTableSchema [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: checkTargetTableSchema\n# #endregion EXT:frontend:checkTargetTableSchema\n\n# #region EXT:frontend:core_logger [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: core_logger\n# #endregion EXT:frontend:core_logger\n\n# #region EXT:frontend:datasetReviewSession [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: datasetReviewSession\n# #endregion EXT:frontend:datasetReviewSession\n\n# #region EXT:frontend:datasetReviewSessionStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: datasetReviewSessionStore\n# #endregion EXT:frontend:datasetReviewSessionStore\n\n# #region EXT:frontend:dictionaryApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: dictionaryApi\n# #endregion EXT:frontend:dictionaryApi\n\n# #region EXT:frontend:environmentContext [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: environmentContext\n# #endregion EXT:frontend:environmentContext\n\n# #region EXT:frontend:environmentContextStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: environmentContextStore\n# #endregion EXT:frontend:environmentContextStore\n\n# #region EXT:frontend:fetchApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: fetchApi\n# #endregion EXT:frontend:fetchApi\n\n# #region EXT:frontend:fetchDatabases [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: fetchDatabases\n# #endregion EXT:frontend:fetchDatabases\n\n# #region EXT:frontend:fetchEnvironments [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: fetchEnvironments\n# #endregion EXT:frontend:fetchEnvironments\n\n# #region EXT:frontend:gitService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: gitService\n# #endregion EXT:frontend:gitService\n\n# #region EXT:frontend:goto [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: goto\n# #endregion EXT:frontend:goto\n\n# #region EXT:frontend:handleUpdate [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: handleUpdate\n# #endregion EXT:frontend:handleUpdate\n\n# #region EXT:frontend:healthStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: healthStore\n# #endregion EXT:frontend:healthStore\n\n# #region EXT:frontend:i18n [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: i18n\n# #endregion EXT:frontend:i18n\n\n# #region EXT:frontend:i18n.profile.lookup_error [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: i18n.profile.lookup_error\n# #endregion EXT:frontend:i18n.profile.lookup_error\n\n# #region EXT:frontend:i18n.t [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: i18n.t\n# #endregion EXT:frontend:i18n.t\n\n# #region EXT:frontend:isProductionContextStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: isProductionContextStore\n# #endregion EXT:frontend:isProductionContextStore\n\n# #region EXT:frontend:migration.mappings.route [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: migration.mappings.route\n# #endregion EXT:frontend:migration.mappings.route\n\n# #region EXT:frontend:models.translate [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: models.translate\n# #endregion EXT:frontend:models.translate\n\n# #region EXT:frontend:normalize_report [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: normalize_report\n# #endregion EXT:frontend:normalize_report\n\n# #region EXT:frontend:orchestrator_lang_stats [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: orchestrator_lang_stats\n# #endregion EXT:frontend:orchestrator_lang_stats\n\n# #region EXT:frontend:policy_resolution_service [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: policy_resolution_service\n# #endregion EXT:frontend:policy_resolution_service\n\n# #region EXT:frontend:repository [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: repository\n# #endregion EXT:frontend:repository\n\n# #region EXT:frontend:requestApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: requestApi\n# #endregion EXT:frontend:requestApi\n\n# #region EXT:frontend:selectedEnvironmentStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: selectedEnvironmentStore\n# #endregion EXT:frontend:selectedEnvironmentStore\n\n# #region EXT:frontend:setupTests [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: setupTests\n# #endregion EXT:frontend:setupTests\n\n# #region EXT:frontend:sidebar [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: sidebar\n# #endregion EXT:frontend:sidebar\n\n# #region EXT:frontend:sidebarStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: sidebarStore\n# #endregion EXT:frontend:sidebarStore\n\n# #region EXT:frontend:stores [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: stores\n# #endregion EXT:frontend:stores\n\n# #region EXT:frontend:taskDrawer [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: taskDrawer\n# #endregion EXT:frontend:taskDrawer\n\n# #region EXT:frontend:taskDrawerStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: taskDrawerStore\n# #endregion EXT:frontend:taskDrawerStore\n\n# #region EXT:frontend:taskService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: taskService\n# #endregion EXT:frontend:taskService\n\n# #region EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: test_dashboard_validation_plugin_persists_task_and_environment_ids\n# #endregion EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids\n\n# #region EXT:frontend:test_llm_plugin_persistence [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: test_llm_plugin_persistence\n# #endregion EXT:frontend:test_llm_plugin_persistence\n\n# #region EXT:frontend:test_llm_provider [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: test_llm_provider\n# #endregion EXT:frontend:test_llm_provider\n\n# #region EXT:frontend:translationRunStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: translationRunStore\n# #endregion EXT:frontend:translationRunStore\n\n# #region EXT:internal:ASSISTANT_AUDIT [C:1] [TYPE External]\n# @BRIEF Internal module reference: ASSISTANT_AUDIT\n# #endregion EXT:internal:ASSISTANT_AUDIT\n\n# #region EXT:internal:All C4+ service and route modules [C:1] [TYPE External]\n# @BRIEF Internal module reference: All C4+ service and route modules\n# #endregion EXT:internal:All C4+ service and route modules\n\n# #region EXT:internal:All application modules [C:1] [TYPE External]\n# @BRIEF Internal module reference: All application modules\n# #endregion EXT:internal:All application modules\n\n# #region EXT:internal:CONVERSATIONS [C:1] [TYPE External]\n# @BRIEF Internal module reference: CONVERSATIONS\n# #endregion EXT:internal:CONVERSATIONS\n\n# #region EXT:internal:ConnectionContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: ConnectionContracts\n# #endregion EXT:internal:ConnectionContracts\n\n# #region EXT:internal:CoreContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: CoreContracts\n# #endregion EXT:internal:CoreContracts\n\n# #region EXT:internal:CotJsonFormat [C:1] [TYPE External]\n# @BRIEF Internal module reference: CotJsonFormat\n# #endregion EXT:internal:CotJsonFormat\n\n# #region EXT:internal:MappingBase [C:1] [TYPE External]\n# @BRIEF Internal module reference: MappingBase\n# #endregion EXT:internal:MappingBase\n\n# #region EXT:internal:MappingModels:Base [C:1] [TYPE External]\n# @BRIEF Internal module reference: MappingModels:Base\n# #endregion EXT:internal:MappingModels:Base\n\n# #region EXT:internal:NavigationContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: NavigationContracts\n# #endregion EXT:internal:NavigationContracts\n\n# #region EXT:internal:PageContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: PageContracts\n# #endregion EXT:internal:PageContracts\n\n# #region EXT:internal:Permissions [C:1] [TYPE External]\n# @BRIEF Internal module reference: Permissions\n# #endregion EXT:internal:Permissions\n\n# #region EXT:method:AsyncAPIClient._handle_http_error [C:1] [TYPE External]\n# @BRIEF Method reference: AsyncAPIClient._handle_http_error\n# #endregion EXT:method:AsyncAPIClient._handle_http_error\n\n# #region EXT:method:AsyncAPIClient.request [C:1] [TYPE External]\n# @BRIEF Method reference: AsyncAPIClient.request\n# #endregion EXT:method:AsyncAPIClient.request\n\n# #region EXT:method:BackupPlugin:execute [C:1] [TYPE External]\n# @BRIEF Method reference: BackupPlugin:execute\n# #endregion EXT:method:BackupPlugin:execute\n\n# #region EXT:method:GlobalSettings.app_timezone [C:1] [TYPE External]\n# @BRIEF Method reference: GlobalSettings.app_timezone\n# #endregion EXT:method:GlobalSettings.app_timezone\n\n# #region EXT:method:MappingService:get_suggestions [C:1] [TYPE External]\n# @BRIEF Method reference: MappingService:get_suggestions\n# #endregion EXT:method:MappingService:get_suggestions\n\n# #region EXT:method:MigrationPlugin:execute [C:1] [TYPE External]\n# @BRIEF Method reference: MigrationPlugin:execute\n# #endregion EXT:method:MigrationPlugin:execute\n\n# #region EXT:method:SessionEventLogger.log_event [C:1] [TYPE External]\n# @BRIEF Method reference: SessionEventLogger.log_event\n# #endregion EXT:method:SessionEventLogger.log_event\n\n# #region EXT:method:SupersetClient.compile_dataset_preview [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.compile_dataset_preview\n# #endregion EXT:method:SupersetClient.compile_dataset_preview\n\n# #region EXT:method:SupersetClient.get_dashboard [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dashboard\n# #endregion EXT:method:SupersetClient.get_dashboard\n\n# #region EXT:method:SupersetClient.get_dashboard_detail [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dashboard_detail\n# #endregion EXT:method:SupersetClient.get_dashboard_detail\n\n# #region EXT:method:SupersetClient.get_dashboards_summary [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dashboards_summary\n# #endregion EXT:method:SupersetClient.get_dashboards_summary\n\n# #region EXT:method:SupersetClient.get_dataset [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dataset\n# #endregion EXT:method:SupersetClient.get_dataset\n\n# #region EXT:method:SupersetClient.update_dataset [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.update_dataset\n# #endregion EXT:method:SupersetClient.update_dataset\n\n# #region EXT:method:SupersetContextExtractor.parse_superset_link [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetContextExtractor.parse_superset_link\n# #endregion EXT:method:SupersetContextExtractor.parse_superset_link\n\n# #region EXT:method:TASK_TYPE_PLUGIN_MAP [C:1] [TYPE External]\n# @BRIEF Method reference: TASK_TYPE_PLUGIN_MAP\n# #endregion EXT:method:TASK_TYPE_PLUGIN_MAP\n\n# #region EXT:method:TaskLogPersistenceService.add_logs [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.add_logs\n# #endregion EXT:method:TaskLogPersistenceService.add_logs\n\n# #region EXT:method:TaskLogPersistenceService.delete_logs_for_tasks [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.delete_logs_for_tasks\n# #endregion EXT:method:TaskLogPersistenceService.delete_logs_for_tasks\n\n# #region EXT:method:TaskLogPersistenceService.get_log_stats [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.get_log_stats\n# #endregion EXT:method:TaskLogPersistenceService.get_log_stats\n\n# #region EXT:method:TaskLogPersistenceService.get_logs [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.get_logs\n# #endregion EXT:method:TaskLogPersistenceService.get_logs\n\n# #region EXT:method:TaskLogPersistenceService.get_sources [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.get_sources\n# #endregion EXT:method:TaskLogPersistenceService.get_sources\n\n# #region EXT:method:TaskManager.create_task [C:1] [TYPE External]\n# @BRIEF Method reference: TaskManager.create_task\n# #endregion EXT:method:TaskManager.create_task\n\n# #region EXT:method:TranslationExecutor._auto_size_batches [C:1] [TYPE External]\n# @BRIEF Method reference: TranslationExecutor._auto_size_batches\n# #endregion EXT:method:TranslationExecutor._auto_size_batches\n\n# #region EXT:method:_build_body [C:1] [TYPE External]\n# @BRIEF Method reference: _build_body\n# #endregion EXT:method:_build_body\n\n# #region EXT:method:_extract_resource_name_from_task [C:1] [TYPE External]\n# @BRIEF Method reference: _extract_resource_name_from_task\n# #endregion EXT:method:_extract_resource_name_from_task\n\n# #region EXT:method:_extract_resource_type_from_task [C:1] [TYPE External]\n# @BRIEF Method reference: _extract_resource_type_from_task\n# #endregion EXT:method:_extract_resource_type_from_task\n\n# #region EXT:method:_find_dashboard_owners [C:1] [TYPE External]\n# @BRIEF Method reference: _find_dashboard_owners\n# #endregion EXT:method:_find_dashboard_owners\n\n# #region EXT:method:_get_git_status_for_dashboard [C:1] [TYPE External]\n# @BRIEF Method reference: _get_git_status_for_dashboard\n# #endregion EXT:method:_get_git_status_for_dashboard\n\n# #region EXT:method:_get_last_llm_task_for_dashboard [C:1] [TYPE External]\n# @BRIEF Method reference: _get_last_llm_task_for_dashboard\n# #endregion EXT:method:_get_last_llm_task_for_dashboard\n\n# #region EXT:method:_get_last_task_for_resource [C:1] [TYPE External]\n# @BRIEF Method reference: _get_last_task_for_resource\n# #endregion EXT:method:_get_last_task_for_resource\n\n# #region EXT:method:_initialize_providers [C:1] [TYPE External]\n# @BRIEF Method reference: _initialize_providers\n# #endregion EXT:method:_initialize_providers\n\n# #region EXT:method:_llm_http [C:1] [TYPE External]\n# @BRIEF Method reference: _llm_http\n# #endregion EXT:method:_llm_http\n\n# #region EXT:method:_normalize_datetime_for_compare [C:1] [TYPE External]\n# @BRIEF Method reference: _normalize_datetime_for_compare\n# #endregion EXT:method:_normalize_datetime_for_compare\n\n# #region EXT:method:_normalize_task_status [C:1] [TYPE External]\n# @BRIEF Method reference: _normalize_task_status\n# #endregion EXT:method:_normalize_task_status\n\n# #region EXT:method:_normalize_validation_status [C:1] [TYPE External]\n# @BRIEF Method reference: _normalize_validation_status\n# #endregion EXT:method:_normalize_validation_status\n\n# #region EXT:method:_prime_dashboard_meta_cache [C:1] [TYPE External]\n# @BRIEF Method reference: _prime_dashboard_meta_cache\n# #endregion EXT:method:_prime_dashboard_meta_cache\n\n# #region EXT:method:_resolve_dashboard_meta [C:1] [TYPE External]\n# @BRIEF Method reference: _resolve_dashboard_meta\n# #endregion EXT:method:_resolve_dashboard_meta\n\n# #region EXT:method:_resolve_targets [C:1] [TYPE External]\n# @BRIEF Method reference: _resolve_targets\n# #endregion EXT:method:_resolve_targets\n\n# #region EXT:method:_should_notify [C:1] [TYPE External]\n# @BRIEF Method reference: _should_notify\n# #endregion EXT:method:_should_notify\n\n# #region EXT:method:decrypt [C:1] [TYPE External]\n# @BRIEF Method reference: decrypt\n# #endregion EXT:method:decrypt\n\n# #region EXT:method:encrypt [C:1] [TYPE External]\n# @BRIEF Method reference: encrypt\n# #endregion EXT:method:encrypt\n\n# #region EXT:method:get_activity_summary [C:1] [TYPE External]\n# @BRIEF Method reference: get_activity_summary\n# #endregion EXT:method:get_activity_summary\n\n# #region EXT:method:get_dashboards_with_status [C:1] [TYPE External]\n# @BRIEF Method reference: get_dashboards_with_status\n# #endregion EXT:method:get_dashboards_with_status\n\n# #region EXT:method:get_datasets_with_status [C:1] [TYPE External]\n# @BRIEF Method reference: get_datasets_with_status\n# #endregion EXT:method:get_datasets_with_status\n\n# #region EXT:method:get_repo [C:1] [TYPE External]\n# @BRIEF Method reference: get_repo\n# #endregion EXT:method:get_repo\n\n# #region EXT:method:schemas.translate.TargetSchemaValidationRequest [C:1] [TYPE External]\n# @BRIEF Method reference: schemas.translate.TargetSchemaValidationRequest\n# #endregion EXT:method:schemas.translate.TargetSchemaValidationRequest\n\n# #region EXT:method:schemas.translate.TargetSchemaValidationResponse [C:1] [TYPE External]\n# @BRIEF Method reference: schemas.translate.TargetSchemaValidationResponse\n# #endregion EXT:method:schemas.translate.TargetSchemaValidationResponse\n\n# #region EXT:method:self.network.request [C:1] [TYPE External]\n# @BRIEF Method reference: self.network.request\n# #endregion EXT:method:self.network.request\n\n# #region EXT:module:TargetName [C:1] [TYPE External]\n# @BRIEF External reference: TargetName\n# #endregion EXT:module:TargetName\n\n# #region EXT:path:EnvSelector.svelte [C:1] [TYPE External]\n# @BRIEF File path: EnvSelector.svelte\n# #endregion EXT:path:EnvSelector.svelte\n\n# #region EXT:path:MappingTable.svelte [C:1] [TYPE External]\n# @BRIEF File path: MappingTable.svelte\n# #endregion EXT:path:MappingTable.svelte\n\n# #region EXT:path:backend/requirements.txt [C:1] [TYPE External]\n# @BRIEF File path: backend/requirements.txt\n# #endregion EXT:path:backend/requirements.txt\n\n# #region EXT:path:docker/backend.entrypoint.sh [C:1] [TYPE External]\n# @BRIEF File path: docker/backend.entrypoint.sh\n# #endregion EXT:path:docker/backend.entrypoint.sh\n\n# #region EXT:path:docker/frontend.entrypoint.sh [C:1] [TYPE External]\n# @BRIEF File path: docker/frontend.entrypoint.sh\n# #endregion EXT:path:docker/frontend.entrypoint.sh\n\n# #region EXT:path:docker/nginx.conf [C:1] [TYPE External]\n# @BRIEF File path: docker/nginx.conf\n# #endregion EXT:path:docker/nginx.conf\n\n# #region EXT:path:docker/nginx.ssl.conf [C:1] [TYPE External]\n# @BRIEF File path: docker/nginx.ssl.conf\n# #endregion EXT:path:docker/nginx.ssl.conf\n\n# #region EXT:path:frontend/package.json [C:1] [TYPE External]\n# @BRIEF File path: frontend/package.json\n# #endregion EXT:path:frontend/package.json\n\n# #region EXT:path:frontend/src/components/EnvSelector.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/EnvSelector.svelte\n# #endregion EXT:path:frontend/src/components/EnvSelector.svelte\n\n# #region EXT:path:frontend/src/components/MappingTable.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/MappingTable.svelte\n# #endregion EXT:path:frontend/src/components/MappingTable.svelte\n\n# #region EXT:path:frontend/src/components/PasswordPrompt.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/PasswordPrompt.svelte\n# #endregion EXT:path:frontend/src/components/PasswordPrompt.svelte\n\n# #region EXT:path:frontend/src/components/TaskHistory.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/TaskHistory.svelte\n# #endregion EXT:path:frontend/src/components/TaskHistory.svelte\n\n# #region EXT:path:frontend/src/lib/api.js [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/lib/api.js\n# #endregion EXT:path:frontend/src/lib/api.js\n\n# #region EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES [C:1] [TYPE External]\n# @BRIEF External reference: SUPPORTED_DENSITIES\n# #endregion EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES\n\n# #region EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES [C:1] [TYPE External]\n# @BRIEF External reference: SUPPORTED_START_PAGES\n# #endregion EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES\n\n# #region EXT:requests [C:1] [TYPE External]\n# @BRIEF External reference: requests\n# #endregion EXT:requests\n\n# #region EXT:spec:BulkReplaceModal:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: BulkReplaceModal:Component\n# #endregion EXT:spec:BulkReplaceModal:Component\n\n# #region EXT:spec:CorrectionCell:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: CorrectionCell:Component\n# #endregion EXT:spec:CorrectionCell:Component\n\n# #region EXT:spec:StatsBar:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: StatsBar:Component\n# #endregion EXT:spec:StatsBar:Component\n\n# #region EXT:spec:TargetSchemaHint:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: TargetSchemaHint:Component\n# #endregion EXT:spec:TargetSchemaHint:Component\n\n# #region EXT:spec:TranslationPreview:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: TranslationPreview:Component\n# #endregion EXT:spec:TranslationPreview:Component\n\n# #region EXT:ss-tools:log_security_event [C:1] [TYPE External]\n# @BRIEF External reference: log_security_event\n# #endregion EXT:ss-tools:log_security_event\n\n# #region EXT:sveltekit:$app/environment [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $app/environment\n# #endregion EXT:sveltekit:$app/environment\n\n# #region EXT:sveltekit:$app/navigation [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $app/navigation\n# #endregion EXT:sveltekit:$app/navigation\n\n# #region EXT:sveltekit:$app/stores [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $app/stores\n# #endregion EXT:sveltekit:$app/stores\n\n# #region EXT:sveltekit:$env/static/public [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $env/static/public\n# #endregion EXT:sveltekit:$env/static/public\n\n# #endregion ExternalStubs\n"
- },
- {
- "contract_id": "EXT:FastAPI:TestClient",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 10,
- "end_line": 12,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: TestClient",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:FastAPI:TestClient [C:1] [TYPE External]\n# @BRIEF External reference: TestClient\n# #endregion EXT:FastAPI:TestClient\n"
- },
- {
- "contract_id": "EXT:Library:SQLAlchemy.Base",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 14,
- "end_line": 16,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: SQLAlchemy.Base",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:SQLAlchemy.Base [C:1] [TYPE External]\n# @BRIEF External library: SQLAlchemy.Base\n# #endregion EXT:Library:SQLAlchemy.Base\n"
- },
- {
- "contract_id": "EXT:Library:authlib",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 18,
- "end_line": 20,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: authlib",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:authlib [C:1] [TYPE External]\n# @BRIEF External library: authlib\n# #endregion EXT:Library:authlib\n"
- },
- {
- "contract_id": "EXT:Library:fastapi.APIRouter",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 22,
- "end_line": 24,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: fastapi.APIRouter",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:fastapi.APIRouter [C:1] [TYPE External]\n# @BRIEF External library: fastapi.APIRouter\n# #endregion EXT:Library:fastapi.APIRouter\n"
- },
- {
- "contract_id": "EXT:Library:pydantic",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 26,
- "end_line": 28,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: pydantic",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:pydantic [C:1] [TYPE External]\n# @BRIEF External library: pydantic\n# #endregion EXT:Library:pydantic\n"
- },
- {
- "contract_id": "EXT:Library:pytest",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 30,
- "end_line": 32,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: pytest",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:pytest [C:1] [TYPE External]\n# @BRIEF External library: pytest\n# #endregion EXT:Library:pytest\n"
- },
- {
- "contract_id": "EXT:Library:sqlalchemy",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 34,
- "end_line": 36,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: sqlalchemy",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:sqlalchemy [C:1] [TYPE External]\n# @BRIEF External library: sqlalchemy\n# #endregion EXT:Library:sqlalchemy\n"
- },
- {
- "contract_id": "EXT:Library:sqlalchemy.orm.Session",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 38,
- "end_line": 40,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: sqlalchemy.orm.Session",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:sqlalchemy.orm.Session [C:1] [TYPE External]\n# @BRIEF External library: sqlalchemy.orm.Session\n# #endregion EXT:Library:sqlalchemy.orm.Session\n"
- },
- {
- "contract_id": "EXT:Library:yaml",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 42,
- "end_line": 44,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: yaml",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:yaml [C:1] [TYPE External]\n# @BRIEF External library: yaml\n# #endregion EXT:Library:yaml\n"
- },
- {
- "contract_id": "EXT:Python:Exception",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 46,
- "end_line": 48,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: Exception",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:Exception [C:1] [TYPE External]\n# @BRIEF Python standard library module: Exception\n# #endregion EXT:Python:Exception\n"
- },
- {
- "contract_id": "EXT:Python:hashlib",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 50,
- "end_line": 52,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: hashlib",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:hashlib [C:1] [TYPE External]\n# @BRIEF Python standard library module: hashlib\n# #endregion EXT:Python:hashlib\n"
- },
- {
- "contract_id": "EXT:Python:hashlib.sha256",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 54,
- "end_line": 56,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: hashlib.sha256",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:hashlib.sha256 [C:1] [TYPE External]\n# @BRIEF Python standard library module: hashlib.sha256\n# #endregion EXT:Python:hashlib.sha256\n"
- },
- {
- "contract_id": "EXT:Python:json",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 58,
- "end_line": 60,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: json",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:json [C:1] [TYPE External]\n# @BRIEF Python standard library module: json\n# #endregion EXT:Python:json\n"
- },
- {
- "contract_id": "EXT:Python:secrets",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 62,
- "end_line": 64,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: secrets",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:secrets [C:1] [TYPE External]\n# @BRIEF Python standard library module: secrets\n# #endregion EXT:Python:secrets\n"
- },
- {
- "contract_id": "EXT:Python:secrets.token_urlsafe",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 66,
- "end_line": 68,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: secrets.token_urlsafe",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:secrets.token_urlsafe [C:1] [TYPE External]\n# @BRIEF Python standard library module: secrets.token_urlsafe\n# #endregion EXT:Python:secrets.token_urlsafe\n"
- },
- {
- "contract_id": "EXT:Python:uuid",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 70,
- "end_line": 72,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library module: uuid",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:uuid [C:1] [TYPE External]\n# @BRIEF Python standard library module: uuid\n# #endregion EXT:Python:uuid\n"
- },
- {
- "contract_id": "EXT:build.sh",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 74,
- "end_line": 76,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: build.sh",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:build.sh [C:1] [TYPE External]\n# @BRIEF External reference: build.sh\n# #endregion EXT:build.sh\n"
- },
- {
- "contract_id": "EXT:frontend:AssistantChatPanel",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 90,
- "end_line": 92,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: AssistantChatPanel",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:AssistantChatPanel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: AssistantChatPanel\n# #endregion EXT:frontend:AssistantChatPanel\n"
- },
- {
- "contract_id": "EXT:frontend:AssistantFirstMessageIntegrationTest",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 94,
- "end_line": 96,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: AssistantFirstMessageIntegrationTest",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:AssistantFirstMessageIntegrationTest [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: AssistantFirstMessageIntegrationTest\n# #endregion EXT:frontend:AssistantFirstMessageIntegrationTest\n"
- },
- {
- "contract_id": "EXT:frontend:BranchSelector",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 98,
- "end_line": 100,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: BranchSelector",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:BranchSelector [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: BranchSelector\n# #endregion EXT:frontend:BranchSelector\n"
- },
- {
- "contract_id": "EXT:frontend:Breadcrumbs",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 102,
- "end_line": 104,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: Breadcrumbs",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:Breadcrumbs [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: Breadcrumbs\n# #endregion EXT:frontend:Breadcrumbs\n"
- },
- {
- "contract_id": "EXT:frontend:ConflictResolver",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 106,
- "end_line": 108,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ConflictResolver",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ConflictResolver [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ConflictResolver\n# #endregion EXT:frontend:ConflictResolver\n"
- },
- {
- "contract_id": "EXT:frontend:DashboardHub",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 110,
- "end_line": 112,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: DashboardHub",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DashboardHub [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: DashboardHub\n# #endregion EXT:frontend:DashboardHub\n"
- },
- {
- "contract_id": "EXT:frontend:DashboardValidationService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 114,
- "end_line": 116,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: DashboardValidationService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DashboardValidationService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: DashboardValidationService\n# #endregion EXT:frontend:DashboardValidationService\n"
- },
- {
- "contract_id": "EXT:frontend:DeploymentModal",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 118,
- "end_line": 120,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: DeploymentModal",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DeploymentModal [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: DeploymentModal\n# #endregion EXT:frontend:DeploymentModal\n"
- },
- {
- "contract_id": "EXT:frontend:EnvironmentsTab",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 122,
- "end_line": 124,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: EnvironmentsTab",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:EnvironmentsTab [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: EnvironmentsTab\n# #endregion EXT:frontend:EnvironmentsTab\n"
- },
- {
- "contract_id": "EXT:frontend:GitApi",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 126,
- "end_line": 128,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: GitApi",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:GitApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: GitApi\n# #endregion EXT:frontend:GitApi\n"
- },
- {
- "contract_id": "EXT:frontend:GitSettingsPage",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 130,
- "end_line": 132,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: GitSettingsPage",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:GitSettingsPage [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: GitSettingsPage\n# #endregion EXT:frontend:GitSettingsPage\n"
- },
- {
- "contract_id": "EXT:frontend:LocaleEn",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 134,
- "end_line": 136,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: LocaleEn",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:LocaleEn [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: LocaleEn\n# #endregion EXT:frontend:LocaleEn\n"
- },
- {
- "contract_id": "EXT:frontend:LocaleRu",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 138,
- "end_line": 140,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: LocaleRu",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:LocaleRu [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: LocaleRu\n# #endregion EXT:frontend:LocaleRu\n"
- },
- {
- "contract_id": "EXT:frontend:MaintenanceEventsTable",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 142,
- "end_line": 144,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: MaintenanceEventsTable",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:MaintenanceEventsTable [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: MaintenanceEventsTable\n# #endregion EXT:frontend:MaintenanceEventsTable\n"
- },
- {
- "contract_id": "EXT:frontend:MaintenanceServiceModule",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 146,
- "end_line": 148,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: MaintenanceServiceModule",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:MaintenanceServiceModule [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: MaintenanceServiceModule\n# #endregion EXT:frontend:MaintenanceServiceModule\n"
- },
- {
- "contract_id": "EXT:frontend:MaintenanceSettingsPanel",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 150,
- "end_line": 152,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: MaintenanceSettingsPanel",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:MaintenanceSettingsPanel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: MaintenanceSettingsPanel\n# #endregion EXT:frontend:MaintenanceSettingsPanel\n"
- },
- {
- "contract_id": "EXT:frontend:PluginLoaderCore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 154,
- "end_line": 156,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: PluginLoaderCore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:PluginLoaderCore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: PluginLoaderCore\n# #endregion EXT:frontend:PluginLoaderCore\n"
- },
- {
- "contract_id": "EXT:frontend:ProfilePageBindAccountFlowTests",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 158,
- "end_line": 160,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ProfilePageBindAccountFlowTests",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ProfilePageBindAccountFlowTests [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ProfilePageBindAccountFlowTests\n# #endregion EXT:frontend:ProfilePageBindAccountFlowTests\n"
- },
- {
- "contract_id": "EXT:frontend:ProtectedRoute",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 162,
- "end_line": 164,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ProtectedRoute",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ProtectedRoute [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ProtectedRoute\n# #endregion EXT:frontend:ProtectedRoute\n"
- },
- {
- "contract_id": "EXT:frontend:ProviderConfigIntegrationTest",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 166,
- "end_line": 168,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ProviderConfigIntegrationTest",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ProviderConfigIntegrationTest [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ProviderConfigIntegrationTest\n# #endregion EXT:frontend:ProviderConfigIntegrationTest\n"
- },
- {
- "contract_id": "EXT:frontend:ReportCard",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 170,
- "end_line": 172,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ReportCard",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ReportCard [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportCard\n# #endregion EXT:frontend:ReportCard\n"
- },
- {
- "contract_id": "EXT:frontend:ReportDetailPanel",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 174,
- "end_line": 176,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ReportDetailPanel",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ReportDetailPanel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportDetailPanel\n# #endregion EXT:frontend:ReportDetailPanel\n"
- },
- {
- "contract_id": "EXT:frontend:ReportModel",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 178,
- "end_line": 180,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ReportModel",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ReportModel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportModel\n# #endregion EXT:frontend:ReportModel\n"
- },
- {
- "contract_id": "EXT:frontend:ReportsList",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 182,
- "end_line": 184,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: ReportsList",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ReportsList [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: ReportsList\n# #endregion EXT:frontend:ReportsList\n"
- },
- {
- "contract_id": "EXT:frontend:RepositoryDashboardGrid",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 186,
- "end_line": 188,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: RepositoryDashboardGrid",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:RepositoryDashboardGrid [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: RepositoryDashboardGrid\n# #endregion EXT:frontend:RepositoryDashboardGrid\n"
- },
- {
- "contract_id": "EXT:frontend:RoutePages",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 190,
- "end_line": 192,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: RoutePages",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:RoutePages [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: RoutePages\n# #endregion EXT:frontend:RoutePages\n"
- },
- {
- "contract_id": "EXT:frontend:SessionRepositoryTests",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 194,
- "end_line": 196,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: SessionRepositoryTests",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:SessionRepositoryTests [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: SessionRepositoryTests\n# #endregion EXT:frontend:SessionRepositoryTests\n"
- },
- {
- "contract_id": "EXT:frontend:SettingsUtils",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 198,
- "end_line": 200,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: SettingsUtils",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:SettingsUtils [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: SettingsUtils\n# #endregion EXT:frontend:SettingsUtils\n"
- },
- {
- "contract_id": "EXT:frontend:SidebarNavigation",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 202,
- "end_line": 204,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: SidebarNavigation",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:SidebarNavigation [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: SidebarNavigation\n# #endregion EXT:frontend:SidebarNavigation\n"
- },
- {
- "contract_id": "EXT:frontend:TaskModel",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 206,
- "end_line": 208,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TaskModel",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TaskModel [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskModel\n# #endregion EXT:frontend:TaskModel\n"
- },
- {
- "contract_id": "EXT:frontend:TaskPersistenceService.delete_tasks",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 210,
- "end_line": 212,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TaskPersistenceService.delete_tasks",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TaskPersistenceService.delete_tasks [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskPersistenceService.delete_tasks\n# #endregion EXT:frontend:TaskPersistenceService.delete_tasks\n"
- },
- {
- "contract_id": "EXT:frontend:TaskPersistenceService.load_tasks",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 214,
- "end_line": 216,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TaskPersistenceService.load_tasks",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TaskPersistenceService.load_tasks [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskPersistenceService.load_tasks\n# #endregion EXT:frontend:TaskPersistenceService.load_tasks\n"
- },
- {
- "contract_id": "EXT:frontend:TaskRunner",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 218,
- "end_line": 220,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TaskRunner",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TaskRunner [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TaskRunner\n# #endregion EXT:frontend:TaskRunner\n"
- },
- {
- "contract_id": "EXT:frontend:TasksModule",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 222,
- "end_line": 224,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TasksModule",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TasksModule [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TasksModule\n# #endregion EXT:frontend:TasksModule\n"
- },
- {
- "contract_id": "EXT:frontend:TestPolicyResolutionService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 226,
- "end_line": 228,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TestPolicyResolutionService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TestPolicyResolutionService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TestPolicyResolutionService\n# #endregion EXT:frontend:TestPolicyResolutionService\n"
- },
- {
- "contract_id": "EXT:frontend:TestResourceService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 230,
- "end_line": 232,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TestResourceService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TestResourceService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TestResourceService\n# #endregion EXT:frontend:TestResourceService\n"
- },
- {
- "contract_id": "EXT:frontend:TestScreenshotService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 234,
- "end_line": 236,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TestScreenshotService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TestScreenshotService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TestScreenshotService\n# #endregion EXT:frontend:TestScreenshotService\n"
- },
- {
- "contract_id": "EXT:frontend:TopNavbar",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 238,
- "end_line": 240,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TopNavbar",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TopNavbar [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TopNavbar\n# #endregion EXT:frontend:TopNavbar\n"
- },
- {
- "contract_id": "EXT:frontend:TypeProfiles",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 242,
- "end_line": 244,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: TypeProfiles",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TypeProfiles [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: TypeProfiles\n# #endregion EXT:frontend:TypeProfiles\n"
- },
- {
- "contract_id": "EXT:frontend:activity",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 246,
- "end_line": 248,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: activity",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:activity [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: activity\n# #endregion EXT:frontend:activity\n"
- },
- {
- "contract_id": "EXT:frontend:activityStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 250,
- "end_line": 252,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: activityStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:activityStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: activityStore\n# #endregion EXT:frontend:activityStore\n"
- },
- {
- "contract_id": "EXT:frontend:addToast",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 254,
- "end_line": 256,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: addToast",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:addToast [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: addToast\n# #endregion EXT:frontend:addToast\n"
- },
- {
- "contract_id": "EXT:frontend:api",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 258,
- "end_line": 260,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: api",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:api [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: api\n# #endregion EXT:frontend:api\n"
- },
- {
- "contract_id": "EXT:frontend:api.client",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 262,
- "end_line": 264,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: api.client",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:api.client [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: api.client\n# #endregion EXT:frontend:api.client\n"
- },
- {
- "contract_id": "EXT:frontend:api_module",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 266,
- "end_line": 268,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: api_module",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:api_module [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: api_module\n# #endregion EXT:frontend:api_module\n"
- },
- {
- "contract_id": "EXT:frontend:assistantChat",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 270,
- "end_line": 272,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: assistantChat",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:assistantChat [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: assistantChat\n# #endregion EXT:frontend:assistantChat\n"
- },
- {
- "contract_id": "EXT:frontend:assistantChatStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 274,
- "end_line": 276,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: assistantChatStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:assistantChatStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: assistantChatStore\n# #endregion EXT:frontend:assistantChatStore\n"
- },
- {
- "contract_id": "EXT:frontend:authStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 278,
- "end_line": 280,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: authStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:authStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: authStore\n# #endregion EXT:frontend:authStore\n"
- },
- {
- "contract_id": "EXT:frontend:checkTargetTableSchema",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 282,
- "end_line": 284,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: checkTargetTableSchema",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:checkTargetTableSchema [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: checkTargetTableSchema\n# #endregion EXT:frontend:checkTargetTableSchema\n"
- },
- {
- "contract_id": "EXT:frontend:core_logger",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 286,
- "end_line": 288,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: core_logger",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:core_logger [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: core_logger\n# #endregion EXT:frontend:core_logger\n"
- },
- {
- "contract_id": "EXT:frontend:datasetReviewSession",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 290,
- "end_line": 292,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: datasetReviewSession",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:datasetReviewSession [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: datasetReviewSession\n# #endregion EXT:frontend:datasetReviewSession\n"
- },
- {
- "contract_id": "EXT:frontend:datasetReviewSessionStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 294,
- "end_line": 296,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: datasetReviewSessionStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:datasetReviewSessionStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: datasetReviewSessionStore\n# #endregion EXT:frontend:datasetReviewSessionStore\n"
- },
- {
- "contract_id": "EXT:frontend:dictionaryApi",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 298,
- "end_line": 300,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: dictionaryApi",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:dictionaryApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: dictionaryApi\n# #endregion EXT:frontend:dictionaryApi\n"
- },
- {
- "contract_id": "EXT:frontend:environmentContext",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 302,
- "end_line": 304,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: environmentContext",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:environmentContext [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: environmentContext\n# #endregion EXT:frontend:environmentContext\n"
- },
- {
- "contract_id": "EXT:frontend:environmentContextStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 306,
- "end_line": 308,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: environmentContextStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:environmentContextStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: environmentContextStore\n# #endregion EXT:frontend:environmentContextStore\n"
- },
- {
- "contract_id": "EXT:frontend:fetchApi",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 310,
- "end_line": 312,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: fetchApi",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:fetchApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: fetchApi\n# #endregion EXT:frontend:fetchApi\n"
- },
- {
- "contract_id": "EXT:frontend:fetchDatabases",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 314,
- "end_line": 316,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: fetchDatabases",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:fetchDatabases [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: fetchDatabases\n# #endregion EXT:frontend:fetchDatabases\n"
- },
- {
- "contract_id": "EXT:frontend:fetchEnvironments",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 318,
- "end_line": 320,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: fetchEnvironments",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:fetchEnvironments [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: fetchEnvironments\n# #endregion EXT:frontend:fetchEnvironments\n"
- },
- {
- "contract_id": "EXT:frontend:gitService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 322,
- "end_line": 324,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: gitService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:gitService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: gitService\n# #endregion EXT:frontend:gitService\n"
- },
- {
- "contract_id": "EXT:frontend:goto",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 326,
- "end_line": 328,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: goto",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:goto [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: goto\n# #endregion EXT:frontend:goto\n"
- },
- {
- "contract_id": "EXT:frontend:handleUpdate",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 330,
- "end_line": 332,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: handleUpdate",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:handleUpdate [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: handleUpdate\n# #endregion EXT:frontend:handleUpdate\n"
- },
- {
- "contract_id": "EXT:frontend:healthStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 334,
- "end_line": 336,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: healthStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:healthStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: healthStore\n# #endregion EXT:frontend:healthStore\n"
- },
- {
- "contract_id": "EXT:frontend:i18n",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 338,
- "end_line": 340,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: i18n",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:i18n [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: i18n\n# #endregion EXT:frontend:i18n\n"
- },
- {
- "contract_id": "EXT:frontend:i18n.profile.lookup_error",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 342,
- "end_line": 344,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: i18n.profile.lookup_error",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:i18n.profile.lookup_error [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: i18n.profile.lookup_error\n# #endregion EXT:frontend:i18n.profile.lookup_error\n"
- },
- {
- "contract_id": "EXT:frontend:i18n.t",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 346,
- "end_line": 348,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: i18n.t",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:i18n.t [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: i18n.t\n# #endregion EXT:frontend:i18n.t\n"
- },
- {
- "contract_id": "EXT:frontend:isProductionContextStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 350,
- "end_line": 352,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: isProductionContextStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:isProductionContextStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: isProductionContextStore\n# #endregion EXT:frontend:isProductionContextStore\n"
- },
- {
- "contract_id": "EXT:frontend:migration.mappings.route",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 354,
- "end_line": 356,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: migration.mappings.route",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:migration.mappings.route [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: migration.mappings.route\n# #endregion EXT:frontend:migration.mappings.route\n"
- },
- {
- "contract_id": "EXT:frontend:models.translate",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 358,
- "end_line": 360,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: models.translate",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:models.translate [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: models.translate\n# #endregion EXT:frontend:models.translate\n"
- },
- {
- "contract_id": "EXT:frontend:normalize_report",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 362,
- "end_line": 364,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: normalize_report",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:normalize_report [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: normalize_report\n# #endregion EXT:frontend:normalize_report\n"
- },
- {
- "contract_id": "EXT:frontend:orchestrator_lang_stats",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 366,
- "end_line": 368,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: orchestrator_lang_stats",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:orchestrator_lang_stats [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: orchestrator_lang_stats\n# #endregion EXT:frontend:orchestrator_lang_stats\n"
- },
- {
- "contract_id": "EXT:frontend:policy_resolution_service",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 370,
- "end_line": 372,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: policy_resolution_service",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:policy_resolution_service [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: policy_resolution_service\n# #endregion EXT:frontend:policy_resolution_service\n"
- },
- {
- "contract_id": "EXT:frontend:repository",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 374,
- "end_line": 376,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: repository",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:repository [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: repository\n# #endregion EXT:frontend:repository\n"
- },
- {
- "contract_id": "EXT:frontend:requestApi",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 378,
- "end_line": 380,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: requestApi",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:requestApi [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: requestApi\n# #endregion EXT:frontend:requestApi\n"
- },
- {
- "contract_id": "EXT:frontend:selectedEnvironmentStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 382,
- "end_line": 384,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: selectedEnvironmentStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:selectedEnvironmentStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: selectedEnvironmentStore\n# #endregion EXT:frontend:selectedEnvironmentStore\n"
- },
- {
- "contract_id": "EXT:frontend:setupTests",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 386,
- "end_line": 388,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: setupTests",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:setupTests [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: setupTests\n# #endregion EXT:frontend:setupTests\n"
- },
- {
- "contract_id": "EXT:frontend:sidebar",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 390,
- "end_line": 392,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: sidebar",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:sidebar [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: sidebar\n# #endregion EXT:frontend:sidebar\n"
- },
- {
- "contract_id": "EXT:frontend:sidebarStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 394,
- "end_line": 396,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: sidebarStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:sidebarStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: sidebarStore\n# #endregion EXT:frontend:sidebarStore\n"
- },
- {
- "contract_id": "EXT:frontend:stores",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 398,
- "end_line": 400,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: stores",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:stores [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: stores\n# #endregion EXT:frontend:stores\n"
- },
- {
- "contract_id": "EXT:frontend:taskDrawer",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 402,
- "end_line": 404,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: taskDrawer",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:taskDrawer [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: taskDrawer\n# #endregion EXT:frontend:taskDrawer\n"
- },
- {
- "contract_id": "EXT:frontend:taskDrawerStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 406,
- "end_line": 408,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: taskDrawerStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:taskDrawerStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: taskDrawerStore\n# #endregion EXT:frontend:taskDrawerStore\n"
- },
- {
- "contract_id": "EXT:frontend:taskService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 410,
- "end_line": 412,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: taskService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:taskService [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: taskService\n# #endregion EXT:frontend:taskService\n"
- },
- {
- "contract_id": "EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 414,
- "end_line": 416,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: test_dashboard_validation_plugin_persists_task_and_environment_ids",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: test_dashboard_validation_plugin_persists_task_and_environment_ids\n# #endregion EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids\n"
- },
- {
- "contract_id": "EXT:frontend:test_llm_plugin_persistence",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 418,
- "end_line": 420,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: test_llm_plugin_persistence",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:test_llm_plugin_persistence [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: test_llm_plugin_persistence\n# #endregion EXT:frontend:test_llm_plugin_persistence\n"
- },
- {
- "contract_id": "EXT:frontend:test_llm_provider",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 422,
- "end_line": 424,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: test_llm_provider",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:test_llm_provider [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: test_llm_provider\n# #endregion EXT:frontend:test_llm_provider\n"
- },
- {
- "contract_id": "EXT:frontend:translationRunStore",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 426,
- "end_line": 428,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store/service/component: translationRunStore",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:translationRunStore [C:1] [TYPE External]\n# @BRIEF Frontend store/service/component: translationRunStore\n# #endregion EXT:frontend:translationRunStore\n"
- },
- {
- "contract_id": "EXT:internal:ASSISTANT_AUDIT",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 430,
- "end_line": 432,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: ASSISTANT_AUDIT",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:ASSISTANT_AUDIT [C:1] [TYPE External]\n# @BRIEF Internal module reference: ASSISTANT_AUDIT\n# #endregion EXT:internal:ASSISTANT_AUDIT\n"
- },
- {
- "contract_id": "EXT:internal:CONVERSATIONS",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 442,
- "end_line": 444,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: CONVERSATIONS",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:CONVERSATIONS [C:1] [TYPE External]\n# @BRIEF Internal module reference: CONVERSATIONS\n# #endregion EXT:internal:CONVERSATIONS\n"
- },
- {
- "contract_id": "EXT:internal:ConnectionContracts",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 446,
- "end_line": 448,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: ConnectionContracts",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:ConnectionContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: ConnectionContracts\n# #endregion EXT:internal:ConnectionContracts\n"
- },
- {
- "contract_id": "EXT:internal:CoreContracts",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 450,
- "end_line": 452,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: CoreContracts",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:CoreContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: CoreContracts\n# #endregion EXT:internal:CoreContracts\n"
- },
- {
- "contract_id": "EXT:internal:CotJsonFormat",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 454,
- "end_line": 456,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: CotJsonFormat",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:CotJsonFormat [C:1] [TYPE External]\n# @BRIEF Internal module reference: CotJsonFormat\n# #endregion EXT:internal:CotJsonFormat\n"
- },
- {
- "contract_id": "EXT:internal:MappingBase",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 458,
- "end_line": 460,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: MappingBase",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:MappingBase [C:1] [TYPE External]\n# @BRIEF Internal module reference: MappingBase\n# #endregion EXT:internal:MappingBase\n"
- },
- {
- "contract_id": "EXT:internal:MappingModels:Base",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 462,
- "end_line": 464,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: MappingModels:Base",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:MappingModels:Base [C:1] [TYPE External]\n# @BRIEF Internal module reference: MappingModels:Base\n# #endregion EXT:internal:MappingModels:Base\n"
- },
- {
- "contract_id": "EXT:internal:NavigationContracts",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 466,
- "end_line": 468,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: NavigationContracts",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:NavigationContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: NavigationContracts\n# #endregion EXT:internal:NavigationContracts\n"
- },
- {
- "contract_id": "EXT:internal:PageContracts",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 470,
- "end_line": 472,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: PageContracts",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:PageContracts [C:1] [TYPE External]\n# @BRIEF Internal module reference: PageContracts\n# #endregion EXT:internal:PageContracts\n"
- },
- {
- "contract_id": "EXT:internal:Permissions",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 474,
- "end_line": 476,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal module reference: Permissions",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:Permissions [C:1] [TYPE External]\n# @BRIEF Internal module reference: Permissions\n# #endregion EXT:internal:Permissions\n"
- },
- {
- "contract_id": "EXT:method:AsyncAPIClient._handle_http_error",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 478,
- "end_line": 480,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: AsyncAPIClient._handle_http_error",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:AsyncAPIClient._handle_http_error [C:1] [TYPE External]\n# @BRIEF Method reference: AsyncAPIClient._handle_http_error\n# #endregion EXT:method:AsyncAPIClient._handle_http_error\n"
- },
- {
- "contract_id": "EXT:method:AsyncAPIClient.request",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 482,
- "end_line": 484,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: AsyncAPIClient.request",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:AsyncAPIClient.request [C:1] [TYPE External]\n# @BRIEF Method reference: AsyncAPIClient.request\n# #endregion EXT:method:AsyncAPIClient.request\n"
- },
- {
- "contract_id": "EXT:method:BackupPlugin:execute",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 486,
- "end_line": 488,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: BackupPlugin:execute",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:BackupPlugin:execute [C:1] [TYPE External]\n# @BRIEF Method reference: BackupPlugin:execute\n# #endregion EXT:method:BackupPlugin:execute\n"
- },
- {
- "contract_id": "EXT:method:GlobalSettings.app_timezone",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 490,
- "end_line": 492,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: GlobalSettings.app_timezone",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:GlobalSettings.app_timezone [C:1] [TYPE External]\n# @BRIEF Method reference: GlobalSettings.app_timezone\n# #endregion EXT:method:GlobalSettings.app_timezone\n"
- },
- {
- "contract_id": "EXT:method:MappingService:get_suggestions",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 494,
- "end_line": 496,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: MappingService:get_suggestions",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:MappingService:get_suggestions [C:1] [TYPE External]\n# @BRIEF Method reference: MappingService:get_suggestions\n# #endregion EXT:method:MappingService:get_suggestions\n"
- },
- {
- "contract_id": "EXT:method:MigrationPlugin:execute",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 498,
- "end_line": 500,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: MigrationPlugin:execute",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:MigrationPlugin:execute [C:1] [TYPE External]\n# @BRIEF Method reference: MigrationPlugin:execute\n# #endregion EXT:method:MigrationPlugin:execute\n"
- },
- {
- "contract_id": "EXT:method:SessionEventLogger.log_event",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 502,
- "end_line": 504,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SessionEventLogger.log_event",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SessionEventLogger.log_event [C:1] [TYPE External]\n# @BRIEF Method reference: SessionEventLogger.log_event\n# #endregion EXT:method:SessionEventLogger.log_event\n"
- },
- {
- "contract_id": "EXT:method:SupersetClient.compile_dataset_preview",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 506,
- "end_line": 508,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetClient.compile_dataset_preview",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetClient.compile_dataset_preview [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.compile_dataset_preview\n# #endregion EXT:method:SupersetClient.compile_dataset_preview\n"
- },
- {
- "contract_id": "EXT:method:SupersetClient.get_dashboard",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 510,
- "end_line": 512,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetClient.get_dashboard",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetClient.get_dashboard [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dashboard\n# #endregion EXT:method:SupersetClient.get_dashboard\n"
- },
- {
- "contract_id": "EXT:method:SupersetClient.get_dashboard_detail",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 514,
- "end_line": 516,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetClient.get_dashboard_detail",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetClient.get_dashboard_detail [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dashboard_detail\n# #endregion EXT:method:SupersetClient.get_dashboard_detail\n"
- },
- {
- "contract_id": "EXT:method:SupersetClient.get_dashboards_summary",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 518,
- "end_line": 520,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetClient.get_dashboards_summary",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetClient.get_dashboards_summary [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dashboards_summary\n# #endregion EXT:method:SupersetClient.get_dashboards_summary\n"
- },
- {
- "contract_id": "EXT:method:SupersetClient.get_dataset",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 522,
- "end_line": 524,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetClient.get_dataset",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetClient.get_dataset [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.get_dataset\n# #endregion EXT:method:SupersetClient.get_dataset\n"
- },
- {
- "contract_id": "EXT:method:SupersetClient.update_dataset",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 526,
- "end_line": 528,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetClient.update_dataset",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetClient.update_dataset [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetClient.update_dataset\n# #endregion EXT:method:SupersetClient.update_dataset\n"
- },
- {
- "contract_id": "EXT:method:SupersetContextExtractor.parse_superset_link",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 530,
- "end_line": 532,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: SupersetContextExtractor.parse_superset_link",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:SupersetContextExtractor.parse_superset_link [C:1] [TYPE External]\n# @BRIEF Method reference: SupersetContextExtractor.parse_superset_link\n# #endregion EXT:method:SupersetContextExtractor.parse_superset_link\n"
- },
- {
- "contract_id": "EXT:method:TASK_TYPE_PLUGIN_MAP",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 534,
- "end_line": 536,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TASK_TYPE_PLUGIN_MAP",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TASK_TYPE_PLUGIN_MAP [C:1] [TYPE External]\n# @BRIEF Method reference: TASK_TYPE_PLUGIN_MAP\n# #endregion EXT:method:TASK_TYPE_PLUGIN_MAP\n"
- },
- {
- "contract_id": "EXT:method:TaskLogPersistenceService.add_logs",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 538,
- "end_line": 540,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TaskLogPersistenceService.add_logs",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TaskLogPersistenceService.add_logs [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.add_logs\n# #endregion EXT:method:TaskLogPersistenceService.add_logs\n"
- },
- {
- "contract_id": "EXT:method:TaskLogPersistenceService.delete_logs_for_tasks",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 542,
- "end_line": 544,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TaskLogPersistenceService.delete_logs_for_tasks",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TaskLogPersistenceService.delete_logs_for_tasks [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.delete_logs_for_tasks\n# #endregion EXT:method:TaskLogPersistenceService.delete_logs_for_tasks\n"
- },
- {
- "contract_id": "EXT:method:TaskLogPersistenceService.get_log_stats",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 546,
- "end_line": 548,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TaskLogPersistenceService.get_log_stats",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TaskLogPersistenceService.get_log_stats [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.get_log_stats\n# #endregion EXT:method:TaskLogPersistenceService.get_log_stats\n"
- },
- {
- "contract_id": "EXT:method:TaskLogPersistenceService.get_logs",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 550,
- "end_line": 552,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TaskLogPersistenceService.get_logs",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TaskLogPersistenceService.get_logs [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.get_logs\n# #endregion EXT:method:TaskLogPersistenceService.get_logs\n"
- },
- {
- "contract_id": "EXT:method:TaskLogPersistenceService.get_sources",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 554,
- "end_line": 556,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TaskLogPersistenceService.get_sources",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TaskLogPersistenceService.get_sources [C:1] [TYPE External]\n# @BRIEF Method reference: TaskLogPersistenceService.get_sources\n# #endregion EXT:method:TaskLogPersistenceService.get_sources\n"
- },
- {
- "contract_id": "EXT:method:TaskManager.create_task",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 558,
- "end_line": 560,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TaskManager.create_task",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TaskManager.create_task [C:1] [TYPE External]\n# @BRIEF Method reference: TaskManager.create_task\n# #endregion EXT:method:TaskManager.create_task\n"
- },
- {
- "contract_id": "EXT:method:TranslationExecutor._auto_size_batches",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 562,
- "end_line": 564,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: TranslationExecutor._auto_size_batches",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:TranslationExecutor._auto_size_batches [C:1] [TYPE External]\n# @BRIEF Method reference: TranslationExecutor._auto_size_batches\n# #endregion EXT:method:TranslationExecutor._auto_size_batches\n"
- },
- {
- "contract_id": "EXT:method:_build_body",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 566,
- "end_line": 568,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _build_body",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_build_body [C:1] [TYPE External]\n# @BRIEF Method reference: _build_body\n# #endregion EXT:method:_build_body\n"
- },
- {
- "contract_id": "EXT:method:_extract_resource_name_from_task",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 570,
- "end_line": 572,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _extract_resource_name_from_task",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_extract_resource_name_from_task [C:1] [TYPE External]\n# @BRIEF Method reference: _extract_resource_name_from_task\n# #endregion EXT:method:_extract_resource_name_from_task\n"
- },
- {
- "contract_id": "EXT:method:_extract_resource_type_from_task",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 574,
- "end_line": 576,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _extract_resource_type_from_task",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_extract_resource_type_from_task [C:1] [TYPE External]\n# @BRIEF Method reference: _extract_resource_type_from_task\n# #endregion EXT:method:_extract_resource_type_from_task\n"
- },
- {
- "contract_id": "EXT:method:_find_dashboard_owners",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 578,
- "end_line": 580,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _find_dashboard_owners",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_find_dashboard_owners [C:1] [TYPE External]\n# @BRIEF Method reference: _find_dashboard_owners\n# #endregion EXT:method:_find_dashboard_owners\n"
- },
- {
- "contract_id": "EXT:method:_get_git_status_for_dashboard",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 582,
- "end_line": 584,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _get_git_status_for_dashboard",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_get_git_status_for_dashboard [C:1] [TYPE External]\n# @BRIEF Method reference: _get_git_status_for_dashboard\n# #endregion EXT:method:_get_git_status_for_dashboard\n"
- },
- {
- "contract_id": "EXT:method:_get_last_llm_task_for_dashboard",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 586,
- "end_line": 588,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _get_last_llm_task_for_dashboard",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_get_last_llm_task_for_dashboard [C:1] [TYPE External]\n# @BRIEF Method reference: _get_last_llm_task_for_dashboard\n# #endregion EXT:method:_get_last_llm_task_for_dashboard\n"
- },
- {
- "contract_id": "EXT:method:_get_last_task_for_resource",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 590,
- "end_line": 592,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _get_last_task_for_resource",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_get_last_task_for_resource [C:1] [TYPE External]\n# @BRIEF Method reference: _get_last_task_for_resource\n# #endregion EXT:method:_get_last_task_for_resource\n"
- },
- {
- "contract_id": "EXT:method:_initialize_providers",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 594,
- "end_line": 596,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _initialize_providers",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_initialize_providers [C:1] [TYPE External]\n# @BRIEF Method reference: _initialize_providers\n# #endregion EXT:method:_initialize_providers\n"
- },
- {
- "contract_id": "EXT:method:_llm_http",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 598,
- "end_line": 600,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _llm_http",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_llm_http [C:1] [TYPE External]\n# @BRIEF Method reference: _llm_http\n# #endregion EXT:method:_llm_http\n"
- },
- {
- "contract_id": "EXT:method:_normalize_datetime_for_compare",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 602,
- "end_line": 604,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _normalize_datetime_for_compare",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_normalize_datetime_for_compare [C:1] [TYPE External]\n# @BRIEF Method reference: _normalize_datetime_for_compare\n# #endregion EXT:method:_normalize_datetime_for_compare\n"
- },
- {
- "contract_id": "EXT:method:_normalize_task_status",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 606,
- "end_line": 608,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _normalize_task_status",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_normalize_task_status [C:1] [TYPE External]\n# @BRIEF Method reference: _normalize_task_status\n# #endregion EXT:method:_normalize_task_status\n"
- },
- {
- "contract_id": "EXT:method:_normalize_validation_status",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 610,
- "end_line": 612,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _normalize_validation_status",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_normalize_validation_status [C:1] [TYPE External]\n# @BRIEF Method reference: _normalize_validation_status\n# #endregion EXT:method:_normalize_validation_status\n"
- },
- {
- "contract_id": "EXT:method:_prime_dashboard_meta_cache",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 614,
- "end_line": 616,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _prime_dashboard_meta_cache",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_prime_dashboard_meta_cache [C:1] [TYPE External]\n# @BRIEF Method reference: _prime_dashboard_meta_cache\n# #endregion EXT:method:_prime_dashboard_meta_cache\n"
- },
- {
- "contract_id": "EXT:method:_resolve_dashboard_meta",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 618,
- "end_line": 620,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _resolve_dashboard_meta",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_resolve_dashboard_meta [C:1] [TYPE External]\n# @BRIEF Method reference: _resolve_dashboard_meta\n# #endregion EXT:method:_resolve_dashboard_meta\n"
- },
- {
- "contract_id": "EXT:method:_resolve_targets",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 622,
- "end_line": 624,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _resolve_targets",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_resolve_targets [C:1] [TYPE External]\n# @BRIEF Method reference: _resolve_targets\n# #endregion EXT:method:_resolve_targets\n"
- },
- {
- "contract_id": "EXT:method:_should_notify",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 626,
- "end_line": 628,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: _should_notify",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:_should_notify [C:1] [TYPE External]\n# @BRIEF Method reference: _should_notify\n# #endregion EXT:method:_should_notify\n"
- },
- {
- "contract_id": "EXT:method:decrypt",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 630,
- "end_line": 632,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: decrypt",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:decrypt [C:1] [TYPE External]\n# @BRIEF Method reference: decrypt\n# #endregion EXT:method:decrypt\n"
- },
- {
- "contract_id": "EXT:method:encrypt",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 634,
- "end_line": 636,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: encrypt",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:encrypt [C:1] [TYPE External]\n# @BRIEF Method reference: encrypt\n# #endregion EXT:method:encrypt\n"
- },
- {
- "contract_id": "EXT:method:get_activity_summary",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 638,
- "end_line": 640,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: get_activity_summary",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:get_activity_summary [C:1] [TYPE External]\n# @BRIEF Method reference: get_activity_summary\n# #endregion EXT:method:get_activity_summary\n"
- },
- {
- "contract_id": "EXT:method:get_dashboards_with_status",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 642,
- "end_line": 644,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: get_dashboards_with_status",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:get_dashboards_with_status [C:1] [TYPE External]\n# @BRIEF Method reference: get_dashboards_with_status\n# #endregion EXT:method:get_dashboards_with_status\n"
- },
- {
- "contract_id": "EXT:method:get_datasets_with_status",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 646,
- "end_line": 648,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: get_datasets_with_status",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:get_datasets_with_status [C:1] [TYPE External]\n# @BRIEF Method reference: get_datasets_with_status\n# #endregion EXT:method:get_datasets_with_status\n"
- },
- {
- "contract_id": "EXT:method:get_repo",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 650,
- "end_line": 652,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: get_repo",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:get_repo [C:1] [TYPE External]\n# @BRIEF Method reference: get_repo\n# #endregion EXT:method:get_repo\n"
- },
- {
- "contract_id": "EXT:method:schemas.translate.TargetSchemaValidationRequest",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 654,
- "end_line": 656,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: schemas.translate.TargetSchemaValidationRequest",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:schemas.translate.TargetSchemaValidationRequest [C:1] [TYPE External]\n# @BRIEF Method reference: schemas.translate.TargetSchemaValidationRequest\n# #endregion EXT:method:schemas.translate.TargetSchemaValidationRequest\n"
- },
- {
- "contract_id": "EXT:method:schemas.translate.TargetSchemaValidationResponse",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 658,
- "end_line": 660,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: schemas.translate.TargetSchemaValidationResponse",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:schemas.translate.TargetSchemaValidationResponse [C:1] [TYPE External]\n# @BRIEF Method reference: schemas.translate.TargetSchemaValidationResponse\n# #endregion EXT:method:schemas.translate.TargetSchemaValidationResponse\n"
- },
- {
- "contract_id": "EXT:method:self.network.request",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 662,
- "end_line": 664,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: self.network.request",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:self.network.request [C:1] [TYPE External]\n# @BRIEF Method reference: self.network.request\n# #endregion EXT:method:self.network.request\n"
- },
- {
- "contract_id": "EXT:module:TargetName",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 666,
- "end_line": 668,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: TargetName",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:module:TargetName [C:1] [TYPE External]\n# @BRIEF External reference: TargetName\n# #endregion EXT:module:TargetName\n"
- },
- {
- "contract_id": "EXT:path:EnvSelector.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 670,
- "end_line": 672,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: EnvSelector.svelte",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:EnvSelector.svelte [C:1] [TYPE External]\n# @BRIEF File path: EnvSelector.svelte\n# #endregion EXT:path:EnvSelector.svelte\n"
- },
- {
- "contract_id": "EXT:path:MappingTable.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 674,
- "end_line": 676,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: MappingTable.svelte",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:MappingTable.svelte [C:1] [TYPE External]\n# @BRIEF File path: MappingTable.svelte\n# #endregion EXT:path:MappingTable.svelte\n"
- },
- {
- "contract_id": "EXT:path:backend/requirements.txt",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 678,
- "end_line": 680,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: backend/requirements.txt",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend/requirements.txt [C:1] [TYPE External]\n# @BRIEF File path: backend/requirements.txt\n# #endregion EXT:path:backend/requirements.txt\n"
- },
- {
- "contract_id": "EXT:path:docker/backend.entrypoint.sh",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 682,
- "end_line": 684,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: docker/backend.entrypoint.sh",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:docker/backend.entrypoint.sh [C:1] [TYPE External]\n# @BRIEF File path: docker/backend.entrypoint.sh\n# #endregion EXT:path:docker/backend.entrypoint.sh\n"
- },
- {
- "contract_id": "EXT:path:docker/frontend.entrypoint.sh",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 686,
- "end_line": 688,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: docker/frontend.entrypoint.sh",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:docker/frontend.entrypoint.sh [C:1] [TYPE External]\n# @BRIEF File path: docker/frontend.entrypoint.sh\n# #endregion EXT:path:docker/frontend.entrypoint.sh\n"
- },
- {
- "contract_id": "EXT:path:docker/nginx.conf",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 690,
- "end_line": 692,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: docker/nginx.conf",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:docker/nginx.conf [C:1] [TYPE External]\n# @BRIEF File path: docker/nginx.conf\n# #endregion EXT:path:docker/nginx.conf\n"
- },
- {
- "contract_id": "EXT:path:docker/nginx.ssl.conf",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 694,
- "end_line": 696,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: docker/nginx.ssl.conf",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:docker/nginx.ssl.conf [C:1] [TYPE External]\n# @BRIEF File path: docker/nginx.ssl.conf\n# #endregion EXT:path:docker/nginx.ssl.conf\n"
- },
- {
- "contract_id": "EXT:path:frontend/package.json",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 698,
- "end_line": 700,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: frontend/package.json",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/package.json [C:1] [TYPE External]\n# @BRIEF File path: frontend/package.json\n# #endregion EXT:path:frontend/package.json\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/components/EnvSelector.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 702,
- "end_line": 704,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: frontend/src/components/EnvSelector.svelte",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/components/EnvSelector.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/EnvSelector.svelte\n# #endregion EXT:path:frontend/src/components/EnvSelector.svelte\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/components/MappingTable.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 706,
- "end_line": 708,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: frontend/src/components/MappingTable.svelte",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/components/MappingTable.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/MappingTable.svelte\n# #endregion EXT:path:frontend/src/components/MappingTable.svelte\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/components/PasswordPrompt.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 710,
- "end_line": 712,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: frontend/src/components/PasswordPrompt.svelte",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/components/PasswordPrompt.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/PasswordPrompt.svelte\n# #endregion EXT:path:frontend/src/components/PasswordPrompt.svelte\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/components/TaskHistory.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 714,
- "end_line": 716,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: frontend/src/components/TaskHistory.svelte",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/components/TaskHistory.svelte [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/components/TaskHistory.svelte\n# #endregion EXT:path:frontend/src/components/TaskHistory.svelte\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/lib/api.js",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 718,
- "end_line": 720,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "File path: frontend/src/lib/api.js",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/lib/api.js [C:1] [TYPE External]\n# @BRIEF File path: frontend/src/lib/api.js\n# #endregion EXT:path:frontend/src/lib/api.js\n"
- },
- {
- "contract_id": "EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 722,
- "end_line": 724,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: SUPPORTED_DENSITIES",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES [C:1] [TYPE External]\n# @BRIEF External reference: SUPPORTED_DENSITIES\n# #endregion EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES\n"
- },
- {
- "contract_id": "EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 726,
- "end_line": 728,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: SUPPORTED_START_PAGES",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES [C:1] [TYPE External]\n# @BRIEF External reference: SUPPORTED_START_PAGES\n# #endregion EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES\n"
- },
- {
- "contract_id": "EXT:requests",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 730,
- "end_line": 732,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: requests",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:requests [C:1] [TYPE External]\n# @BRIEF External reference: requests\n# #endregion EXT:requests\n"
- },
- {
- "contract_id": "EXT:spec:BulkReplaceModal:Component",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 734,
- "end_line": 736,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Spec/design-time contract: BulkReplaceModal:Component",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:spec:BulkReplaceModal:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: BulkReplaceModal:Component\n# #endregion EXT:spec:BulkReplaceModal:Component\n"
- },
- {
- "contract_id": "EXT:spec:CorrectionCell:Component",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 738,
- "end_line": 740,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Spec/design-time contract: CorrectionCell:Component",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:spec:CorrectionCell:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: CorrectionCell:Component\n# #endregion EXT:spec:CorrectionCell:Component\n"
- },
- {
- "contract_id": "EXT:spec:StatsBar:Component",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 742,
- "end_line": 744,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Spec/design-time contract: StatsBar:Component",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:spec:StatsBar:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: StatsBar:Component\n# #endregion EXT:spec:StatsBar:Component\n"
- },
- {
- "contract_id": "EXT:spec:TargetSchemaHint:Component",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 746,
- "end_line": 748,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Spec/design-time contract: TargetSchemaHint:Component",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:spec:TargetSchemaHint:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: TargetSchemaHint:Component\n# #endregion EXT:spec:TargetSchemaHint:Component\n"
- },
- {
- "contract_id": "EXT:spec:TranslationPreview:Component",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 750,
- "end_line": 752,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Spec/design-time contract: TranslationPreview:Component",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:spec:TranslationPreview:Component [C:1] [TYPE External]\n# @BRIEF Spec/design-time contract: TranslationPreview:Component\n# #endregion EXT:spec:TranslationPreview:Component\n"
- },
- {
- "contract_id": "EXT:ss-tools:log_security_event",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 754,
- "end_line": 756,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External reference: log_security_event",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:ss-tools:log_security_event [C:1] [TYPE External]\n# @BRIEF External reference: log_security_event\n# #endregion EXT:ss-tools:log_security_event\n"
- },
- {
- "contract_id": "EXT:sveltekit:$app/environment",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 758,
- "end_line": 760,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "SvelteKit import: $app/environment",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:sveltekit:$app/environment [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $app/environment\n# #endregion EXT:sveltekit:$app/environment\n"
- },
- {
- "contract_id": "EXT:sveltekit:$app/navigation",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 762,
- "end_line": 764,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "SvelteKit import: $app/navigation",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:sveltekit:$app/navigation [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $app/navigation\n# #endregion EXT:sveltekit:$app/navigation\n"
- },
- {
- "contract_id": "EXT:sveltekit:$app/stores",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 766,
- "end_line": 768,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "SvelteKit import: $app/stores",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:sveltekit:$app/stores [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $app/stores\n# #endregion EXT:sveltekit:$app/stores\n"
- },
- {
- "contract_id": "EXT:sveltekit:$env/static/public",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 770,
- "end_line": 772,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "SvelteKit import: $env/static/public",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:sveltekit:$env/static/public [C:1] [TYPE External]\n# @BRIEF SvelteKit import: $env/static/public\n# #endregion EXT:sveltekit:$env/static/public\n"
- },
- {
- "contract_id": "EXT:list:GitDashboardPage_GitConfigRoutes",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 775,
- "end_line": 777,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "E2E test list target: GitDashboardPage, GitConfigRoutes",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:GitDashboardPage_GitConfigRoutes [C:1] [TYPE External]\n# @BRIEF E2E test list target: GitDashboardPage, GitConfigRoutes\n# #endregion EXT:list:GitDashboardPage_GitConfigRoutes\n"
- },
- {
- "contract_id": "EXT:list:MigrationApi_SettingsPage",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 779,
- "end_line": 781,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "E2E test list target: MigrationApi, SettingsPage",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:MigrationApi_SettingsPage [C:1] [TYPE External]\n# @BRIEF E2E test list target: MigrationApi, SettingsPage\n# #endregion EXT:list:MigrationApi_SettingsPage\n"
- },
- {
- "contract_id": "EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 783,
- "end_line": 785,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "E2E test list target: LoginPage, SettingsPage, TranslateJob, GitConfig",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig [C:1] [TYPE External]\n# @BRIEF E2E test list target: LoginPage, SettingsPage, TranslateJob, GitConfig\n# #endregion EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig\n"
- },
- {
- "contract_id": "EXT:list:TranslatePage_TranslateJobRoutes",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 787,
- "end_line": 789,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "E2E test list target: TranslatePage, TranslateJobRoutes",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:TranslatePage_TranslateJobRoutes [C:1] [TYPE External]\n# @BRIEF E2E test list target: TranslatePage, TranslateJobRoutes\n# #endregion EXT:list:TranslatePage_TranslateJobRoutes\n"
- },
- {
- "contract_id": "EXT:list:DashboardHub_LLM_SettingsPage",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 791,
- "end_line": 793,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "E2E test list target: DashboardHub, LLM, SettingsPage",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:DashboardHub_LLM_SettingsPage [C:1] [TYPE External]\n# @BRIEF E2E test list target: DashboardHub, LLM, SettingsPage\n# #endregion EXT:list:DashboardHub_LLM_SettingsPage\n"
- },
- {
- "contract_id": "EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 795,
- "end_line": 797,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "E2E test list target: StartupEnvironmentWizard, LoginPage, EnvironmentsTab",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab [C:1] [TYPE External]\n# @BRIEF E2E test list target: StartupEnvironmentWizard, LoginPage, EnvironmentsTab\n# #endregion EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab\n"
- },
- {
- "contract_id": "EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 799,
- "end_line": 801,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Test filter state references",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge [C:1] [TYPE External]\n# @BRIEF Test filter state references\n# #endregion EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge\n"
- },
- {
- "contract_id": "EXT:list:MigrationEngine_internal_methods",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 803,
- "end_line": 805,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "MigrationEngine internal method references",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:MigrationEngine_internal_methods [C:1] [TYPE External]\n# @BRIEF MigrationEngine internal method references\n# #endregion EXT:list:MigrationEngine_internal_methods\n"
- },
- {
- "contract_id": "EXT:list:MigrateEngine_transform_methods",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 807,
- "end_line": 809,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "MigrationEngine transform method references",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:MigrateEngine_transform_methods [C:1] [TYPE External]\n# @BRIEF MigrationEngine transform method references\n# #endregion EXT:list:MigrateEngine_transform_methods\n"
- },
- {
- "contract_id": "EXT:list:GitPackage_all_routes",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 811,
- "end_line": 813,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Git package all route references",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:list:GitPackage_all_routes [C:1] [TYPE External]\n# @BRIEF Git package all route references\n# #endregion EXT:list:GitPackage_all_routes\n"
- },
- {
- "contract_id": "EXT:internal:_text_cleaner",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 815,
- "end_line": 817,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Test module reference: _text_cleaner",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:_text_cleaner [C:1] [TYPE External]\n# @BRIEF Test module reference: _text_cleaner\n# #endregion EXT:internal:_text_cleaner\n"
- },
- {
- "contract_id": "EXT:internal:_utils",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 819,
- "end_line": 821,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Test module reference: _utils",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:_utils [C:1] [TYPE External]\n# @BRIEF Test module reference: _utils\n# #endregion EXT:internal:_utils\n"
- },
- {
- "contract_id": "EXT:internal:test_health_service",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 823,
- "end_line": 825,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Test self-reference: test_health_service",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:test_health_service [C:1] [TYPE External]\n# @BRIEF Test self-reference: test_health_service\n# #endregion EXT:internal:test_health_service\n"
- },
- {
- "contract_id": "EXT:internal:re_sqlparse",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 827,
- "end_line": 829,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal: re and sqlparse",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:re_sqlparse [C:1] [TYPE External]\n# @BRIEF Internal: re and sqlparse\n# #endregion EXT:internal:re_sqlparse\n"
- },
- {
- "contract_id": "EXT:method:ValidationApi.fetchTasks",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 831,
- "end_line": 833,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: ValidationApi.fetchTasks",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:ValidationApi.fetchTasks [C:1] [TYPE External]\n# @BRIEF Method reference: ValidationApi.fetchTasks\n# #endregion EXT:method:ValidationApi.fetchTasks\n"
- },
- {
- "contract_id": "EXT:frontend:ReportTypeProfiles",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 835,
- "end_line": 837,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: ReportTypeProfiles",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ReportTypeProfiles [C:1] [TYPE External]\n# @BRIEF Frontend: ReportTypeProfiles\n# #endregion EXT:frontend:ReportTypeProfiles\n"
- },
- {
- "contract_id": "EXT:frontend:AssistantChatTest",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 839,
- "end_line": 841,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: AssistantChatTest",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:AssistantChatTest [C:1] [TYPE External]\n# @BRIEF Frontend: AssistantChatTest\n# #endregion EXT:frontend:AssistantChatTest\n"
- },
- {
- "contract_id": "EXT:frontend:DashboardDetailPage",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 843,
- "end_line": 845,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: DashboardDetailPage",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DashboardDetailPage [C:1] [TYPE External]\n# @BRIEF Frontend: DashboardDetailPage\n# #endregion EXT:frontend:DashboardDetailPage\n"
- },
- {
- "contract_id": "EXT:frontend:DashboardRouter",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 847,
- "end_line": 849,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: DashboardRouter",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DashboardRouter [C:1] [TYPE External]\n# @BRIEF Frontend: DashboardRouter\n# #endregion EXT:frontend:DashboardRouter\n"
- },
- {
- "contract_id": "EXT:frontend:EnvConfig",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 851,
- "end_line": 853,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: EnvConfig",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:EnvConfig [C:1] [TYPE External]\n# @BRIEF Frontend: EnvConfig\n# #endregion EXT:frontend:EnvConfig\n"
- },
- {
- "contract_id": "EXT:frontend:App",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 855,
- "end_line": 857,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend module: App",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:App [C:1] [TYPE External]\n# @BRIEF Frontend module: App\n# #endregion EXT:frontend:App\n"
- },
- {
- "contract_id": "EXT:frontend:Utils",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 859,
- "end_line": 861,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend utility module: Utils",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:Utils [C:1] [TYPE External]\n# @BRIEF Frontend utility module: Utils\n# #endregion EXT:frontend:Utils\n"
- },
- {
- "contract_id": "EXT:frontend:AuthService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 863,
- "end_line": 865,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: AuthService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:AuthService [C:1] [TYPE External]\n# @BRIEF Frontend: AuthService\n# #endregion EXT:frontend:AuthService\n"
- },
- {
- "contract_id": "EXT:frontend:Navbar",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 867,
- "end_line": 869,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend component: Navbar",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:Navbar [C:1] [TYPE External]\n# @BRIEF Frontend component: Navbar\n# #endregion EXT:frontend:Navbar\n"
- },
- {
- "contract_id": "EXT:frontend:ValidationPolicy",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 871,
- "end_line": 873,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: ValidationPolicy",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:ValidationPolicy [C:1] [TYPE External]\n# @BRIEF Frontend: ValidationPolicy\n# #endregion EXT:frontend:ValidationPolicy\n"
- },
- {
- "contract_id": "EXT:frontend:Select",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 875,
- "end_line": 877,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend component: Select",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:Select [C:1] [TYPE External]\n# @BRIEF Frontend component: Select\n# #endregion EXT:frontend:Select\n"
- },
- {
- "contract_id": "EXT:frontend:AssistantApi",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 879,
- "end_line": 881,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: AssistantApi",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:AssistantApi [C:1] [TYPE External]\n# @BRIEF Frontend: AssistantApi\n# #endregion EXT:frontend:AssistantApi\n"
- },
- {
- "contract_id": "EXT:frontend:DatasetReviewApi",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 883,
- "end_line": 885,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: DatasetReviewApi",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DatasetReviewApi [C:1] [TYPE External]\n# @BRIEF Frontend: DatasetReviewApi\n# #endregion EXT:frontend:DatasetReviewApi\n"
- },
- {
- "contract_id": "EXT:frontend:DatasetReviewWorkspace",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 887,
- "end_line": 889,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: DatasetReviewWorkspace",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DatasetReviewWorkspace [C:1] [TYPE External]\n# @BRIEF Frontend: DatasetReviewWorkspace\n# #endregion EXT:frontend:DatasetReviewWorkspace\n"
- },
- {
- "contract_id": "EXT:frontend:auth",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 891,
- "end_line": 893,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: auth",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:auth [C:1] [TYPE External]\n# @BRIEF Frontend: auth\n# #endregion EXT:frontend:auth\n"
- },
- {
- "contract_id": "EXT:Library:OAuth",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 895,
- "end_line": 897,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: OAuth",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:OAuth [C:1] [TYPE External]\n# @BRIEF External library: OAuth\n# #endregion EXT:Library:OAuth\n"
- },
- {
- "contract_id": "EXT:frontend:adminService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 899,
- "end_line": 901,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend service: adminService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:adminService [C:1] [TYPE External]\n# @BRIEF Frontend service: adminService\n# #endregion EXT:frontend:adminService\n"
- },
- {
- "contract_id": "EXT:path:backend.src.api.routes.migration",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 903,
- "end_line": 905,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API route: migration",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.api.routes.migration [C:1] [TYPE External]\n# @BRIEF Backend API route: migration\n# #endregion EXT:path:backend.src.api.routes.migration\n"
- },
- {
- "contract_id": "EXT:path:backend.src.core.plugin_base.PluginBase",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 907,
- "end_line": 909,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend core: PluginBase",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.core.plugin_base.PluginBase [C:1] [TYPE External]\n# @BRIEF Backend core: PluginBase\n# #endregion EXT:path:backend.src.core.plugin_base.PluginBase\n"
- },
- {
- "contract_id": "EXT:path:backend.src.models.clean_release",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 911,
- "end_line": 913,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend model: clean_release",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.models.clean_release [C:1] [TYPE External]\n# @BRIEF Backend model: clean_release\n# #endregion EXT:path:backend.src.models.clean_release\n"
- },
- {
- "contract_id": "EXT:path:backend.src.models.git",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 915,
- "end_line": 917,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend model: git",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.models.git [C:1] [TYPE External]\n# @BRIEF Backend model: git\n# #endregion EXT:path:backend.src.models.git\n"
- },
- {
- "contract_id": "EXT:path:backend.src.models.report",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 919,
- "end_line": 921,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend model: report",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.models.report [C:1] [TYPE External]\n# @BRIEF Backend model: report\n# #endregion EXT:path:backend.src.models.report\n"
- },
- {
- "contract_id": "EXT:path:backend.api.storage",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 923,
- "end_line": 925,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API: storage",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.api.storage [C:1] [TYPE External]\n# @BRIEF Backend API: storage\n# #endregion EXT:path:backend.api.storage\n"
- },
- {
- "contract_id": "EXT:path:backend.src.services.clean_release.demo_data_service",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 927,
- "end_line": 929,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend service: demo_data_service",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.services.clean_release.demo_data_service [C:1] [TYPE External]\n# @BRIEF Backend service: demo_data_service\n# #endregion EXT:path:backend.src.services.clean_release.demo_data_service\n"
- },
- {
- "contract_id": "EXT:path:backend.src.services.clean_release.repository",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 931,
- "end_line": 933,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend service: clean_release repository",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.services.clean_release.repository [C:1] [TYPE External]\n# @BRIEF Backend service: clean_release repository\n# #endregion EXT:path:backend.src.services.clean_release.repository\n"
- },
- {
- "contract_id": "EXT:path:backend.src.services.health_service.HealthService",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 935,
- "end_line": 937,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend service: HealthService",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.services.health_service.HealthService [C:1] [TYPE External]\n# @BRIEF Backend service: HealthService\n# #endregion EXT:path:backend.src.services.health_service.HealthService\n"
- },
- {
- "contract_id": "EXT:path:backend.src.api.routes.admin.create_user",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 939,
- "end_line": 941,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API route: admin.create_user",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.api.routes.admin.create_user [C:1] [TYPE External]\n# @BRIEF Backend API route: admin.create_user\n# #endregion EXT:path:backend.src.api.routes.admin.create_user\n"
- },
- {
- "contract_id": "EXT:path:backend.src.api.routes.admin.list_roles",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 943,
- "end_line": 945,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API route: admin.list_roles",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.api.routes.admin.list_roles [C:1] [TYPE External]\n# @BRIEF Backend API route: admin.list_roles\n# #endregion EXT:path:backend.src.api.routes.admin.list_roles\n"
- },
- {
- "contract_id": "EXT:path:backend.src.api.routes.admin.list_users",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 947,
- "end_line": 949,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API route: admin.list_users",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.api.routes.admin.list_users [C:1] [TYPE External]\n# @BRIEF Backend API route: admin.list_users\n# #endregion EXT:path:backend.src.api.routes.admin.list_users\n"
- },
- {
- "contract_id": "EXT:path:backend.src.api.routes.settings.get_logging_config",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 951,
- "end_line": 953,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API route: settings.get_logging_config",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.api.routes.settings.get_logging_config [C:1] [TYPE External]\n# @BRIEF Backend API route: settings.get_logging_config\n# #endregion EXT:path:backend.src.api.routes.settings.get_logging_config\n"
- },
- {
- "contract_id": "EXT:path:backend.src.api.routes.settings.update_logging_config",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 955,
- "end_line": 957,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend API route: settings.update_logging_config",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend.src.api.routes.settings.update_logging_config [C:1] [TYPE External]\n# @BRIEF Backend API route: settings.update_logging_config\n# #endregion EXT:path:backend.src.api.routes.settings.update_logging_config\n"
- },
- {
- "contract_id": "EXT:path:backend/src/plugins/llm_analysis/plugin.py",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 959,
- "end_line": 961,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Backend plugin path: llm_analysis/plugin.py",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:backend/src/plugins/llm_analysis/plugin.py [C:1] [TYPE External]\n# @BRIEF Backend plugin path: llm_analysis/plugin.py\n# #endregion EXT:path:backend/src/plugins/llm_analysis/plugin.py\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 967,
- "end_line": 969,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend route path",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte [C:1] [TYPE External]\n# @BRIEF Frontend route path\n# #endregion EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte\n"
- },
- {
- "contract_id": "EXT:path:frontend/src/services/toolsService.js",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 971,
- "end_line": 973,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend service path: toolsService.js",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:frontend/src/services/toolsService.js [C:1] [TYPE External]\n# @BRIEF Frontend service path: toolsService.js\n# #endregion EXT:path:frontend/src/services/toolsService.js\n"
- },
- {
- "contract_id": "EXT:path:../task_logger.py",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 979,
- "end_line": 981,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Relative path: task_logger.py",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:../task_logger.py [C:1] [TYPE External]\n# @BRIEF Relative path: task_logger.py\n# #endregion EXT:path:../task_logger.py\n"
- },
- {
- "contract_id": "EXT:path:/tools/storage",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 983,
- "end_line": 985,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Path: /tools/storage",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:/tools/storage [C:1] [TYPE External]\n# @BRIEF Path: /tools/storage\n# #endregion EXT:path:/tools/storage\n"
- },
- {
- "contract_id": "EXT:path:src/core/logger.py",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 987,
- "end_line": 989,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Path: src/core/logger.py",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:src/core/logger.py [C:1] [TYPE External]\n# @BRIEF Path: src/core/logger.py\n# #endregion EXT:path:src/core/logger.py\n"
- },
- {
- "contract_id": "EXT:path:src.core.logger",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 991,
- "end_line": 993,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Path: src.core.logger",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:src.core.logger [C:1] [TYPE External]\n# @BRIEF Path: src.core.logger\n# #endregion EXT:path:src.core.logger\n"
- },
- {
- "contract_id": "EXT:path:src.core.plugin_base.PluginBase",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 995,
- "end_line": 997,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Path: src.core.plugin_base.PluginBase",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:path:src.core.plugin_base.PluginBase [C:1] [TYPE External]\n# @BRIEF Path: src.core.plugin_base.PluginBase\n# #endregion EXT:path:src.core.plugin_base.PluginBase\n"
- },
- {
- "contract_id": "EXT:frontend:GitServiceClient",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 999,
- "end_line": 1001,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: GitServiceClient",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:GitServiceClient [C:1] [TYPE External]\n# @BRIEF Frontend: GitServiceClient\n# #endregion EXT:frontend:GitServiceClient\n"
- },
- {
- "contract_id": "EXT:Library:sqlalchemy.Session",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1003,
- "end_line": 1005,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: sqlalchemy.Session",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:sqlalchemy.Session [C:1] [TYPE External]\n# @BRIEF External library: sqlalchemy.Session\n# #endregion EXT:Library:sqlalchemy.Session\n"
- },
- {
- "contract_id": "EXT:internal:OAuth",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1007,
- "end_line": 1009,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Internal: OAuth",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:internal:OAuth [C:1] [TYPE External]\n# @BRIEF Internal: OAuth\n# #endregion EXT:internal:OAuth\n"
- },
- {
- "contract_id": "EXT:frontend:BackupManager",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1047,
- "end_line": 1049,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend component: BackupManager",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:BackupManager [C:1] [TYPE External]\n# @BRIEF Frontend component: BackupManager\n# #endregion EXT:frontend:BackupManager\n"
- },
- {
- "contract_id": "EXT:frontend:DebugTool",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1051,
- "end_line": 1053,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend component: DebugTool",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DebugTool [C:1] [TYPE External]\n# @BRIEF Frontend component: DebugTool\n# #endregion EXT:frontend:DebugTool\n"
- },
- {
- "contract_id": "EXT:frontend:toasts",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1055,
- "end_line": 1057,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store: toasts",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:toasts [C:1] [TYPE External]\n# @BRIEF Frontend store: toasts\n# #endregion EXT:frontend:toasts\n"
- },
- {
- "contract_id": "EXT:frontend:onresume",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1059,
- "end_line": 1061,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend event: onresume",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:onresume [C:1] [TYPE External]\n# @BRIEF Frontend event: onresume\n# #endregion EXT:frontend:onresume\n"
- },
- {
- "contract_id": "EXT:frontend:oncancel",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1063,
- "end_line": 1065,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend event: oncancel",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:oncancel [C:1] [TYPE External]\n# @BRIEF Frontend event: oncancel\n# #endregion EXT:frontend:oncancel\n"
- },
- {
- "contract_id": "EXT:frontend:onresolve",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1067,
- "end_line": 1069,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend event: onresolve",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:onresolve [C:1] [TYPE External]\n# @BRIEF Frontend event: onresolve\n# #endregion EXT:frontend:onresolve\n"
- },
- {
- "contract_id": "EXT:frontend:api.js",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1071,
- "end_line": 1073,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend module: api.js",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:api.js [C:1] [TYPE External]\n# @BRIEF Frontend module: api.js\n# #endregion EXT:frontend:api.js\n"
- },
- {
- "contract_id": "EXT:frontend:i18n.locale",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1075,
- "end_line": 1077,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store: i18n.locale",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:i18n.locale [C:1] [TYPE External]\n# @BRIEF Frontend store: i18n.locale\n# #endregion EXT:frontend:i18n.locale\n"
- },
- {
- "contract_id": "EXT:frontend:DashboardMaintenanceBadge",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1079,
- "end_line": 1081,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend component: DashboardMaintenanceBadge",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:DashboardMaintenanceBadge [C:1] [TYPE External]\n# @BRIEF Frontend component: DashboardMaintenanceBadge\n# #endregion EXT:frontend:DashboardMaintenanceBadge\n"
- },
- {
- "contract_id": "EXT:frontend:locale",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1083,
- "end_line": 1085,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend store: locale",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:locale [C:1] [TYPE External]\n# @BRIEF Frontend store: locale\n# #endregion EXT:frontend:locale\n"
- },
- {
- "contract_id": "EXT:frontend:TaskDrawer",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1087,
- "end_line": 1089,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend component: TaskDrawer",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:TaskDrawer [C:1] [TYPE External]\n# @BRIEF Frontend component: TaskDrawer\n# #endregion EXT:frontend:TaskDrawer\n"
- },
- {
- "contract_id": "EXT:Library:superset_tool.client",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1091,
- "end_line": 1093,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: superset_tool.client",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:superset_tool.client [C:1] [TYPE External]\n# @BRIEF External library: superset_tool.client\n# #endregion EXT:Library:superset_tool.client\n"
- },
- {
- "contract_id": "EXT:Library:superset_tool.utils",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1095,
- "end_line": 1097,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: superset_tool.utils",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:superset_tool.utils [C:1] [TYPE External]\n# @BRIEF External library: superset_tool.utils\n# #endregion EXT:Library:superset_tool.utils\n"
- },
- {
- "contract_id": "EXT:Library:pandas",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1099,
- "end_line": 1101,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: pandas",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:pandas [C:1] [TYPE External]\n# @BRIEF External library: pandas\n# #endregion EXT:Library:pandas\n"
- },
- {
- "contract_id": "EXT:Library:bcrypt",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1103,
- "end_line": 1105,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: bcrypt",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:bcrypt [C:1] [TYPE External]\n# @BRIEF External library: bcrypt\n# #endregion EXT:Library:bcrypt\n"
- },
- {
- "contract_id": "EXT:Library:rapidfuzz",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1107,
- "end_line": 1109,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: rapidfuzz",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:rapidfuzz [C:1] [TYPE External]\n# @BRIEF External library: rapidfuzz\n# #endregion EXT:Library:rapidfuzz\n"
- },
- {
- "contract_id": "EXT:Library:tenacity",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1111,
- "end_line": 1113,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: tenacity",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:tenacity [C:1] [TYPE External]\n# @BRIEF External library: tenacity\n# #endregion EXT:Library:tenacity\n"
- },
- {
- "contract_id": "EXT:Library:OAuth2PasswordBearer",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1115,
- "end_line": 1117,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: OAuth2PasswordBearer",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:OAuth2PasswordBearer [C:1] [TYPE External]\n# @BRIEF External library: OAuth2PasswordBearer\n# #endregion EXT:Library:OAuth2PasswordBearer\n"
- },
- {
- "contract_id": "EXT:Library:pydantic_settings.BaseSettings",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1119,
- "end_line": 1121,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "External library: pydantic_settings.BaseSettings",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Library:pydantic_settings.BaseSettings [C:1] [TYPE External]\n# @BRIEF External library: pydantic_settings.BaseSettings\n# #endregion EXT:Library:pydantic_settings.BaseSettings\n"
- },
- {
- "contract_id": "EXT:Python:enum",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1123,
- "end_line": 1125,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Python standard library: enum",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:Python:enum [C:1] [TYPE External]\n# @BRIEF Python standard library: enum\n# #endregion EXT:Python:enum\n"
- },
- {
- "contract_id": "EXT:frontend:i18n_ru_locale",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1135,
- "end_line": 1137,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: i18n_ru_locale",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:i18n_ru_locale [C:1] [TYPE External]\n# @BRIEF Frontend: i18n_ru_locale\n# #endregion EXT:frontend:i18n_ru_locale\n"
- },
- {
- "contract_id": "EXT:frontend:i18n_en_locale",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1139,
- "end_line": 1141,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Frontend: i18n_en_locale",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:frontend:i18n_en_locale [C:1] [TYPE External]\n# @BRIEF Frontend: i18n_en_locale\n# #endregion EXT:frontend:i18n_en_locale\n"
- },
- {
- "contract_id": "EXT:method:adminService.createADGroupMapping",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1143,
- "end_line": 1145,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: adminService.createADGroupMapping",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:adminService.createADGroupMapping [C:1] [TYPE External]\n# @BRIEF Method reference: adminService.createADGroupMapping\n# #endregion EXT:method:adminService.createADGroupMapping\n"
- },
- {
- "contract_id": "EXT:method:adminService.getLoggingConfig",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1147,
- "end_line": 1149,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: adminService.getLoggingConfig",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:adminService.getLoggingConfig [C:1] [TYPE External]\n# @BRIEF Method reference: adminService.getLoggingConfig\n# #endregion EXT:method:adminService.getLoggingConfig\n"
- },
- {
- "contract_id": "EXT:method:adminService.updateLoggingConfig",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1151,
- "end_line": 1153,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: adminService.updateLoggingConfig",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:adminService.updateLoggingConfig [C:1] [TYPE External]\n# @BRIEF Method reference: adminService.updateLoggingConfig\n# #endregion EXT:method:adminService.updateLoggingConfig\n"
- },
- {
- "contract_id": "EXT:method:adminService.deleteUser",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1155,
- "end_line": 1157,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: adminService.deleteUser",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:adminService.deleteUser [C:1] [TYPE External]\n# @BRIEF Method reference: adminService.deleteUser\n# #endregion EXT:method:adminService.deleteUser\n"
- },
- {
- "contract_id": "EXT:method:adminService.createUser",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1159,
- "end_line": 1161,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: adminService.createUser",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:adminService.createUser [C:1] [TYPE External]\n# @BRIEF Method reference: adminService.createUser\n# #endregion EXT:method:adminService.createUser\n"
- },
- {
- "contract_id": "EXT:method:adminService.updateUser",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1163,
- "end_line": 1165,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: adminService.updateUser",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:adminService.updateUser [C:1] [TYPE External]\n# @BRIEF Method reference: adminService.updateUser\n# #endregion EXT:method:adminService.updateUser\n"
- },
- {
- "contract_id": "EXT:method:DatasetMapper.get_sqllab_mappings",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1167,
- "end_line": 1169,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: DatasetMapper.get_sqllab_mappings",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:DatasetMapper.get_sqllab_mappings [C:1] [TYPE External]\n# @BRIEF Method reference: DatasetMapper.get_sqllab_mappings\n# #endregion EXT:method:DatasetMapper.get_sqllab_mappings\n"
- },
- {
- "contract_id": "EXT:method:DatasetMapper.load_excel_mappings",
- "contract_type": "External",
- "file_path": "backend/src/schemas/_external_stubs.py",
- "start_line": 1171,
- "end_line": 1173,
- "tier": "TIER_1",
- "complexity": 1,
- "metadata": {
- "BRIEF": "Method reference: DatasetMapper.load_excel_mappings",
- "COMPLEXITY": 1
- },
- "relations": [],
- "schema_warnings": [],
- "anchor_syntax": "region",
- "tier_source": "AutoCalculated",
- "body": "# #region EXT:method:DatasetMapper.load_excel_mappings [C:1] [TYPE External]\n# @BRIEF Method reference: DatasetMapper.load_excel_mappings\n# #endregion EXT:method:DatasetMapper.load_excel_mappings\n"
- },
{
"contract_id": "AuthSchemas",
"contract_type": "Module",
@@ -47754,20 +42932,20 @@
{
"source_id": "candidate_service",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:backend.src.services.clean_release.repository",
- "target_ref": "[EXT:path:backend.src.services.clean_release.repository]"
+ "target_id": "CleanReleaseRepository",
+ "target_ref": "[CleanReleaseRepository]"
},
{
"source_id": "candidate_service",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:backend.src.models.clean_release",
- "target_ref": "[EXT:path:backend.src.models.clean_release]"
+ "target_id": "CleanReleaseModels",
+ "target_ref": "[CleanReleaseModels]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region candidate_service [C:5] [TYPE Module] [SEMANTICS pydantic, clean-release, candidate, lifecycle, release]\n# @BRIEF Register release candidates with validated artifacts and advance lifecycle through legal transitions.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [EXT:path:backend.src.services.clean_release.repository]\n# @RELATION DEPENDS_ON -> [EXT:path:backend.src.models.clean_release]\n# @PRE candidate_id must be unique; artifacts input must be non-empty and valid.\n# @POST candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.\n# @INVARIANT Candidate lifecycle transitions are delegated to domain guard logic.\n\nfrom __future__ import annotations\n\nfrom collections.abc import Iterable\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom ...models.clean_release import CandidateArtifact, ReleaseCandidate\nfrom .enums import CandidateStatus\nfrom .repository import CleanReleaseRepository\n\n\n# #region _validate_artifacts [TYPE Function]\n# @BRIEF Validate raw artifact payload list for required fields and shape.\n# @PRE artifacts payload is provided by caller.\n# @POST Returns normalized artifact list or raises ValueError.\ndef _validate_artifacts(artifacts: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:\n normalized = list(artifacts)\n if not normalized:\n raise ValueError(\"artifacts must not be empty\")\n\n required_fields = (\"id\", \"path\", \"sha256\", \"size\")\n for index, artifact in enumerate(normalized):\n if not isinstance(artifact, dict):\n raise ValueError(f\"artifact[{index}] must be an object\")\n for field in required_fields:\n if field not in artifact:\n raise ValueError(f\"artifact[{index}] missing required field '{field}'\")\n if not str(artifact[\"id\"]).strip():\n raise ValueError(f\"artifact[{index}] field 'id' must be non-empty\")\n if not str(artifact[\"path\"]).strip():\n raise ValueError(f\"artifact[{index}] field 'path' must be non-empty\")\n if not str(artifact[\"sha256\"]).strip():\n raise ValueError(f\"artifact[{index}] field 'sha256' must be non-empty\")\n if not isinstance(artifact[\"size\"], int) or artifact[\"size\"] <= 0:\n raise ValueError(f\"artifact[{index}] field 'size' must be a positive integer\")\n return normalized\n# #endregion _validate_artifacts\n\n\n# #region register_candidate [TYPE Function]\n# @BRIEF Register a candidate and persist its artifacts with legal lifecycle transition.\n# @PRE candidate_id must be unique and artifacts must pass validation.\n# @POST Candidate exists in repository with PREPARED status and artifacts persisted.\ndef register_candidate(\n repository: CleanReleaseRepository,\n candidate_id: str,\n version: str,\n source_snapshot_ref: str,\n created_by: str,\n artifacts: Iterable[dict[str, Any]],\n) -> ReleaseCandidate:\n if not candidate_id or not candidate_id.strip():\n raise ValueError(\"candidate_id must be non-empty\")\n if not version or not version.strip():\n raise ValueError(\"version must be non-empty\")\n if not source_snapshot_ref or not source_snapshot_ref.strip():\n raise ValueError(\"source_snapshot_ref must be non-empty\")\n if not created_by or not created_by.strip():\n raise ValueError(\"created_by must be non-empty\")\n\n existing = repository.get_candidate(candidate_id)\n if existing is not None:\n raise ValueError(f\"candidate '{candidate_id}' already exists\")\n\n validated_artifacts = _validate_artifacts(artifacts)\n\n candidate = ReleaseCandidate(\n id=candidate_id,\n version=version,\n source_snapshot_ref=source_snapshot_ref,\n created_by=created_by,\n created_at=datetime.now(UTC),\n status=CandidateStatus.DRAFT.value,\n )\n repository.save_candidate(candidate)\n\n for artifact_payload in validated_artifacts:\n artifact = CandidateArtifact(\n id=str(artifact_payload[\"id\"]),\n candidate_id=candidate_id,\n path=str(artifact_payload[\"path\"]),\n sha256=str(artifact_payload[\"sha256\"]),\n size=int(artifact_payload[\"size\"]),\n detected_category=artifact_payload.get(\"detected_category\"),\n declared_category=artifact_payload.get(\"declared_category\"),\n source_uri=artifact_payload.get(\"source_uri\"),\n source_host=artifact_payload.get(\"source_host\"),\n metadata_json=artifact_payload.get(\"metadata_json\", {}),\n )\n repository.save_artifact(artifact)\n\n candidate.transition_to(CandidateStatus.PREPARED)\n repository.save_candidate(candidate)\n return candidate\n# #endregion register_candidate\n\n# #endregion candidate_service\n"
+ "body": "# #region candidate_service [C:5] [TYPE Module] [SEMANTICS pydantic, clean-release, candidate, lifecycle, release]\n# @BRIEF Register release candidates with validated artifacts and advance lifecycle through legal transitions.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [CleanReleaseRepository]\n# @RELATION DEPENDS_ON -> [CleanReleaseModels]\n# @PRE candidate_id must be unique; artifacts input must be non-empty and valid.\n# @POST candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.\n# @INVARIANT Candidate lifecycle transitions are delegated to domain guard logic.\n\nfrom __future__ import annotations\n\nfrom collections.abc import Iterable\nfrom datetime import UTC, datetime\nfrom typing import Any\n\nfrom ...models.clean_release import CandidateArtifact, ReleaseCandidate\nfrom .enums import CandidateStatus\nfrom .repository import CleanReleaseRepository\n\n\n# #region _validate_artifacts [TYPE Function]\n# @BRIEF Validate raw artifact payload list for required fields and shape.\n# @PRE artifacts payload is provided by caller.\n# @POST Returns normalized artifact list or raises ValueError.\ndef _validate_artifacts(artifacts: Iterable[dict[str, Any]]) -> list[dict[str, Any]]:\n normalized = list(artifacts)\n if not normalized:\n raise ValueError(\"artifacts must not be empty\")\n\n required_fields = (\"id\", \"path\", \"sha256\", \"size\")\n for index, artifact in enumerate(normalized):\n if not isinstance(artifact, dict):\n raise ValueError(f\"artifact[{index}] must be an object\")\n for field in required_fields:\n if field not in artifact:\n raise ValueError(f\"artifact[{index}] missing required field '{field}'\")\n if not str(artifact[\"id\"]).strip():\n raise ValueError(f\"artifact[{index}] field 'id' must be non-empty\")\n if not str(artifact[\"path\"]).strip():\n raise ValueError(f\"artifact[{index}] field 'path' must be non-empty\")\n if not str(artifact[\"sha256\"]).strip():\n raise ValueError(f\"artifact[{index}] field 'sha256' must be non-empty\")\n if not isinstance(artifact[\"size\"], int) or artifact[\"size\"] <= 0:\n raise ValueError(f\"artifact[{index}] field 'size' must be a positive integer\")\n return normalized\n# #endregion _validate_artifacts\n\n\n# #region register_candidate [TYPE Function]\n# @BRIEF Register a candidate and persist its artifacts with legal lifecycle transition.\n# @PRE candidate_id must be unique and artifacts must pass validation.\n# @POST Candidate exists in repository with PREPARED status and artifacts persisted.\ndef register_candidate(\n repository: CleanReleaseRepository,\n candidate_id: str,\n version: str,\n source_snapshot_ref: str,\n created_by: str,\n artifacts: Iterable[dict[str, Any]],\n) -> ReleaseCandidate:\n if not candidate_id or not candidate_id.strip():\n raise ValueError(\"candidate_id must be non-empty\")\n if not version or not version.strip():\n raise ValueError(\"version must be non-empty\")\n if not source_snapshot_ref or not source_snapshot_ref.strip():\n raise ValueError(\"source_snapshot_ref must be non-empty\")\n if not created_by or not created_by.strip():\n raise ValueError(\"created_by must be non-empty\")\n\n existing = repository.get_candidate(candidate_id)\n if existing is not None:\n raise ValueError(f\"candidate '{candidate_id}' already exists\")\n\n validated_artifacts = _validate_artifacts(artifacts)\n\n candidate = ReleaseCandidate(\n id=candidate_id,\n version=version,\n source_snapshot_ref=source_snapshot_ref,\n created_by=created_by,\n created_at=datetime.now(UTC),\n status=CandidateStatus.DRAFT.value,\n )\n repository.save_candidate(candidate)\n\n for artifact_payload in validated_artifacts:\n artifact = CandidateArtifact(\n id=str(artifact_payload[\"id\"]),\n candidate_id=candidate_id,\n path=str(artifact_payload[\"path\"]),\n sha256=str(artifact_payload[\"sha256\"]),\n size=int(artifact_payload[\"size\"]),\n detected_category=artifact_payload.get(\"detected_category\"),\n declared_category=artifact_payload.get(\"declared_category\"),\n source_uri=artifact_payload.get(\"source_uri\"),\n source_host=artifact_payload.get(\"source_host\"),\n metadata_json=artifact_payload.get(\"metadata_json\", {}),\n )\n repository.save_artifact(artifact)\n\n candidate.transition_to(CandidateStatus.PREPARED)\n repository.save_candidate(candidate)\n return candidate\n# #endregion register_candidate\n\n# #endregion candidate_service\n"
},
{
"contract_id": "_validate_artifacts",
@@ -52098,7 +47276,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region profile_preference_service [C:4] [TYPE Module] [SEMANTICS profile,preference,crud,persistence]\n# @BRIEF Profile preference persistence — read, update, and normalize user dashboard filter preferences\n# with validation, encryption of git tokens, and deterministic default construction.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [AuthRepository]\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RATIONALE Extracted from ProfileService to satisfy INV_7. Preference CRUD is the core profile\n# operation with DB persistence, token encryption, and cross-field validation — a\n# cohesive unit that isolates cleanly from security badges and Superset lookups.\n# @REJECTED Keeping preference logic inside ProfileService was rejected because it forces all\n# three domains (preferences, security, lookup) into one class exceeding 150 lines,\n# and couples the validation logic to unrelated dependencies.\n# @PRE db session is active.\n# @POST Preference rows are created/updated with normalized values and encrypted tokens.\n# @SIDE_EFFECT Writes preference records via AuthRepository; encrypts git tokens.\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ..core.auth.repository import AuthRepository\nfrom ..core.logger import belief_scope, logger\nfrom ..models.auth import User\nfrom ..models.profile import UserDashboardPreference\nfrom ..schemas.profile import (\n ProfilePreference,\n ProfilePreferenceResponse,\n ProfilePreferenceUpdateRequest,\n)\nfrom .llm_provider import EncryptionManager\nfrom .profile[EXT:internal:_utils] import (\n ProfileAuthorizationError,\n ProfileValidationError,\n build_default_preference,\n mask_secret_value,\n normalize_density,\n normalize_start_page,\n normalize_username,\n sanitize_secret,\n sanitize_text,\n sanitize_username,\n validate_update_payload,\n)\nfrom .security_badge_service import SecurityBadgeService\n\n\n# #region ProfilePreferenceService [C:4] [TYPE Class] [SEMANTICS preference,crud,validation,encryption]\n# @BRIEF Handles profile preference persistence, validation, and token encryption.\n# @RELATION DEPENDS_ON -> [AuthRepository]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @PRE db session is active.\n# @POST Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.\nclass ProfilePreferenceService:\n \"\"\"Profile preference persistence and validation.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize with DB session and references to shared services.\n # @PRE db session is active.\n # @POST Service is ready for preference persistence operations.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n self.auth_repository = AuthRepository(db)\n self.encryption = EncryptionManager()\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n # #endregion __init__\n\n # #region get_my_preference [TYPE Function]\n # @BRIEF Return current user's persisted preference or default non-configured view.\n # @PRE current_user is authenticated.\n # @POST Returned payload belongs to current_user only.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.get_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reflect(\"Loading current user's dashboard preference\")\n preference = self._get_preference_row(current_user.id)\n security_summary = self.security_badge_service.build_security_summary(current_user)\n\n if preference is None:\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference not configured yet\",\n preference=build_default_preference(current_user.id),\n security=security_summary,\n )\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference loaded\",\n preference=self._to_preference_payload(\n preference, str(current_user.id)\n ),\n security=security_summary,\n )\n # #endregion get_my_preference\n\n # #region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Return only dashboard-filter fields required by dashboards listing hot path.\n # @PRE current_user is authenticated.\n # @POST Returns normalized username and profile-default filter toggles without security summary expansion.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n with belief_scope(\n \"ProfilePreferenceService.get_dashboard_filter_binding\", f\"user_id={current_user.id}\"\n ):\n preference = self._get_preference_row(current_user.id)\n if preference is None:\n return {\n \"superset_username\": None,\n \"superset_username_normalized\": None,\n \"show_only_my_dashboards\": False,\n \"show_only_slug_dashboards\": True,\n }\n\n return {\n \"superset_username\": sanitize_username(\n preference.superset_username\n ),\n \"superset_username_normalized\": normalize_username(\n preference.superset_username\n ),\n \"show_only_my_dashboards\": bool(preference.show_only_my_dashboards),\n \"show_only_slug_dashboards\": bool(\n preference.show_only_slug_dashboards\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n }\n # #endregion get_dashboard_filter_binding\n\n # #region update_my_preference [TYPE Function]\n # @BRIEF Validate and persist current user's profile preference in self-scoped mode.\n # @PRE current_user is authenticated and payload is provided.\n # @POST Preference row for current_user is created/updated when validation passes.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.update_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reason(\"Evaluating self-scope guard before preference mutation\")\n requested_user_id = str(target_user_id or current_user.id)\n if requested_user_id != str(current_user.id):\n logger.explore(\"Cross-user mutation attempt blocked\")\n raise ProfileAuthorizationError(\n \"Cross-user preference mutation is forbidden\"\n )\n\n preference = self._get_or_create_preference_row(current_user.id)\n provided_fields = set(getattr(payload, \"model_fields_set\", set()))\n\n effective_superset_username = sanitize_username(\n preference.superset_username\n )\n if \"superset_username\" in provided_fields:\n effective_superset_username = sanitize_username(\n payload.superset_username\n )\n\n effective_show_only = bool(preference.show_only_my_dashboards)\n if \"show_only_my_dashboards\" in provided_fields:\n effective_show_only = bool(payload.show_only_my_dashboards)\n\n effective_show_only_slug = (\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n )\n if \"show_only_slug_dashboards\" in provided_fields:\n effective_show_only_slug = bool(payload.show_only_slug_dashboards)\n\n effective_git_username = sanitize_text(preference.git_username)\n if \"git_username\" in provided_fields:\n effective_git_username = sanitize_text(payload.git_username)\n\n effective_git_email = sanitize_text(preference.git_email)\n if \"git_email\" in provided_fields:\n effective_git_email = sanitize_text(payload.git_email)\n\n effective_start_page = normalize_start_page(preference.start_page)\n if \"start_page\" in provided_fields:\n effective_start_page = normalize_start_page(payload.start_page)\n\n effective_auto_open_task_drawer = (\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n )\n if \"auto_open_task_drawer\" in provided_fields:\n effective_auto_open_task_drawer = bool(payload.auto_open_task_drawer)\n\n effective_dashboards_table_density = normalize_density(\n preference.dashboards_table_density\n )\n if \"dashboards_table_density\" in provided_fields:\n effective_dashboards_table_density = normalize_density(\n payload.dashboards_table_density\n )\n\n effective_telegram_id = sanitize_text(preference.telegram_id)\n if \"telegram_id\" in provided_fields:\n effective_telegram_id = sanitize_text(payload.telegram_id)\n\n effective_email_address = sanitize_text(preference.email_address)\n if \"email_address\" in provided_fields:\n effective_email_address = sanitize_text(payload.email_address)\n\n effective_notify_on_fail = (\n bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True\n )\n if \"notify_on_fail\" in provided_fields:\n effective_notify_on_fail = bool(payload.notify_on_fail)\n\n validation_errors = validate_update_payload(\n superset_username=effective_superset_username,\n show_only_my_dashboards=effective_show_only,\n git_email=effective_git_email,\n start_page=effective_start_page,\n dashboards_table_density=effective_dashboards_table_density,\n email_address=effective_email_address,\n )\n if validation_errors:\n logger.reflect(\"Validation failed; mutation is denied\")\n raise ProfileValidationError(validation_errors)\n\n preference.superset_username = effective_superset_username\n preference.superset_username_normalized = normalize_username(\n effective_superset_username\n )\n preference.show_only_my_dashboards = effective_show_only\n preference.show_only_slug_dashboards = effective_show_only_slug\n\n preference.git_username = effective_git_username\n preference.git_email = effective_git_email\n\n if \"git_personal_access_token\" in provided_fields:\n sanitized_token = sanitize_secret(\n payload.git_personal_access_token\n )\n if sanitized_token is None:\n preference.git_personal_access_token_encrypted = None\n else:\n preference.git_personal_access_token_encrypted = (\n self.encryption.encrypt(sanitized_token)\n )\n\n preference.start_page = effective_start_page\n preference.auto_open_task_drawer = effective_auto_open_task_drawer\n preference.dashboards_table_density = effective_dashboards_table_density\n preference.telegram_id = effective_telegram_id\n preference.email_address = effective_email_address\n preference.notify_on_fail = effective_notify_on_fail\n preference.updated_at = datetime.utcnow()\n\n persisted_preference = self.auth_repository.save_user_dashboard_preference(\n preference\n )\n\n logger.reason(\"Preference persisted successfully\")\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference saved\",\n preference=self._to_preference_payload(\n persisted_preference,\n str(current_user.id),\n ),\n security=self.security_badge_service.build_security_summary(current_user),\n )\n # #endregion update_my_preference\n\n # #region _to_preference_payload [TYPE Function]\n # @BRIEF Map ORM preference row to API DTO with token metadata.\n # @PRE preference row can contain nullable optional fields.\n # @POST Returns normalized ProfilePreference object.\n def _to_preference_payload(\n self,\n preference: UserDashboardPreference,\n user_id: str,\n ) -> ProfilePreference:\n encrypted_token = sanitize_text(\n preference.git_personal_access_token_encrypted\n )\n token_masked = None\n if encrypted_token:\n try:\n decrypted_token = self.encryption.decrypt(encrypted_token)\n token_masked = mask_secret_value(decrypted_token)\n except Exception:\n token_masked = \"***\"\n\n created_at = getattr(preference, \"created_at\", None) or datetime.utcnow()\n updated_at = getattr(preference, \"updated_at\", None) or created_at\n\n return ProfilePreference(\n user_id=str(user_id),\n superset_username=sanitize_username(preference.superset_username),\n superset_username_normalized=normalize_username(\n preference.superset_username_normalized\n ),\n show_only_my_dashboards=bool(preference.show_only_my_dashboards),\n show_only_slug_dashboards=(\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n git_username=sanitize_text(preference.git_username),\n git_email=sanitize_text(preference.git_email),\n has_git_personal_access_token=bool(encrypted_token),\n git_personal_access_token_masked=token_masked,\n start_page=normalize_start_page(preference.start_page),\n auto_open_task_drawer=(\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n ),\n dashboards_table_density=normalize_density(\n preference.dashboards_table_density\n ),\n telegram_id=sanitize_text(preference.telegram_id),\n email_address=sanitize_text(preference.email_address),\n notify_on_fail=bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True,\n created_at=created_at,\n updated_at=updated_at,\n )\n # #endregion _to_preference_payload\n\n # #region _build_default_preference [C:1] [TYPE Function]\n # @BRIEF Delegate to profile[EXT:internal:_utils].build_default_preference.\n def _build_default_preference(self, user_id: str) -> ProfilePreference:\n return build_default_preference(user_id)\n # #endregion _build_default_preference\n\n # #region _get_preference_row [C:2] [TYPE Function]\n # @BRIEF Return persisted preference row for user or None.\n def _get_preference_row(self, user_id: str) -> UserDashboardPreference | None:\n return self.auth_repository.get_user_dashboard_preference(str(user_id))\n # #endregion _get_preference_row\n\n # #region _get_or_create_preference_row [C:2] [TYPE Function]\n # @BRIEF Return existing preference row or create new unsaved row.\n def _get_or_create_preference_row(self, user_id: str) -> UserDashboardPreference:\n existing = self._get_preference_row(user_id)\n if existing is not None:\n return existing\n return UserDashboardPreference(user_id=str(user_id))\n # #endregion _get_or_create_preference_row\n# #endregion ProfilePreferenceService\n# #endregion profile_preference_service\n"
+ "body": "# #region profile_preference_service [C:4] [TYPE Module] [SEMANTICS profile,preference,crud,persistence]\n# @BRIEF Profile preference persistence — read, update, and normalize user dashboard filter preferences\n# with validation, encryption of git tokens, and deterministic default construction.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [AuthRepository]\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RATIONALE Extracted from ProfileService to satisfy INV_7. Preference CRUD is the core profile\n# operation with DB persistence, token encryption, and cross-field validation — a\n# cohesive unit that isolates cleanly from security badges and Superset lookups.\n# @REJECTED Keeping preference logic inside ProfileService was rejected because it forces all\n# three domains (preferences, security, lookup) into one class exceeding 150 lines,\n# and couples the validation logic to unrelated dependencies.\n# @PRE db session is active.\n# @POST Preference rows are created/updated with normalized values and encrypted tokens.\n# @SIDE_EFFECT Writes preference records via AuthRepository; encrypts git tokens.\n\nfrom datetime import datetime\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ..core.auth.repository import AuthRepository\nfrom ..core.logger import belief_scope, logger\nfrom ..models.auth import User\nfrom ..models.profile import UserDashboardPreference\nfrom ..schemas.profile import (\n ProfilePreference,\n ProfilePreferenceResponse,\n ProfilePreferenceUpdateRequest,\n)\nfrom .llm_provider import EncryptionManager\nfrom .profile_utils import (\n ProfileAuthorizationError,\n ProfileValidationError,\n build_default_preference,\n mask_secret_value,\n normalize_density,\n normalize_start_page,\n normalize_username,\n sanitize_secret,\n sanitize_text,\n sanitize_username,\n validate_update_payload,\n)\nfrom .security_badge_service import SecurityBadgeService\n\n\n# #region ProfilePreferenceService [C:4] [TYPE Class] [SEMANTICS preference,crud,validation,encryption]\n# @BRIEF Handles profile preference persistence, validation, and token encryption.\n# @RELATION DEPENDS_ON -> [AuthRepository]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @PRE db session is active.\n# @POST Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.\nclass ProfilePreferenceService:\n \"\"\"Profile preference persistence and validation.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize with DB session and references to shared services.\n # @PRE db session is active.\n # @POST Service is ready for preference persistence operations.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n self.auth_repository = AuthRepository(db)\n self.encryption = EncryptionManager()\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n # #endregion __init__\n\n # #region get_my_preference [TYPE Function]\n # @BRIEF Return current user's persisted preference or default non-configured view.\n # @PRE current_user is authenticated.\n # @POST Returned payload belongs to current_user only.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.get_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reflect(\"Loading current user's dashboard preference\")\n preference = self._get_preference_row(current_user.id)\n security_summary = self.security_badge_service.build_security_summary(current_user)\n\n if preference is None:\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference not configured yet\",\n preference=build_default_preference(current_user.id),\n security=security_summary,\n )\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference loaded\",\n preference=self._to_preference_payload(\n preference, str(current_user.id)\n ),\n security=security_summary,\n )\n # #endregion get_my_preference\n\n # #region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Return only dashboard-filter fields required by dashboards listing hot path.\n # @PRE current_user is authenticated.\n # @POST Returns normalized username and profile-default filter toggles without security summary expansion.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n with belief_scope(\n \"ProfilePreferenceService.get_dashboard_filter_binding\", f\"user_id={current_user.id}\"\n ):\n preference = self._get_preference_row(current_user.id)\n if preference is None:\n return {\n \"superset_username\": None,\n \"superset_username_normalized\": None,\n \"show_only_my_dashboards\": False,\n \"show_only_slug_dashboards\": True,\n }\n\n return {\n \"superset_username\": sanitize_username(\n preference.superset_username\n ),\n \"superset_username_normalized\": normalize_username(\n preference.superset_username\n ),\n \"show_only_my_dashboards\": bool(preference.show_only_my_dashboards),\n \"show_only_slug_dashboards\": bool(\n preference.show_only_slug_dashboards\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n }\n # #endregion get_dashboard_filter_binding\n\n # #region update_my_preference [TYPE Function]\n # @BRIEF Validate and persist current user's profile preference in self-scoped mode.\n # @PRE current_user is authenticated and payload is provided.\n # @POST Preference row for current_user is created/updated when validation passes.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.update_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reason(\"Evaluating self-scope guard before preference mutation\")\n requested_user_id = str(target_user_id or current_user.id)\n if requested_user_id != str(current_user.id):\n logger.explore(\"Cross-user mutation attempt blocked\")\n raise ProfileAuthorizationError(\n \"Cross-user preference mutation is forbidden\"\n )\n\n preference = self._get_or_create_preference_row(current_user.id)\n provided_fields = set(getattr(payload, \"model_fields_set\", set()))\n\n effective_superset_username = sanitize_username(\n preference.superset_username\n )\n if \"superset_username\" in provided_fields:\n effective_superset_username = sanitize_username(\n payload.superset_username\n )\n\n effective_show_only = bool(preference.show_only_my_dashboards)\n if \"show_only_my_dashboards\" in provided_fields:\n effective_show_only = bool(payload.show_only_my_dashboards)\n\n effective_show_only_slug = (\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n )\n if \"show_only_slug_dashboards\" in provided_fields:\n effective_show_only_slug = bool(payload.show_only_slug_dashboards)\n\n effective_git_username = sanitize_text(preference.git_username)\n if \"git_username\" in provided_fields:\n effective_git_username = sanitize_text(payload.git_username)\n\n effective_git_email = sanitize_text(preference.git_email)\n if \"git_email\" in provided_fields:\n effective_git_email = sanitize_text(payload.git_email)\n\n effective_start_page = normalize_start_page(preference.start_page)\n if \"start_page\" in provided_fields:\n effective_start_page = normalize_start_page(payload.start_page)\n\n effective_auto_open_task_drawer = (\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n )\n if \"auto_open_task_drawer\" in provided_fields:\n effective_auto_open_task_drawer = bool(payload.auto_open_task_drawer)\n\n effective_dashboards_table_density = normalize_density(\n preference.dashboards_table_density\n )\n if \"dashboards_table_density\" in provided_fields:\n effective_dashboards_table_density = normalize_density(\n payload.dashboards_table_density\n )\n\n effective_telegram_id = sanitize_text(preference.telegram_id)\n if \"telegram_id\" in provided_fields:\n effective_telegram_id = sanitize_text(payload.telegram_id)\n\n effective_email_address = sanitize_text(preference.email_address)\n if \"email_address\" in provided_fields:\n effective_email_address = sanitize_text(payload.email_address)\n\n effective_notify_on_fail = (\n bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True\n )\n if \"notify_on_fail\" in provided_fields:\n effective_notify_on_fail = bool(payload.notify_on_fail)\n\n validation_errors = validate_update_payload(\n superset_username=effective_superset_username,\n show_only_my_dashboards=effective_show_only,\n git_email=effective_git_email,\n start_page=effective_start_page,\n dashboards_table_density=effective_dashboards_table_density,\n email_address=effective_email_address,\n )\n if validation_errors:\n logger.reflect(\"Validation failed; mutation is denied\")\n raise ProfileValidationError(validation_errors)\n\n preference.superset_username = effective_superset_username\n preference.superset_username_normalized = normalize_username(\n effective_superset_username\n )\n preference.show_only_my_dashboards = effective_show_only\n preference.show_only_slug_dashboards = effective_show_only_slug\n\n preference.git_username = effective_git_username\n preference.git_email = effective_git_email\n\n if \"git_personal_access_token\" in provided_fields:\n sanitized_token = sanitize_secret(\n payload.git_personal_access_token\n )\n if sanitized_token is None:\n preference.git_personal_access_token_encrypted = None\n else:\n preference.git_personal_access_token_encrypted = (\n self.encryption.encrypt(sanitized_token)\n )\n\n preference.start_page = effective_start_page\n preference.auto_open_task_drawer = effective_auto_open_task_drawer\n preference.dashboards_table_density = effective_dashboards_table_density\n preference.telegram_id = effective_telegram_id\n preference.email_address = effective_email_address\n preference.notify_on_fail = effective_notify_on_fail\n preference.updated_at = datetime.utcnow()\n\n persisted_preference = self.auth_repository.save_user_dashboard_preference(\n preference\n )\n\n logger.reason(\"Preference persisted successfully\")\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference saved\",\n preference=self._to_preference_payload(\n persisted_preference,\n str(current_user.id),\n ),\n security=self.security_badge_service.build_security_summary(current_user),\n )\n # #endregion update_my_preference\n\n # #region _to_preference_payload [TYPE Function]\n # @BRIEF Map ORM preference row to API DTO with token metadata.\n # @PRE preference row can contain nullable optional fields.\n # @POST Returns normalized ProfilePreference object.\n def _to_preference_payload(\n self,\n preference: UserDashboardPreference,\n user_id: str,\n ) -> ProfilePreference:\n encrypted_token = sanitize_text(\n preference.git_personal_access_token_encrypted\n )\n token_masked = None\n if encrypted_token:\n try:\n decrypted_token = self.encryption.decrypt(encrypted_token)\n token_masked = mask_secret_value(decrypted_token)\n except Exception:\n token_masked = \"***\"\n\n created_at = getattr(preference, \"created_at\", None) or datetime.utcnow()\n updated_at = getattr(preference, \"updated_at\", None) or created_at\n\n return ProfilePreference(\n user_id=str(user_id),\n superset_username=sanitize_username(preference.superset_username),\n superset_username_normalized=normalize_username(\n preference.superset_username_normalized\n ),\n show_only_my_dashboards=bool(preference.show_only_my_dashboards),\n show_only_slug_dashboards=(\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n git_username=sanitize_text(preference.git_username),\n git_email=sanitize_text(preference.git_email),\n has_git_personal_access_token=bool(encrypted_token),\n git_personal_access_token_masked=token_masked,\n start_page=normalize_start_page(preference.start_page),\n auto_open_task_drawer=(\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n ),\n dashboards_table_density=normalize_density(\n preference.dashboards_table_density\n ),\n telegram_id=sanitize_text(preference.telegram_id),\n email_address=sanitize_text(preference.email_address),\n notify_on_fail=bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True,\n created_at=created_at,\n updated_at=updated_at,\n )\n # #endregion _to_preference_payload\n\n # #region _build_default_preference [C:1] [TYPE Function]\n # @BRIEF Delegate to ProfileUtils.build_default_preference.\n def _build_default_preference(self, user_id: str) -> ProfilePreference:\n return build_default_preference(user_id)\n # #endregion _build_default_preference\n\n # #region _get_preference_row [C:2] [TYPE Function]\n # @BRIEF Return persisted preference row for user or None.\n def _get_preference_row(self, user_id: str) -> UserDashboardPreference | None:\n return self.auth_repository.get_user_dashboard_preference(str(user_id))\n # #endregion _get_preference_row\n\n # #region _get_or_create_preference_row [C:2] [TYPE Function]\n # @BRIEF Return existing preference row or create new unsaved row.\n def _get_or_create_preference_row(self, user_id: str) -> UserDashboardPreference:\n existing = self._get_preference_row(user_id)\n if existing is not None:\n return existing\n return UserDashboardPreference(user_id=str(user_id))\n # #endregion _get_or_create_preference_row\n# #endregion ProfilePreferenceService\n# #endregion profile_preference_service\n"
},
{
"contract_id": "ProfilePreferenceService",
@@ -52137,7 +47315,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region ProfilePreferenceService [C:4] [TYPE Class] [SEMANTICS preference,crud,validation,encryption]\n# @BRIEF Handles profile preference persistence, validation, and token encryption.\n# @RELATION DEPENDS_ON -> [AuthRepository]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @PRE db session is active.\n# @POST Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.\nclass ProfilePreferenceService:\n \"\"\"Profile preference persistence and validation.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize with DB session and references to shared services.\n # @PRE db session is active.\n # @POST Service is ready for preference persistence operations.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n self.auth_repository = AuthRepository(db)\n self.encryption = EncryptionManager()\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n # #endregion __init__\n\n # #region get_my_preference [TYPE Function]\n # @BRIEF Return current user's persisted preference or default non-configured view.\n # @PRE current_user is authenticated.\n # @POST Returned payload belongs to current_user only.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.get_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reflect(\"Loading current user's dashboard preference\")\n preference = self._get_preference_row(current_user.id)\n security_summary = self.security_badge_service.build_security_summary(current_user)\n\n if preference is None:\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference not configured yet\",\n preference=build_default_preference(current_user.id),\n security=security_summary,\n )\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference loaded\",\n preference=self._to_preference_payload(\n preference, str(current_user.id)\n ),\n security=security_summary,\n )\n # #endregion get_my_preference\n\n # #region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Return only dashboard-filter fields required by dashboards listing hot path.\n # @PRE current_user is authenticated.\n # @POST Returns normalized username and profile-default filter toggles without security summary expansion.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n with belief_scope(\n \"ProfilePreferenceService.get_dashboard_filter_binding\", f\"user_id={current_user.id}\"\n ):\n preference = self._get_preference_row(current_user.id)\n if preference is None:\n return {\n \"superset_username\": None,\n \"superset_username_normalized\": None,\n \"show_only_my_dashboards\": False,\n \"show_only_slug_dashboards\": True,\n }\n\n return {\n \"superset_username\": sanitize_username(\n preference.superset_username\n ),\n \"superset_username_normalized\": normalize_username(\n preference.superset_username\n ),\n \"show_only_my_dashboards\": bool(preference.show_only_my_dashboards),\n \"show_only_slug_dashboards\": bool(\n preference.show_only_slug_dashboards\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n }\n # #endregion get_dashboard_filter_binding\n\n # #region update_my_preference [TYPE Function]\n # @BRIEF Validate and persist current user's profile preference in self-scoped mode.\n # @PRE current_user is authenticated and payload is provided.\n # @POST Preference row for current_user is created/updated when validation passes.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.update_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reason(\"Evaluating self-scope guard before preference mutation\")\n requested_user_id = str(target_user_id or current_user.id)\n if requested_user_id != str(current_user.id):\n logger.explore(\"Cross-user mutation attempt blocked\")\n raise ProfileAuthorizationError(\n \"Cross-user preference mutation is forbidden\"\n )\n\n preference = self._get_or_create_preference_row(current_user.id)\n provided_fields = set(getattr(payload, \"model_fields_set\", set()))\n\n effective_superset_username = sanitize_username(\n preference.superset_username\n )\n if \"superset_username\" in provided_fields:\n effective_superset_username = sanitize_username(\n payload.superset_username\n )\n\n effective_show_only = bool(preference.show_only_my_dashboards)\n if \"show_only_my_dashboards\" in provided_fields:\n effective_show_only = bool(payload.show_only_my_dashboards)\n\n effective_show_only_slug = (\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n )\n if \"show_only_slug_dashboards\" in provided_fields:\n effective_show_only_slug = bool(payload.show_only_slug_dashboards)\n\n effective_git_username = sanitize_text(preference.git_username)\n if \"git_username\" in provided_fields:\n effective_git_username = sanitize_text(payload.git_username)\n\n effective_git_email = sanitize_text(preference.git_email)\n if \"git_email\" in provided_fields:\n effective_git_email = sanitize_text(payload.git_email)\n\n effective_start_page = normalize_start_page(preference.start_page)\n if \"start_page\" in provided_fields:\n effective_start_page = normalize_start_page(payload.start_page)\n\n effective_auto_open_task_drawer = (\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n )\n if \"auto_open_task_drawer\" in provided_fields:\n effective_auto_open_task_drawer = bool(payload.auto_open_task_drawer)\n\n effective_dashboards_table_density = normalize_density(\n preference.dashboards_table_density\n )\n if \"dashboards_table_density\" in provided_fields:\n effective_dashboards_table_density = normalize_density(\n payload.dashboards_table_density\n )\n\n effective_telegram_id = sanitize_text(preference.telegram_id)\n if \"telegram_id\" in provided_fields:\n effective_telegram_id = sanitize_text(payload.telegram_id)\n\n effective_email_address = sanitize_text(preference.email_address)\n if \"email_address\" in provided_fields:\n effective_email_address = sanitize_text(payload.email_address)\n\n effective_notify_on_fail = (\n bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True\n )\n if \"notify_on_fail\" in provided_fields:\n effective_notify_on_fail = bool(payload.notify_on_fail)\n\n validation_errors = validate_update_payload(\n superset_username=effective_superset_username,\n show_only_my_dashboards=effective_show_only,\n git_email=effective_git_email,\n start_page=effective_start_page,\n dashboards_table_density=effective_dashboards_table_density,\n email_address=effective_email_address,\n )\n if validation_errors:\n logger.reflect(\"Validation failed; mutation is denied\")\n raise ProfileValidationError(validation_errors)\n\n preference.superset_username = effective_superset_username\n preference.superset_username_normalized = normalize_username(\n effective_superset_username\n )\n preference.show_only_my_dashboards = effective_show_only\n preference.show_only_slug_dashboards = effective_show_only_slug\n\n preference.git_username = effective_git_username\n preference.git_email = effective_git_email\n\n if \"git_personal_access_token\" in provided_fields:\n sanitized_token = sanitize_secret(\n payload.git_personal_access_token\n )\n if sanitized_token is None:\n preference.git_personal_access_token_encrypted = None\n else:\n preference.git_personal_access_token_encrypted = (\n self.encryption.encrypt(sanitized_token)\n )\n\n preference.start_page = effective_start_page\n preference.auto_open_task_drawer = effective_auto_open_task_drawer\n preference.dashboards_table_density = effective_dashboards_table_density\n preference.telegram_id = effective_telegram_id\n preference.email_address = effective_email_address\n preference.notify_on_fail = effective_notify_on_fail\n preference.updated_at = datetime.utcnow()\n\n persisted_preference = self.auth_repository.save_user_dashboard_preference(\n preference\n )\n\n logger.reason(\"Preference persisted successfully\")\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference saved\",\n preference=self._to_preference_payload(\n persisted_preference,\n str(current_user.id),\n ),\n security=self.security_badge_service.build_security_summary(current_user),\n )\n # #endregion update_my_preference\n\n # #region _to_preference_payload [TYPE Function]\n # @BRIEF Map ORM preference row to API DTO with token metadata.\n # @PRE preference row can contain nullable optional fields.\n # @POST Returns normalized ProfilePreference object.\n def _to_preference_payload(\n self,\n preference: UserDashboardPreference,\n user_id: str,\n ) -> ProfilePreference:\n encrypted_token = sanitize_text(\n preference.git_personal_access_token_encrypted\n )\n token_masked = None\n if encrypted_token:\n try:\n decrypted_token = self.encryption.decrypt(encrypted_token)\n token_masked = mask_secret_value(decrypted_token)\n except Exception:\n token_masked = \"***\"\n\n created_at = getattr(preference, \"created_at\", None) or datetime.utcnow()\n updated_at = getattr(preference, \"updated_at\", None) or created_at\n\n return ProfilePreference(\n user_id=str(user_id),\n superset_username=sanitize_username(preference.superset_username),\n superset_username_normalized=normalize_username(\n preference.superset_username_normalized\n ),\n show_only_my_dashboards=bool(preference.show_only_my_dashboards),\n show_only_slug_dashboards=(\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n git_username=sanitize_text(preference.git_username),\n git_email=sanitize_text(preference.git_email),\n has_git_personal_access_token=bool(encrypted_token),\n git_personal_access_token_masked=token_masked,\n start_page=normalize_start_page(preference.start_page),\n auto_open_task_drawer=(\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n ),\n dashboards_table_density=normalize_density(\n preference.dashboards_table_density\n ),\n telegram_id=sanitize_text(preference.telegram_id),\n email_address=sanitize_text(preference.email_address),\n notify_on_fail=bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True,\n created_at=created_at,\n updated_at=updated_at,\n )\n # #endregion _to_preference_payload\n\n # #region _build_default_preference [C:1] [TYPE Function]\n # @BRIEF Delegate to profile[EXT:internal:_utils].build_default_preference.\n def _build_default_preference(self, user_id: str) -> ProfilePreference:\n return build_default_preference(user_id)\n # #endregion _build_default_preference\n\n # #region _get_preference_row [C:2] [TYPE Function]\n # @BRIEF Return persisted preference row for user or None.\n def _get_preference_row(self, user_id: str) -> UserDashboardPreference | None:\n return self.auth_repository.get_user_dashboard_preference(str(user_id))\n # #endregion _get_preference_row\n\n # #region _get_or_create_preference_row [C:2] [TYPE Function]\n # @BRIEF Return existing preference row or create new unsaved row.\n def _get_or_create_preference_row(self, user_id: str) -> UserDashboardPreference:\n existing = self._get_preference_row(user_id)\n if existing is not None:\n return existing\n return UserDashboardPreference(user_id=str(user_id))\n # #endregion _get_or_create_preference_row\n# #endregion ProfilePreferenceService\n"
+ "body": "# #region ProfilePreferenceService [C:4] [TYPE Class] [SEMANTICS preference,crud,validation,encryption]\n# @BRIEF Handles profile preference persistence, validation, and token encryption.\n# @RELATION DEPENDS_ON -> [AuthRepository]\n# @RELATION DEPENDS_ON -> [EncryptionManager]\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @PRE db session is active.\n# @POST Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.\nclass ProfilePreferenceService:\n \"\"\"Profile preference persistence and validation.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize with DB session and references to shared services.\n # @PRE db session is active.\n # @POST Service is ready for preference persistence operations.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n self.auth_repository = AuthRepository(db)\n self.encryption = EncryptionManager()\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n # #endregion __init__\n\n # #region get_my_preference [TYPE Function]\n # @BRIEF Return current user's persisted preference or default non-configured view.\n # @PRE current_user is authenticated.\n # @POST Returned payload belongs to current_user only.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.get_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reflect(\"Loading current user's dashboard preference\")\n preference = self._get_preference_row(current_user.id)\n security_summary = self.security_badge_service.build_security_summary(current_user)\n\n if preference is None:\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference not configured yet\",\n preference=build_default_preference(current_user.id),\n security=security_summary,\n )\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference loaded\",\n preference=self._to_preference_payload(\n preference, str(current_user.id)\n ),\n security=security_summary,\n )\n # #endregion get_my_preference\n\n # #region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Return only dashboard-filter fields required by dashboards listing hot path.\n # @PRE current_user is authenticated.\n # @POST Returns normalized username and profile-default filter toggles without security summary expansion.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n with belief_scope(\n \"ProfilePreferenceService.get_dashboard_filter_binding\", f\"user_id={current_user.id}\"\n ):\n preference = self._get_preference_row(current_user.id)\n if preference is None:\n return {\n \"superset_username\": None,\n \"superset_username_normalized\": None,\n \"show_only_my_dashboards\": False,\n \"show_only_slug_dashboards\": True,\n }\n\n return {\n \"superset_username\": sanitize_username(\n preference.superset_username\n ),\n \"superset_username_normalized\": normalize_username(\n preference.superset_username\n ),\n \"show_only_my_dashboards\": bool(preference.show_only_my_dashboards),\n \"show_only_slug_dashboards\": bool(\n preference.show_only_slug_dashboards\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n }\n # #endregion get_dashboard_filter_binding\n\n # #region update_my_preference [TYPE Function]\n # @BRIEF Validate and persist current user's profile preference in self-scoped mode.\n # @PRE current_user is authenticated and payload is provided.\n # @POST Preference row for current_user is created/updated when validation passes.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n with belief_scope(\n \"ProfilePreferenceService.update_my_preference\", f\"user_id={current_user.id}\"\n ):\n logger.reason(\"Evaluating self-scope guard before preference mutation\")\n requested_user_id = str(target_user_id or current_user.id)\n if requested_user_id != str(current_user.id):\n logger.explore(\"Cross-user mutation attempt blocked\")\n raise ProfileAuthorizationError(\n \"Cross-user preference mutation is forbidden\"\n )\n\n preference = self._get_or_create_preference_row(current_user.id)\n provided_fields = set(getattr(payload, \"model_fields_set\", set()))\n\n effective_superset_username = sanitize_username(\n preference.superset_username\n )\n if \"superset_username\" in provided_fields:\n effective_superset_username = sanitize_username(\n payload.superset_username\n )\n\n effective_show_only = bool(preference.show_only_my_dashboards)\n if \"show_only_my_dashboards\" in provided_fields:\n effective_show_only = bool(payload.show_only_my_dashboards)\n\n effective_show_only_slug = (\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n )\n if \"show_only_slug_dashboards\" in provided_fields:\n effective_show_only_slug = bool(payload.show_only_slug_dashboards)\n\n effective_git_username = sanitize_text(preference.git_username)\n if \"git_username\" in provided_fields:\n effective_git_username = sanitize_text(payload.git_username)\n\n effective_git_email = sanitize_text(preference.git_email)\n if \"git_email\" in provided_fields:\n effective_git_email = sanitize_text(payload.git_email)\n\n effective_start_page = normalize_start_page(preference.start_page)\n if \"start_page\" in provided_fields:\n effective_start_page = normalize_start_page(payload.start_page)\n\n effective_auto_open_task_drawer = (\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n )\n if \"auto_open_task_drawer\" in provided_fields:\n effective_auto_open_task_drawer = bool(payload.auto_open_task_drawer)\n\n effective_dashboards_table_density = normalize_density(\n preference.dashboards_table_density\n )\n if \"dashboards_table_density\" in provided_fields:\n effective_dashboards_table_density = normalize_density(\n payload.dashboards_table_density\n )\n\n effective_telegram_id = sanitize_text(preference.telegram_id)\n if \"telegram_id\" in provided_fields:\n effective_telegram_id = sanitize_text(payload.telegram_id)\n\n effective_email_address = sanitize_text(preference.email_address)\n if \"email_address\" in provided_fields:\n effective_email_address = sanitize_text(payload.email_address)\n\n effective_notify_on_fail = (\n bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True\n )\n if \"notify_on_fail\" in provided_fields:\n effective_notify_on_fail = bool(payload.notify_on_fail)\n\n validation_errors = validate_update_payload(\n superset_username=effective_superset_username,\n show_only_my_dashboards=effective_show_only,\n git_email=effective_git_email,\n start_page=effective_start_page,\n dashboards_table_density=effective_dashboards_table_density,\n email_address=effective_email_address,\n )\n if validation_errors:\n logger.reflect(\"Validation failed; mutation is denied\")\n raise ProfileValidationError(validation_errors)\n\n preference.superset_username = effective_superset_username\n preference.superset_username_normalized = normalize_username(\n effective_superset_username\n )\n preference.show_only_my_dashboards = effective_show_only\n preference.show_only_slug_dashboards = effective_show_only_slug\n\n preference.git_username = effective_git_username\n preference.git_email = effective_git_email\n\n if \"git_personal_access_token\" in provided_fields:\n sanitized_token = sanitize_secret(\n payload.git_personal_access_token\n )\n if sanitized_token is None:\n preference.git_personal_access_token_encrypted = None\n else:\n preference.git_personal_access_token_encrypted = (\n self.encryption.encrypt(sanitized_token)\n )\n\n preference.start_page = effective_start_page\n preference.auto_open_task_drawer = effective_auto_open_task_drawer\n preference.dashboards_table_density = effective_dashboards_table_density\n preference.telegram_id = effective_telegram_id\n preference.email_address = effective_email_address\n preference.notify_on_fail = effective_notify_on_fail\n preference.updated_at = datetime.utcnow()\n\n persisted_preference = self.auth_repository.save_user_dashboard_preference(\n preference\n )\n\n logger.reason(\"Preference persisted successfully\")\n return ProfilePreferenceResponse(\n status=\"success\",\n message=\"Preference saved\",\n preference=self._to_preference_payload(\n persisted_preference,\n str(current_user.id),\n ),\n security=self.security_badge_service.build_security_summary(current_user),\n )\n # #endregion update_my_preference\n\n # #region _to_preference_payload [TYPE Function]\n # @BRIEF Map ORM preference row to API DTO with token metadata.\n # @PRE preference row can contain nullable optional fields.\n # @POST Returns normalized ProfilePreference object.\n def _to_preference_payload(\n self,\n preference: UserDashboardPreference,\n user_id: str,\n ) -> ProfilePreference:\n encrypted_token = sanitize_text(\n preference.git_personal_access_token_encrypted\n )\n token_masked = None\n if encrypted_token:\n try:\n decrypted_token = self.encryption.decrypt(encrypted_token)\n token_masked = mask_secret_value(decrypted_token)\n except Exception:\n token_masked = \"***\"\n\n created_at = getattr(preference, \"created_at\", None) or datetime.utcnow()\n updated_at = getattr(preference, \"updated_at\", None) or created_at\n\n return ProfilePreference(\n user_id=str(user_id),\n superset_username=sanitize_username(preference.superset_username),\n superset_username_normalized=normalize_username(\n preference.superset_username_normalized\n ),\n show_only_my_dashboards=bool(preference.show_only_my_dashboards),\n show_only_slug_dashboards=(\n bool(preference.show_only_slug_dashboards)\n if preference.show_only_slug_dashboards is not None\n else True\n ),\n git_username=sanitize_text(preference.git_username),\n git_email=sanitize_text(preference.git_email),\n has_git_personal_access_token=bool(encrypted_token),\n git_personal_access_token_masked=token_masked,\n start_page=normalize_start_page(preference.start_page),\n auto_open_task_drawer=(\n bool(preference.auto_open_task_drawer)\n if preference.auto_open_task_drawer is not None\n else True\n ),\n dashboards_table_density=normalize_density(\n preference.dashboards_table_density\n ),\n telegram_id=sanitize_text(preference.telegram_id),\n email_address=sanitize_text(preference.email_address),\n notify_on_fail=bool(preference.notify_on_fail)\n if preference.notify_on_fail is not None\n else True,\n created_at=created_at,\n updated_at=updated_at,\n )\n # #endregion _to_preference_payload\n\n # #region _build_default_preference [C:1] [TYPE Function]\n # @BRIEF Delegate to ProfileUtils.build_default_preference.\n def _build_default_preference(self, user_id: str) -> ProfilePreference:\n return build_default_preference(user_id)\n # #endregion _build_default_preference\n\n # #region _get_preference_row [C:2] [TYPE Function]\n # @BRIEF Return persisted preference row for user or None.\n def _get_preference_row(self, user_id: str) -> UserDashboardPreference | None:\n return self.auth_repository.get_user_dashboard_preference(str(user_id))\n # #endregion _get_preference_row\n\n # #region _get_or_create_preference_row [C:2] [TYPE Function]\n # @BRIEF Return existing preference row or create new unsaved row.\n def _get_or_create_preference_row(self, user_id: str) -> UserDashboardPreference:\n existing = self._get_preference_row(user_id)\n if existing is not None:\n return existing\n return UserDashboardPreference(user_id=str(user_id))\n # #endregion _get_or_create_preference_row\n# #endregion ProfilePreferenceService\n"
},
{
"contract_id": "get_my_preference",
@@ -52224,14 +47402,14 @@
"tier": "TIER_1",
"complexity": 1,
"metadata": {
- "BRIEF": "Delegate to profile[EXT:internal:_utils].build_default_preference.",
+ "BRIEF": "Delegate to ProfileUtils.build_default_preference.",
"COMPLEXITY": 1
},
"relations": [],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": " # #region _build_default_preference [C:1] [TYPE Function]\n # @BRIEF Delegate to profile[EXT:internal:_utils].build_default_preference.\n def _build_default_preference(self, user_id: str) -> ProfilePreference:\n return build_default_preference(user_id)\n # #endregion _build_default_preference\n"
+ "body": " # #region _build_default_preference [C:1] [TYPE Function]\n # @BRIEF Delegate to ProfileUtils.build_default_preference.\n def _build_default_preference(self, user_id: str) -> ProfilePreference:\n return build_default_preference(user_id)\n # #endregion _build_default_preference\n"
},
{
"contract_id": "_get_preference_row",
@@ -52285,7 +47463,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region profile_service [C:5] [TYPE Module] [SEMANTICS sqlalchemy, profile, preference, superset, lookup]\n#\n# @BRIEF Composite facade orchestrating profile preference persistence, Superset account lookup,\n# security badges, and deterministic actor matching by delegating to focused sub-services.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @RELATION DEPENDS_ON -> [ProfilePreferenceResponse]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [AuthRepositoryModule]\n# @RELATION DEPENDS_ON -> [User]\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy.orm.Session]\n# @RELATION DEPENDS_ON -> [ProfilePreferenceService]\n# @RELATION DEPENDS_ON -> [SupersetLookupService]\n# @RELATION DEPENDS_ON -> [SecurityBadgeService]\n# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]\n#\n# @INVARIANT Profile ID needs to be unique per-user session\n#\n# @TEST_CONTRACT ProfilePreferenceUpdateRequest -> ProfilePreferenceResponse\n# @TEST_FIXTURE valid_profile_update -> {\"user_id\":\"u-1\",\"superset_username\":\"John_Doe\",\"show_only_my_dashboards\":true}\n# @TEST_EDGE enable_without_username -> toggle=true with empty username returns validation error\n# @TEST_EDGE cross_user_mutation -> attempt to update another user preference returns forbidden\n# @TEST_EDGE lookup_env_not_found -> unknown environment_id returns not found\n# @TEST_INVARIANT normalization_consistency -> VERIFIED_BY: [valid_profile_update, enable_without_username]\n# @DATA_CONTRACT Profile_id -> ProfileInfo; session_id -> valid UUID\n# @PRE Session is active and valid\n# @POST Profile with updated fields populated and\n# @SIDE_EFFECT Database read/write operations\n# @RATIONALE Decomposed from monolithic 770-line ProfileService into three focused services\n# (ProfilePreferenceService, SupersetLookupService, SecurityBadgeService) plus pure\n# utility functions (profile[EXT:internal:_utils]) to satisfy INV_7. This module is a thin facade\n# that preserves the public API contract for all existing callers.\n# @REJECTED Keeping all three domains in a single ProfileService class was rejected — it violated\n# INV_7 (770 lines vs 150 max), mixed I/O patterns (DB writes + HTTP calls), and created\n# unnecessary coupling between preference persistence and Superset network operations.\n\nfrom collections.abc import Iterable\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ..core.logger import belief_scope, logger\nfrom ..models.auth import User\nfrom ..schemas.profile import (\n ProfilePreferenceResponse,\n ProfilePreferenceUpdateRequest,\n SupersetAccountLookupRequest,\n SupersetAccountLookupResponse,\n)\nfrom .profile_preference_service import ProfilePreferenceService\nfrom .profile[EXT:internal:_utils] import (\n EnvironmentNotFoundError,\n ProfileAuthorizationError,\n ProfileValidationError,\n normalize_owner_tokens,\n normalize_username,\n sanitize_username,\n)\nfrom .security_badge_service import SecurityBadgeService\nfrom .superset_lookup_service import SupersetLookupService\n\n# Re-export exception classes for backward-compatible imports\n__all__ = [\n \"EnvironmentNotFoundError\",\n \"ProfileAuthorizationError\",\n \"ProfilePreferenceService\",\n \"ProfileService\",\n \"ProfileValidationError\",\n \"SecurityBadgeService\",\n \"SupersetLookupService\",\n]\n\n\n# #region ProfileService [C:4] [TYPE Class] [SEMANTICS profile,facade,delegate,coordinator]\n# @BRIEF Facade that composes ProfilePreferenceService, SupersetLookupService, and\n# SecurityBadgeService into a single interface for backward compatibility.\n# @RELATION DEPENDS_ON -> [ProfilePreferenceService]\n# @RELATION DEPENDS_ON -> [SupersetLookupService]\n# @RELATION DEPENDS_ON -> [SecurityBadgeService]\n# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]\n# @PRE Caller provides authenticated User context for external service methods.\n# @POST Delegates to sub-services and returns normalized profile/lookup responses.\n# @SIDE_EFFECT Writes preference records and encrypted tokens; performs external account lookups when requested.\n# @DATA_CONTRACT Input[User,ProfilePreferenceUpdateRequest|SupersetAccountLookupRequest] -> Output[ProfilePreferenceResponse|SupersetAccountLookupResponse|bool]\n# @INVARIANT Profile data integrity maintained, cache consistency with database state\n# @RATIONALE Thin coordinator — all sub-10-line delegating methods. Actual business logic lives\n# in the injected sub-services.\nclass ProfileService:\n \"\"\"Facade composing preference, lookup, and security services.\"\"\"\n\n # region init [TYPE Function]\n # @BRIEF Initialize facade and create sub-services.\n # @PRE db session is active and config_manager supports get_environments().\n # @POST All sub-services are initialized and ready.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.preference_service = ProfilePreferenceService(db, config_manager, plugin_loader)\n self.lookup_service = SupersetLookupService(config_manager)\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n\n # endregion init\n\n # region get_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n return self.preference_service.get_my_preference(current_user)\n\n # endregion get_my_preference\n\n # region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n return self.preference_service.get_dashboard_filter_binding(current_user)\n\n # endregion get_dashboard_filter_binding\n\n # region update_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n return self.preference_service.update_my_preference(\n current_user, payload, target_user_id\n )\n\n # endregion update_my_preference\n\n # region lookup_superset_accounts [TYPE Function]\n # @BRIEF Delegate to SupersetLookupService.\n def lookup_superset_accounts(\n self,\n current_user: User,\n request: SupersetAccountLookupRequest,\n ) -> SupersetAccountLookupResponse:\n return self.lookup_service.lookup_superset_accounts(current_user, request)\n\n # endregion lookup_superset_accounts\n\n # region matches_dashboard_actor [TYPE Function]\n # @BRIEF Apply trim+case-insensitive actor match across owners OR modified_by.\n # @PRE bound_username can be empty; owners may contain mixed payload.\n # @POST Returns True when normalized username matches owners or modified_by.\n def matches_dashboard_actor(\n self,\n bound_username: str | None,\n owners: Iterable[Any] | None,\n modified_by: str | None,\n ) -> bool:\n normalized_actor = normalize_username(bound_username)\n if not normalized_actor:\n return False\n\n owner_tokens = normalize_owner_tokens(owners)\n modified_token = normalize_username(modified_by)\n\n if normalized_actor in owner_tokens:\n return True\n if modified_token and normalized_actor == modified_token:\n return True\n return False\n\n # endregion matches_dashboard_actor\n\n\n# #endregion ProfileService\n\n# #endregion profile_service\n"
+ "body": "# #region profile_service [C:5] [TYPE Module] [SEMANTICS sqlalchemy, profile, preference, superset, lookup]\n#\n# @BRIEF Composite facade orchestrating profile preference persistence, Superset account lookup,\n# security badges, and deterministic actor matching by delegating to focused sub-services.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [UserDashboardPreference]\n# @RELATION DEPENDS_ON -> [ProfilePreferenceResponse]\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [AuthRepositoryModule]\n# @RELATION DEPENDS_ON -> [User]\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy.orm.Session]\n# @RELATION DEPENDS_ON -> [ProfilePreferenceService]\n# @RELATION DEPENDS_ON -> [SupersetLookupService]\n# @RELATION DEPENDS_ON -> [SecurityBadgeService]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n#\n# @INVARIANT Profile ID needs to be unique per-user session\n#\n# @TEST_CONTRACT ProfilePreferenceUpdateRequest -> ProfilePreferenceResponse\n# @TEST_FIXTURE valid_profile_update -> {\"user_id\":\"u-1\",\"superset_username\":\"John_Doe\",\"show_only_my_dashboards\":true}\n# @TEST_EDGE enable_without_username -> toggle=true with empty username returns validation error\n# @TEST_EDGE cross_user_mutation -> attempt to update another user preference returns forbidden\n# @TEST_EDGE lookup_env_not_found -> unknown environment_id returns not found\n# @TEST_INVARIANT normalization_consistency -> VERIFIED_BY: [valid_profile_update, enable_without_username]\n# @DATA_CONTRACT Profile_id -> ProfileInfo; session_id -> valid UUID\n# @PRE Session is active and valid\n# @POST Profile with updated fields populated and\n# @SIDE_EFFECT Database read/write operations\n# @RATIONALE Decomposed from monolithic 770-line ProfileService into three focused services\n# (ProfilePreferenceService, SupersetLookupService, SecurityBadgeService) plus pure\n# utility functions (ProfileUtils) to satisfy INV_7. This module is a thin facade\n# that preserves the public API contract for all existing callers.\n# @REJECTED Keeping all three domains in a single ProfileService class was rejected — it violated\n# INV_7 (770 lines vs 150 max), mixed I/O patterns (DB writes + HTTP calls), and created\n# unnecessary coupling between preference persistence and Superset network operations.\n\nfrom collections.abc import Iterable\nfrom typing import Any\n\nfrom sqlalchemy.orm import Session\n\nfrom ..core.logger import belief_scope, logger\nfrom ..models.auth import User\nfrom ..schemas.profile import (\n ProfilePreferenceResponse,\n ProfilePreferenceUpdateRequest,\n SupersetAccountLookupRequest,\n SupersetAccountLookupResponse,\n)\nfrom .profile_preference_service import ProfilePreferenceService\nfrom .profile_utils import (\n EnvironmentNotFoundError,\n ProfileAuthorizationError,\n ProfileValidationError,\n normalize_owner_tokens,\n normalize_username,\n sanitize_username,\n)\nfrom .security_badge_service import SecurityBadgeService\nfrom .superset_lookup_service import SupersetLookupService\n\n# Re-export exception classes for backward-compatible imports\n__all__ = [\n \"EnvironmentNotFoundError\",\n \"ProfileAuthorizationError\",\n \"ProfilePreferenceService\",\n \"ProfileService\",\n \"ProfileValidationError\",\n \"SecurityBadgeService\",\n \"SupersetLookupService\",\n]\n\n\n# #region ProfileService [C:4] [TYPE Class] [SEMANTICS profile,facade,delegate,coordinator]\n# @BRIEF Facade that composes ProfilePreferenceService, SupersetLookupService, and\n# SecurityBadgeService into a single interface for backward compatibility.\n# @RELATION DEPENDS_ON -> [ProfilePreferenceService]\n# @RELATION DEPENDS_ON -> [SupersetLookupService]\n# @RELATION DEPENDS_ON -> [SecurityBadgeService]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @PRE Caller provides authenticated User context for external service methods.\n# @POST Delegates to sub-services and returns normalized profile/lookup responses.\n# @SIDE_EFFECT Writes preference records and encrypted tokens; performs external account lookups when requested.\n# @DATA_CONTRACT Input[User,ProfilePreferenceUpdateRequest|SupersetAccountLookupRequest] -> Output[ProfilePreferenceResponse|SupersetAccountLookupResponse|bool]\n# @INVARIANT Profile data integrity maintained, cache consistency with database state\n# @RATIONALE Thin coordinator — all sub-10-line delegating methods. Actual business logic lives\n# in the injected sub-services.\nclass ProfileService:\n \"\"\"Facade composing preference, lookup, and security services.\"\"\"\n\n # region init [TYPE Function]\n # @BRIEF Initialize facade and create sub-services.\n # @PRE db session is active and config_manager supports get_environments().\n # @POST All sub-services are initialized and ready.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.preference_service = ProfilePreferenceService(db, config_manager, plugin_loader)\n self.lookup_service = SupersetLookupService(config_manager)\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n\n # endregion init\n\n # region get_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n return self.preference_service.get_my_preference(current_user)\n\n # endregion get_my_preference\n\n # region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n return self.preference_service.get_dashboard_filter_binding(current_user)\n\n # endregion get_dashboard_filter_binding\n\n # region update_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n return self.preference_service.update_my_preference(\n current_user, payload, target_user_id\n )\n\n # endregion update_my_preference\n\n # region lookup_superset_accounts [TYPE Function]\n # @BRIEF Delegate to SupersetLookupService.\n def lookup_superset_accounts(\n self,\n current_user: User,\n request: SupersetAccountLookupRequest,\n ) -> SupersetAccountLookupResponse:\n return self.lookup_service.lookup_superset_accounts(current_user, request)\n\n # endregion lookup_superset_accounts\n\n # region matches_dashboard_actor [TYPE Function]\n # @BRIEF Apply trim+case-insensitive actor match across owners OR modified_by.\n # @PRE bound_username can be empty; owners may contain mixed payload.\n # @POST Returns True when normalized username matches owners or modified_by.\n def matches_dashboard_actor(\n self,\n bound_username: str | None,\n owners: Iterable[Any] | None,\n modified_by: str | None,\n ) -> bool:\n normalized_actor = normalize_username(bound_username)\n if not normalized_actor:\n return False\n\n owner_tokens = normalize_owner_tokens(owners)\n modified_token = normalize_username(modified_by)\n\n if normalized_actor in owner_tokens:\n return True\n if modified_token and normalized_actor == modified_token:\n return True\n return False\n\n # endregion matches_dashboard_actor\n\n\n# #endregion ProfileService\n\n# #endregion profile_service\n"
},
{
"contract_id": "ProfileService",
@@ -52303,10 +47481,10 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region ProfileService [C:4] [TYPE Class] [SEMANTICS profile,facade,delegate,coordinator]\n# @BRIEF Facade that composes ProfilePreferenceService, SupersetLookupService, and\n# SecurityBadgeService into a single interface for backward compatibility.\n# @RELATION DEPENDS_ON -> [ProfilePreferenceService]\n# @RELATION DEPENDS_ON -> [SupersetLookupService]\n# @RELATION DEPENDS_ON -> [SecurityBadgeService]\n# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]\n# @PRE Caller provides authenticated User context for external service methods.\n# @POST Delegates to sub-services and returns normalized profile/lookup responses.\n# @SIDE_EFFECT Writes preference records and encrypted tokens; performs external account lookups when requested.\n# @DATA_CONTRACT Input[User,ProfilePreferenceUpdateRequest|SupersetAccountLookupRequest] -> Output[ProfilePreferenceResponse|SupersetAccountLookupResponse|bool]\n# @INVARIANT Profile data integrity maintained, cache consistency with database state\n# @RATIONALE Thin coordinator — all sub-10-line delegating methods. Actual business logic lives\n# in the injected sub-services.\nclass ProfileService:\n \"\"\"Facade composing preference, lookup, and security services.\"\"\"\n\n # region init [TYPE Function]\n # @BRIEF Initialize facade and create sub-services.\n # @PRE db session is active and config_manager supports get_environments().\n # @POST All sub-services are initialized and ready.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.preference_service = ProfilePreferenceService(db, config_manager, plugin_loader)\n self.lookup_service = SupersetLookupService(config_manager)\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n\n # endregion init\n\n # region get_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n return self.preference_service.get_my_preference(current_user)\n\n # endregion get_my_preference\n\n # region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n return self.preference_service.get_dashboard_filter_binding(current_user)\n\n # endregion get_dashboard_filter_binding\n\n # region update_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n return self.preference_service.update_my_preference(\n current_user, payload, target_user_id\n )\n\n # endregion update_my_preference\n\n # region lookup_superset_accounts [TYPE Function]\n # @BRIEF Delegate to SupersetLookupService.\n def lookup_superset_accounts(\n self,\n current_user: User,\n request: SupersetAccountLookupRequest,\n ) -> SupersetAccountLookupResponse:\n return self.lookup_service.lookup_superset_accounts(current_user, request)\n\n # endregion lookup_superset_accounts\n\n # region matches_dashboard_actor [TYPE Function]\n # @BRIEF Apply trim+case-insensitive actor match across owners OR modified_by.\n # @PRE bound_username can be empty; owners may contain mixed payload.\n # @POST Returns True when normalized username matches owners or modified_by.\n def matches_dashboard_actor(\n self,\n bound_username: str | None,\n owners: Iterable[Any] | None,\n modified_by: str | None,\n ) -> bool:\n normalized_actor = normalize_username(bound_username)\n if not normalized_actor:\n return False\n\n owner_tokens = normalize_owner_tokens(owners)\n modified_token = normalize_username(modified_by)\n\n if normalized_actor in owner_tokens:\n return True\n if modified_token and normalized_actor == modified_token:\n return True\n return False\n\n # endregion matches_dashboard_actor\n\n\n# #endregion ProfileService\n"
+ "body": "# #region ProfileService [C:4] [TYPE Class] [SEMANTICS profile,facade,delegate,coordinator]\n# @BRIEF Facade that composes ProfilePreferenceService, SupersetLookupService, and\n# SecurityBadgeService into a single interface for backward compatibility.\n# @RELATION DEPENDS_ON -> [ProfilePreferenceService]\n# @RELATION DEPENDS_ON -> [SupersetLookupService]\n# @RELATION DEPENDS_ON -> [SecurityBadgeService]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @PRE Caller provides authenticated User context for external service methods.\n# @POST Delegates to sub-services and returns normalized profile/lookup responses.\n# @SIDE_EFFECT Writes preference records and encrypted tokens; performs external account lookups when requested.\n# @DATA_CONTRACT Input[User,ProfilePreferenceUpdateRequest|SupersetAccountLookupRequest] -> Output[ProfilePreferenceResponse|SupersetAccountLookupResponse|bool]\n# @INVARIANT Profile data integrity maintained, cache consistency with database state\n# @RATIONALE Thin coordinator — all sub-10-line delegating methods. Actual business logic lives\n# in the injected sub-services.\nclass ProfileService:\n \"\"\"Facade composing preference, lookup, and security services.\"\"\"\n\n # region init [TYPE Function]\n # @BRIEF Initialize facade and create sub-services.\n # @PRE db session is active and config_manager supports get_environments().\n # @POST All sub-services are initialized and ready.\n def __init__(self, db: Session, config_manager: Any, plugin_loader: Any = None):\n self.preference_service = ProfilePreferenceService(db, config_manager, plugin_loader)\n self.lookup_service = SupersetLookupService(config_manager)\n self.security_badge_service = SecurityBadgeService(plugin_loader)\n self.db = db\n self.config_manager = config_manager\n self.plugin_loader = plugin_loader\n\n # endregion init\n\n # region get_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_my_preference(self, current_user: User) -> ProfilePreferenceResponse:\n return self.preference_service.get_my_preference(current_user)\n\n # endregion get_my_preference\n\n # region get_dashboard_filter_binding [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def get_dashboard_filter_binding(self, current_user: User) -> dict:\n return self.preference_service.get_dashboard_filter_binding(current_user)\n\n # endregion get_dashboard_filter_binding\n\n # region update_my_preference [TYPE Function]\n # @BRIEF Delegate to ProfilePreferenceService.\n def update_my_preference(\n self,\n current_user: User,\n payload: ProfilePreferenceUpdateRequest,\n target_user_id: str | None = None,\n ) -> ProfilePreferenceResponse:\n return self.preference_service.update_my_preference(\n current_user, payload, target_user_id\n )\n\n # endregion update_my_preference\n\n # region lookup_superset_accounts [TYPE Function]\n # @BRIEF Delegate to SupersetLookupService.\n def lookup_superset_accounts(\n self,\n current_user: User,\n request: SupersetAccountLookupRequest,\n ) -> SupersetAccountLookupResponse:\n return self.lookup_service.lookup_superset_accounts(current_user, request)\n\n # endregion lookup_superset_accounts\n\n # region matches_dashboard_actor [TYPE Function]\n # @BRIEF Apply trim+case-insensitive actor match across owners OR modified_by.\n # @PRE bound_username can be empty; owners may contain mixed payload.\n # @POST Returns True when normalized username matches owners or modified_by.\n def matches_dashboard_actor(\n self,\n bound_username: str | None,\n owners: Iterable[Any] | None,\n modified_by: str | None,\n ) -> bool:\n normalized_actor = normalize_username(bound_username)\n if not normalized_actor:\n return False\n\n owner_tokens = normalize_owner_tokens(owners)\n modified_token = normalize_username(modified_by)\n\n if normalized_actor in owner_tokens:\n return True\n if modified_token and normalized_actor == modified_token:\n return True\n return False\n\n # endregion matches_dashboard_actor\n\n\n# #endregion ProfileService\n"
},
{
- "contract_id": "profile[EXT:internal:_utils]",
+ "contract_id": "ProfileUtils",
"contract_type": "Module",
"file_path": "backend/src/services/profile_utils.py",
"start_line": 1,
@@ -52321,7 +47499,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region profile[EXT:internal:_utils] [C:2] [TYPE Module] [SEMANTICS string,normalization,utility,sanitize]\n# @BRIEF Pure utility helpers for profile data sanitization, normalization, and secret masking.\n# Also contains shared exception classes to avoid circular imports between profile sub-modules.\n# @LAYER Domain\n# @RATIONALE Extracted from ProfileService to satisfy INV_7 — module length under 400 lines,\n# contract length under 150 lines. These are stateless pure functions that do not\n# require a class or service container.\n# @REJECTED Keeping these as private methods on ProfileService was rejected because they\n# inflate the class beyond 150 lines and mix pure computation with I/O-bound\n# service logic.\n\nfrom collections.abc import Iterable, Sequence\nfrom datetime import datetime\nfrom typing import Any\n\n\n# #region ProfileValidationError [C:2] [TYPE Class]\n# @RELATION INHERITS -> [EXT:Python:Exception]\n# @BRIEF Domain validation error for profile preference update requests.\nclass ProfileValidationError(Exception):\n def __init__(self, errors: Sequence[str]):\n self.errors = list(errors)\n super().__init__(\"Profile preference validation failed\")\n# #endregion ProfileValidationError\n\n\n# #region EnvironmentNotFoundError [C:2] [TYPE Class]\n# @RELATION INHERITS -> [EXT:Python:Exception]\n# @BRIEF Raised when environment_id from lookup request is unknown in app configuration.\nclass EnvironmentNotFoundError(Exception):\n pass\n# #endregion EnvironmentNotFoundError\n\n\n# #region ProfileAuthorizationError [C:2] [TYPE Class]\n# @RELATION INHERITS -> [EXT:Python:Exception]\n# @BRIEF Raised when caller attempts cross-user preference mutation.\nclass ProfileAuthorizationError(Exception):\n pass\n# #endregion ProfileAuthorizationError\n\nSUPPORTED_START_PAGES: set[str] = {\"dashboards\", \"datasets\", \"reports\"}\nSUPPORTED_DENSITIES: set[str] = {\"compact\", \"comfortable\"}\n\n\n# #region sanitize_text [C:1] [TYPE Function]\n# @BRIEF Normalize optional text into trimmed form or None.\ndef sanitize_text(value: str | None) -> str | None:\n normalized = str(value or \"\").strip()\n if not normalized:\n return None\n return normalized\n# #endregion sanitize_text\n\n\n# #region sanitize_secret [C:1] [TYPE Function]\n# @BRIEF Normalize secret input into trimmed form or None.\ndef sanitize_secret(value: str | None) -> str | None:\n if value is None:\n return None\n normalized = str(value).strip()\n if not normalized:\n return None\n return normalized\n# #endregion sanitize_secret\n\n\n# #region sanitize_username [C:1] [TYPE Function]\n# @BRIEF Normalize raw username into trimmed form or None for empty input.\ndef sanitize_username(value: str | None) -> str | None:\n return sanitize_text(value)\n# #endregion sanitize_username\n\n\n# #region normalize_username [C:1] [TYPE Function]\n# @BRIEF Apply deterministic trim+lower normalization for actor matching.\ndef normalize_username(value: str | None) -> str | None:\n sanitized = sanitize_username(value)\n if sanitized is None:\n return None\n return sanitized.lower()\n# #endregion normalize_username\n\n\n# #region normalize_start_page [C:1] [TYPE Function]\n# @BRIEF Normalize supported start page aliases to canonical values.\ndef normalize_start_page(value: str | None) -> str:\n normalized = str(value or \"\").strip().lower()\n if normalized == \"reports-logs\":\n return \"reports\"\n if normalized in SUPPORTED_START_PAGES:\n return normalized\n return \"dashboards\"\n# #endregion normalize_start_page\n\n\n# #region normalize_density [C:1] [TYPE Function]\n# @BRIEF Normalize supported density aliases to canonical values.\ndef normalize_density(value: str | None) -> str:\n normalized = str(value or \"\").strip().lower()\n if normalized == \"free\":\n return \"comfortable\"\n if normalized in SUPPORTED_DENSITIES:\n return normalized\n return \"comfortable\"\n# #endregion normalize_density\n\n\n# #region mask_secret_value [C:1] [TYPE Function]\n# @BRIEF Build a safe display value for sensitive secrets.\ndef mask_secret_value(secret: str | None) -> str | None:\n sanitized = sanitize_secret(secret)\n if sanitized is None:\n return None\n if len(sanitized) <= 4:\n return \"***\"\n return f\"{sanitized[:2]}***{sanitized[-2:]}\"\n# #endregion mask_secret_value\n\n\n# #region validate_update_payload [C:2] [TYPE Function]\n# @BRIEF Validate username/toggle constraints for preference mutation.\n# @RELATION CALLS -> [sanitize_username]\n# @RELATION CALLS -> [sanitize_text]\n# @RELATION DEPENDS_ON -> [EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES]\n# @RELATION DEPENDS_ON -> [EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES]\n# @POST Returns validation errors list; empty list means valid.\ndef validate_update_payload(\n superset_username: str | None,\n show_only_my_dashboards: bool,\n git_email: str | None,\n start_page: str,\n dashboards_table_density: str,\n email_address: str | None = None,\n) -> list[str]:\n errors: list[str] = []\n sanitized_username = sanitize_username(superset_username)\n\n if sanitized_username and any(ch.isspace() for ch in sanitized_username):\n errors.append(\n \"Username should not contain spaces. Please enter a valid Apache Superset username.\"\n )\n if show_only_my_dashboards and not sanitized_username:\n errors.append(\n \"Superset username is required when default filter is enabled.\"\n )\n\n sanitized_git_email = sanitize_text(git_email)\n if sanitized_git_email:\n if (\n \" \" in sanitized_git_email\n or \"@\" not in sanitized_git_email\n or sanitized_git_email.startswith(\"@\")\n or sanitized_git_email.endswith(\"@\")\n ):\n errors.append(\"Git email should be a valid email address.\")\n\n if start_page not in SUPPORTED_START_PAGES:\n errors.append(\"Start page value is not supported.\")\n\n if dashboards_table_density not in SUPPORTED_DENSITIES:\n errors.append(\"Dashboards table density value is not supported.\")\n\n sanitized_email = sanitize_text(email_address)\n if sanitized_email:\n if (\n \" \" in sanitized_email\n or \"@\" not in sanitized_email\n or sanitized_email.startswith(\"@\")\n or sanitized_email.endswith(\"@\")\n ):\n errors.append(\"Notification email should be a valid email address.\")\n\n return errors\n# #endregion validate_update_payload\n\n\n# #region build_default_preference [C:2] [TYPE Function] [SEMANTICS preference,default,unconfigured]\n# @BRIEF Build non-persisted default preference DTO for unconfigured users.\n# @RELATION DEPENDS_ON -> [ProfilePreference]\ndef build_default_preference(user_id: str) -> Any:\n \"\"\"Build default ProfilePreference with disabled toggles and empty usernames.\"\"\"\n from ..schemas.profile import ProfilePreference\n now = datetime.utcnow()\n return ProfilePreference(\n user_id=str(user_id),\n superset_username=None,\n superset_username_normalized=None,\n show_only_my_dashboards=False,\n show_only_slug_dashboards=True,\n git_username=None,\n git_email=None,\n has_git_personal_access_token=False,\n git_personal_access_token_masked=None,\n start_page=\"dashboards\",\n auto_open_task_drawer=True,\n dashboards_table_density=\"comfortable\",\n telegram_id=None,\n email_address=None,\n notify_on_fail=True,\n created_at=now,\n updated_at=now,\n )\n# #endregion build_default_preference\n\n\n# #region normalize_owner_tokens [C:2] [TYPE Function]\n# @BRIEF Normalize owners payload into deduplicated lower-cased tokens.\n# @RELATION CALLS -> [normalize_username]\ndef normalize_owner_tokens(owners: Iterable[Any] | None) -> list[str]:\n if owners is None:\n return []\n normalized: list[str] = []\n for owner in owners:\n owner_candidates: list[Any]\n if isinstance(owner, dict):\n first_name = sanitize_username(str(owner.get(\"first_name\") or \"\"))\n last_name = sanitize_username(str(owner.get(\"last_name\") or \"\"))\n full_name = \" \".join(\n part for part in [first_name, last_name] if part\n ).strip()\n snake_name = \"_\".join(\n part for part in [first_name, last_name] if part\n ).strip(\"_\")\n owner_candidates = [\n owner.get(\"username\"),\n owner.get(\"user_name\"),\n owner.get(\"name\"),\n owner.get(\"full_name\"),\n first_name,\n last_name,\n full_name or None,\n snake_name or None,\n owner.get(\"email\"),\n ]\n else:\n owner_candidates = [owner]\n\n for candidate in owner_candidates:\n token = normalize_username(str(candidate or \"\"))\n if token and token not in normalized:\n normalized.append(token)\n return normalized\n# #endregion normalize_owner_tokens\n# #endregion profile[EXT:internal:_utils]\n"
+ "body": "# #region ProfileUtils [C:2] [TYPE Module] [SEMANTICS string,normalization,utility,sanitize]\n# @BRIEF Pure utility helpers for profile data sanitization, normalization, and secret masking.\n# Also contains shared exception classes to avoid circular imports between profile sub-modules.\n# @LAYER Domain\n# @RATIONALE Extracted from ProfileService to satisfy INV_7 — module length under 400 lines,\n# contract length under 150 lines. These are stateless pure functions that do not\n# require a class or service container.\n# @REJECTED Keeping these as private methods on ProfileService was rejected because they\n# inflate the class beyond 150 lines and mix pure computation with I/O-bound\n# service logic.\n\nfrom collections.abc import Iterable, Sequence\nfrom datetime import datetime\nfrom typing import Any\n\n\n# #region ProfileValidationError [C:2] [TYPE Class]\n# @RELATION INHERITS -> [EXT:Python:Exception]\n# @BRIEF Domain validation error for profile preference update requests.\nclass ProfileValidationError(Exception):\n def __init__(self, errors: Sequence[str]):\n self.errors = list(errors)\n super().__init__(\"Profile preference validation failed\")\n# #endregion ProfileValidationError\n\n\n# #region EnvironmentNotFoundError [C:2] [TYPE Class]\n# @RELATION INHERITS -> [EXT:Python:Exception]\n# @BRIEF Raised when environment_id from lookup request is unknown in app configuration.\nclass EnvironmentNotFoundError(Exception):\n pass\n# #endregion EnvironmentNotFoundError\n\n\n# #region ProfileAuthorizationError [C:2] [TYPE Class]\n# @RELATION INHERITS -> [EXT:Python:Exception]\n# @BRIEF Raised when caller attempts cross-user preference mutation.\nclass ProfileAuthorizationError(Exception):\n pass\n# #endregion ProfileAuthorizationError\n\nSUPPORTED_START_PAGES: set[str] = {\"dashboards\", \"datasets\", \"reports\"}\nSUPPORTED_DENSITIES: set[str] = {\"compact\", \"comfortable\"}\n\n\n# #region sanitize_text [C:1] [TYPE Function]\n# @BRIEF Normalize optional text into trimmed form or None.\ndef sanitize_text(value: str | None) -> str | None:\n normalized = str(value or \"\").strip()\n if not normalized:\n return None\n return normalized\n# #endregion sanitize_text\n\n\n# #region sanitize_secret [C:1] [TYPE Function]\n# @BRIEF Normalize secret input into trimmed form or None.\ndef sanitize_secret(value: str | None) -> str | None:\n if value is None:\n return None\n normalized = str(value).strip()\n if not normalized:\n return None\n return normalized\n# #endregion sanitize_secret\n\n\n# #region sanitize_username [C:1] [TYPE Function]\n# @BRIEF Normalize raw username into trimmed form or None for empty input.\ndef sanitize_username(value: str | None) -> str | None:\n return sanitize_text(value)\n# #endregion sanitize_username\n\n\n# #region normalize_username [C:1] [TYPE Function]\n# @BRIEF Apply deterministic trim+lower normalization for actor matching.\ndef normalize_username(value: str | None) -> str | None:\n sanitized = sanitize_username(value)\n if sanitized is None:\n return None\n return sanitized.lower()\n# #endregion normalize_username\n\n\n# #region normalize_start_page [C:1] [TYPE Function]\n# @BRIEF Normalize supported start page aliases to canonical values.\ndef normalize_start_page(value: str | None) -> str:\n normalized = str(value or \"\").strip().lower()\n if normalized == \"reports-logs\":\n return \"reports\"\n if normalized in SUPPORTED_START_PAGES:\n return normalized\n return \"dashboards\"\n# #endregion normalize_start_page\n\n\n# #region normalize_density [C:1] [TYPE Function]\n# @BRIEF Normalize supported density aliases to canonical values.\ndef normalize_density(value: str | None) -> str:\n normalized = str(value or \"\").strip().lower()\n if normalized == \"free\":\n return \"comfortable\"\n if normalized in SUPPORTED_DENSITIES:\n return normalized\n return \"comfortable\"\n# #endregion normalize_density\n\n\n# #region mask_secret_value [C:1] [TYPE Function]\n# @BRIEF Build a safe display value for sensitive secrets.\ndef mask_secret_value(secret: str | None) -> str | None:\n sanitized = sanitize_secret(secret)\n if sanitized is None:\n return None\n if len(sanitized) <= 4:\n return \"***\"\n return f\"{sanitized[:2]}***{sanitized[-2:]}\"\n# #endregion mask_secret_value\n\n\n# #region validate_update_payload [C:2] [TYPE Function]\n# @BRIEF Validate username/toggle constraints for preference mutation.\n# @RELATION CALLS -> [sanitize_username]\n# @RELATION CALLS -> [sanitize_text]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @POST Returns validation errors list; empty list means valid.\ndef validate_update_payload(\n superset_username: str | None,\n show_only_my_dashboards: bool,\n git_email: str | None,\n start_page: str,\n dashboards_table_density: str,\n email_address: str | None = None,\n) -> list[str]:\n errors: list[str] = []\n sanitized_username = sanitize_username(superset_username)\n\n if sanitized_username and any(ch.isspace() for ch in sanitized_username):\n errors.append(\n \"Username should not contain spaces. Please enter a valid Apache Superset username.\"\n )\n if show_only_my_dashboards and not sanitized_username:\n errors.append(\n \"Superset username is required when default filter is enabled.\"\n )\n\n sanitized_git_email = sanitize_text(git_email)\n if sanitized_git_email:\n if (\n \" \" in sanitized_git_email\n or \"@\" not in sanitized_git_email\n or sanitized_git_email.startswith(\"@\")\n or sanitized_git_email.endswith(\"@\")\n ):\n errors.append(\"Git email should be a valid email address.\")\n\n if start_page not in SUPPORTED_START_PAGES:\n errors.append(\"Start page value is not supported.\")\n\n if dashboards_table_density not in SUPPORTED_DENSITIES:\n errors.append(\"Dashboards table density value is not supported.\")\n\n sanitized_email = sanitize_text(email_address)\n if sanitized_email:\n if (\n \" \" in sanitized_email\n or \"@\" not in sanitized_email\n or sanitized_email.startswith(\"@\")\n or sanitized_email.endswith(\"@\")\n ):\n errors.append(\"Notification email should be a valid email address.\")\n\n return errors\n# #endregion validate_update_payload\n\n\n# #region build_default_preference [C:2] [TYPE Function] [SEMANTICS preference,default,unconfigured]\n# @BRIEF Build non-persisted default preference DTO for unconfigured users.\n# @RELATION DEPENDS_ON -> [ProfilePreference]\ndef build_default_preference(user_id: str) -> Any:\n \"\"\"Build default ProfilePreference with disabled toggles and empty usernames.\"\"\"\n from ..schemas.profile import ProfilePreference\n now = datetime.utcnow()\n return ProfilePreference(\n user_id=str(user_id),\n superset_username=None,\n superset_username_normalized=None,\n show_only_my_dashboards=False,\n show_only_slug_dashboards=True,\n git_username=None,\n git_email=None,\n has_git_personal_access_token=False,\n git_personal_access_token_masked=None,\n start_page=\"dashboards\",\n auto_open_task_drawer=True,\n dashboards_table_density=\"comfortable\",\n telegram_id=None,\n email_address=None,\n notify_on_fail=True,\n created_at=now,\n updated_at=now,\n )\n# #endregion build_default_preference\n\n\n# #region normalize_owner_tokens [C:2] [TYPE Function]\n# @BRIEF Normalize owners payload into deduplicated lower-cased tokens.\n# @RELATION CALLS -> [normalize_username]\ndef normalize_owner_tokens(owners: Iterable[Any] | None) -> list[str]:\n if owners is None:\n return []\n normalized: list[str] = []\n for owner in owners:\n owner_candidates: list[Any]\n if isinstance(owner, dict):\n first_name = sanitize_username(str(owner.get(\"first_name\") or \"\"))\n last_name = sanitize_username(str(owner.get(\"last_name\") or \"\"))\n full_name = \" \".join(\n part for part in [first_name, last_name] if part\n ).strip()\n snake_name = \"_\".join(\n part for part in [first_name, last_name] if part\n ).strip(\"_\")\n owner_candidates = [\n owner.get(\"username\"),\n owner.get(\"user_name\"),\n owner.get(\"name\"),\n owner.get(\"full_name\"),\n first_name,\n last_name,\n full_name or None,\n snake_name or None,\n owner.get(\"email\"),\n ]\n else:\n owner_candidates = [owner]\n\n for candidate in owner_candidates:\n token = normalize_username(str(candidate or \"\"))\n if token and token not in normalized:\n normalized.append(token)\n return normalized\n# #endregion normalize_owner_tokens\n# #endregion ProfileUtils\n"
},
{
"contract_id": "ProfileValidationError",
@@ -52553,20 +47731,20 @@
{
"source_id": "validate_update_payload",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES",
- "target_ref": "[EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES]"
+ "target_id": "ProfileUtils",
+ "target_ref": "[ProfileUtils]"
},
{
"source_id": "validate_update_payload",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES",
- "target_ref": "[EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES]"
+ "target_id": "ProfileUtils",
+ "target_ref": "[ProfileUtils]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region validate_update_payload [C:2] [TYPE Function]\n# @BRIEF Validate username/toggle constraints for preference mutation.\n# @RELATION CALLS -> [sanitize_username]\n# @RELATION CALLS -> [sanitize_text]\n# @RELATION DEPENDS_ON -> [EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES]\n# @RELATION DEPENDS_ON -> [EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES]\n# @POST Returns validation errors list; empty list means valid.\ndef validate_update_payload(\n superset_username: str | None,\n show_only_my_dashboards: bool,\n git_email: str | None,\n start_page: str,\n dashboards_table_density: str,\n email_address: str | None = None,\n) -> list[str]:\n errors: list[str] = []\n sanitized_username = sanitize_username(superset_username)\n\n if sanitized_username and any(ch.isspace() for ch in sanitized_username):\n errors.append(\n \"Username should not contain spaces. Please enter a valid Apache Superset username.\"\n )\n if show_only_my_dashboards and not sanitized_username:\n errors.append(\n \"Superset username is required when default filter is enabled.\"\n )\n\n sanitized_git_email = sanitize_text(git_email)\n if sanitized_git_email:\n if (\n \" \" in sanitized_git_email\n or \"@\" not in sanitized_git_email\n or sanitized_git_email.startswith(\"@\")\n or sanitized_git_email.endswith(\"@\")\n ):\n errors.append(\"Git email should be a valid email address.\")\n\n if start_page not in SUPPORTED_START_PAGES:\n errors.append(\"Start page value is not supported.\")\n\n if dashboards_table_density not in SUPPORTED_DENSITIES:\n errors.append(\"Dashboards table density value is not supported.\")\n\n sanitized_email = sanitize_text(email_address)\n if sanitized_email:\n if (\n \" \" in sanitized_email\n or \"@\" not in sanitized_email\n or sanitized_email.startswith(\"@\")\n or sanitized_email.endswith(\"@\")\n ):\n errors.append(\"Notification email should be a valid email address.\")\n\n return errors\n# #endregion validate_update_payload\n"
+ "body": "# #region validate_update_payload [C:2] [TYPE Function]\n# @BRIEF Validate username/toggle constraints for preference mutation.\n# @RELATION CALLS -> [sanitize_username]\n# @RELATION CALLS -> [sanitize_text]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @POST Returns validation errors list; empty list means valid.\ndef validate_update_payload(\n superset_username: str | None,\n show_only_my_dashboards: bool,\n git_email: str | None,\n start_page: str,\n dashboards_table_density: str,\n email_address: str | None = None,\n) -> list[str]:\n errors: list[str] = []\n sanitized_username = sanitize_username(superset_username)\n\n if sanitized_username and any(ch.isspace() for ch in sanitized_username):\n errors.append(\n \"Username should not contain spaces. Please enter a valid Apache Superset username.\"\n )\n if show_only_my_dashboards and not sanitized_username:\n errors.append(\n \"Superset username is required when default filter is enabled.\"\n )\n\n sanitized_git_email = sanitize_text(git_email)\n if sanitized_git_email:\n if (\n \" \" in sanitized_git_email\n or \"@\" not in sanitized_git_email\n or sanitized_git_email.startswith(\"@\")\n or sanitized_git_email.endswith(\"@\")\n ):\n errors.append(\"Git email should be a valid email address.\")\n\n if start_page not in SUPPORTED_START_PAGES:\n errors.append(\"Start page value is not supported.\")\n\n if dashboards_table_density not in SUPPORTED_DENSITIES:\n errors.append(\"Dashboards table density value is not supported.\")\n\n sanitized_email = sanitize_text(email_address)\n if sanitized_email:\n if (\n \" \" in sanitized_email\n or \"@\" not in sanitized_email\n or sanitized_email.startswith(\"@\")\n or sanitized_email.endswith(\"@\")\n ):\n errors.append(\"Notification email should be a valid email address.\")\n\n return errors\n# #endregion validate_update_payload\n"
},
{
"contract_id": "build_default_preference",
@@ -53244,7 +48422,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region security_badge_service [C:4] [TYPE Module] [SEMANTICS profile,security,permissions,badges]\n# @BRIEF Builds security summary and permission badges for profile UI — role extraction,\n# permission pair collection, and catalog formatting.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [User]\n# @RELATION DEPENDS_ON -> [discover_declared_permissions]\n# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]\n# @RATIONALE Extracted from ProfileService to satisfy INV_7. Security badge construction\n# is a distinct concern with its own dependencies (discover_declared_permissions,\n# plugin_loader) and can be tested independently.\n# @REJECTED Keeping security badge logic inside ProfileService was rejected — it adds\n# plugin_loader coupling to preference operations that do not need it and\n# inflates the class past 150 lines.\n# @PRE Plugin loader may be None; user must have roles/permissions graph.\n# @POST Returns deterministic security projection for profile UI with sorted permissions.\n# @SIDE_EFFECT Reads plugin permissions via discover_declared_permissions when plugin_loader is set.\n\nfrom typing import Any\n\nfrom ..core.logger import belief_scope, logger\nfrom ..models.auth import User\nfrom ..schemas.profile import ProfilePermissionState, ProfileSecuritySummary\nfrom .profile[EXT:internal:_utils] import sanitize_text\nfrom .rbac_permission_catalog import discover_declared_permissions\n\n\n# #region SecurityBadgeService [C:4] [TYPE Class] [SEMANTICS security,permission,badge,profile]\n# @BRIEF Builds security summary with role names and permission badges for profile UI display.\n# @RELATION DEPENDS_ON -> [User]\n# @RELATION CALLS -> [discover_declared_permissions]\n# @PRE plugin_loader may be None for degraded permission discovery.\n# @POST build_security_summary returns ProfileSecuritySummary with deterministic sorted permissions.\nclass SecurityBadgeService:\n \"\"\"Builds security summary with role names and permission badges.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize service with optional plugin loader for permission discovery.\n def __init__(self, plugin_loader: Any = None):\n self.plugin_loader = plugin_loader\n # #endregion __init__\n\n # #region build_security_summary [TYPE Function]\n # @BRIEF Build read-only security snapshot with role and permission badges.\n # @PRE current_user is authenticated.\n # @POST Returns deterministic security projection for profile UI.\n def build_security_summary(self, current_user: User) -> ProfileSecuritySummary:\n with belief_scope(\"SecurityBadgeService.build_security_summary\"):\n role_names_set: set[str] = set()\n roles = getattr(current_user, \"roles\", []) or []\n for role in roles:\n normalized_role_name = sanitize_text(getattr(role, \"name\", None))\n if normalized_role_name:\n role_names_set.add(normalized_role_name)\n role_names = sorted(role_names_set)\n\n is_admin = any(str(role_name).lower() == \"admin\" for role_name in role_names)\n user_permission_pairs = self._collect_user_permission_pairs(current_user)\n\n declared_permission_pairs: set[tuple[str, str]] = set()\n try:\n discovered_permissions = discover_declared_permissions(\n plugin_loader=self.plugin_loader\n )\n for resource, action in discovered_permissions:\n normalized_resource = sanitize_text(resource)\n normalized_action = str(action or \"\").strip().upper()\n if normalized_resource and normalized_action:\n declared_permission_pairs.add(\n (normalized_resource, normalized_action)\n )\n except Exception as discovery_error:\n logger.explore(\n \"Failed to build declared permission catalog\",\n extra={\"error\": str(discovery_error), \"src\": \"SecurityBadgeService.build_security_summary\"},\n )\n\n if not declared_permission_pairs:\n declared_permission_pairs = set(user_permission_pairs)\n\n sorted_permission_pairs = sorted(\n declared_permission_pairs,\n key=lambda pair: (pair[0], pair[1]),\n )\n permission_states = [\n ProfilePermissionState(\n key=self._format_permission_key(resource, action),\n allowed=bool(is_admin or (resource, action) in user_permission_pairs),\n )\n for resource, action in sorted_permission_pairs\n ]\n\n auth_source = sanitize_text(getattr(current_user, \"auth_source\", None))\n current_role = \"Admin\" if is_admin else (role_names[0] if role_names else None)\n\n return ProfileSecuritySummary(\n read_only=True,\n auth_source=auth_source,\n current_role=current_role,\n role_source=auth_source,\n roles=role_names,\n permissions=permission_states,\n )\n # #endregion build_security_summary\n\n # #region _collect_user_permission_pairs [TYPE Function]\n # @BRIEF Collect effective permission tuples from current user's roles.\n # @PRE current_user can include role/permission graph.\n # @POST Returns unique normalized (resource, ACTION) tuples.\n def _collect_user_permission_pairs(\n self, current_user: User\n ) -> set[tuple[str, str]]:\n collected: set[tuple[str, str]] = set()\n roles = getattr(current_user, \"roles\", []) or []\n for role in roles:\n permissions = getattr(role, \"permissions\", []) or []\n for permission in permissions:\n resource = sanitize_text(getattr(permission, \"resource\", None))\n action = str(getattr(permission, \"action\", \"\") or \"\").strip().upper()\n if resource and action:\n collected.add((resource, action))\n return collected\n # #endregion _collect_user_permission_pairs\n\n # #region _format_permission_key [C:1] [TYPE Function]\n # @BRIEF Convert normalized permission pair to compact UI key.\n def _format_permission_key(self, resource: str, action: str) -> str:\n normalized_resource = sanitize_text(resource) or \"\"\n normalized_action = str(action or \"\").strip().upper()\n if normalized_action == \"READ\":\n return normalized_resource\n return f\"{normalized_resource}:{normalized_action.lower()}\"\n # #endregion _format_permission_key\n# #endregion SecurityBadgeService\n# #endregion security_badge_service\n"
+ "body": "# #region security_badge_service [C:4] [TYPE Module] [SEMANTICS profile,security,permissions,badges]\n# @BRIEF Builds security summary and permission badges for profile UI — role extraction,\n# permission pair collection, and catalog formatting.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [User]\n# @RELATION DEPENDS_ON -> [discover_declared_permissions]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @RATIONALE Extracted from ProfileService to satisfy INV_7. Security badge construction\n# is a distinct concern with its own dependencies (discover_declared_permissions,\n# plugin_loader) and can be tested independently.\n# @REJECTED Keeping security badge logic inside ProfileService was rejected — it adds\n# plugin_loader coupling to preference operations that do not need it and\n# inflates the class past 150 lines.\n# @PRE Plugin loader may be None; user must have roles/permissions graph.\n# @POST Returns deterministic security projection for profile UI with sorted permissions.\n# @SIDE_EFFECT Reads plugin permissions via discover_declared_permissions when plugin_loader is set.\n\nfrom typing import Any\n\nfrom ..core.logger import belief_scope, logger\nfrom ..models.auth import User\nfrom ..schemas.profile import ProfilePermissionState, ProfileSecuritySummary\nfrom .profile_utils import sanitize_text\nfrom .rbac_permission_catalog import discover_declared_permissions\n\n\n# #region SecurityBadgeService [C:4] [TYPE Class] [SEMANTICS security,permission,badge,profile]\n# @BRIEF Builds security summary with role names and permission badges for profile UI display.\n# @RELATION DEPENDS_ON -> [User]\n# @RELATION CALLS -> [discover_declared_permissions]\n# @PRE plugin_loader may be None for degraded permission discovery.\n# @POST build_security_summary returns ProfileSecuritySummary with deterministic sorted permissions.\nclass SecurityBadgeService:\n \"\"\"Builds security summary with role names and permission badges.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize service with optional plugin loader for permission discovery.\n def __init__(self, plugin_loader: Any = None):\n self.plugin_loader = plugin_loader\n # #endregion __init__\n\n # #region build_security_summary [TYPE Function]\n # @BRIEF Build read-only security snapshot with role and permission badges.\n # @PRE current_user is authenticated.\n # @POST Returns deterministic security projection for profile UI.\n def build_security_summary(self, current_user: User) -> ProfileSecuritySummary:\n with belief_scope(\"SecurityBadgeService.build_security_summary\"):\n role_names_set: set[str] = set()\n roles = getattr(current_user, \"roles\", []) or []\n for role in roles:\n normalized_role_name = sanitize_text(getattr(role, \"name\", None))\n if normalized_role_name:\n role_names_set.add(normalized_role_name)\n role_names = sorted(role_names_set)\n\n is_admin = any(str(role_name).lower() == \"admin\" for role_name in role_names)\n user_permission_pairs = self._collect_user_permission_pairs(current_user)\n\n declared_permission_pairs: set[tuple[str, str]] = set()\n try:\n discovered_permissions = discover_declared_permissions(\n plugin_loader=self.plugin_loader\n )\n for resource, action in discovered_permissions:\n normalized_resource = sanitize_text(resource)\n normalized_action = str(action or \"\").strip().upper()\n if normalized_resource and normalized_action:\n declared_permission_pairs.add(\n (normalized_resource, normalized_action)\n )\n except Exception as discovery_error:\n logger.explore(\n \"Failed to build declared permission catalog\",\n extra={\"error\": str(discovery_error), \"src\": \"SecurityBadgeService.build_security_summary\"},\n )\n\n if not declared_permission_pairs:\n declared_permission_pairs = set(user_permission_pairs)\n\n sorted_permission_pairs = sorted(\n declared_permission_pairs,\n key=lambda pair: (pair[0], pair[1]),\n )\n permission_states = [\n ProfilePermissionState(\n key=self._format_permission_key(resource, action),\n allowed=bool(is_admin or (resource, action) in user_permission_pairs),\n )\n for resource, action in sorted_permission_pairs\n ]\n\n auth_source = sanitize_text(getattr(current_user, \"auth_source\", None))\n current_role = \"Admin\" if is_admin else (role_names[0] if role_names else None)\n\n return ProfileSecuritySummary(\n read_only=True,\n auth_source=auth_source,\n current_role=current_role,\n role_source=auth_source,\n roles=role_names,\n permissions=permission_states,\n )\n # #endregion build_security_summary\n\n # #region _collect_user_permission_pairs [TYPE Function]\n # @BRIEF Collect effective permission tuples from current user's roles.\n # @PRE current_user can include role/permission graph.\n # @POST Returns unique normalized (resource, ACTION) tuples.\n def _collect_user_permission_pairs(\n self, current_user: User\n ) -> set[tuple[str, str]]:\n collected: set[tuple[str, str]] = set()\n roles = getattr(current_user, \"roles\", []) or []\n for role in roles:\n permissions = getattr(role, \"permissions\", []) or []\n for permission in permissions:\n resource = sanitize_text(getattr(permission, \"resource\", None))\n action = str(getattr(permission, \"action\", \"\") or \"\").strip().upper()\n if resource and action:\n collected.add((resource, action))\n return collected\n # #endregion _collect_user_permission_pairs\n\n # #region _format_permission_key [C:1] [TYPE Function]\n # @BRIEF Convert normalized permission pair to compact UI key.\n def _format_permission_key(self, resource: str, action: str) -> str:\n normalized_resource = sanitize_text(resource) or \"\"\n normalized_action = str(action or \"\").strip().upper()\n if normalized_action == \"READ\":\n return normalized_resource\n return f\"{normalized_resource}:{normalized_action.lower()}\"\n # #endregion _format_permission_key\n# #endregion SecurityBadgeService\n# #endregion security_badge_service\n"
},
{
"contract_id": "SecurityBadgeService",
@@ -53351,7 +48529,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region SqlTableExtractorModule [C:2] [TYPE Module] [SEMANTICS sql, jinja, table, extraction, parsing]\n# @BRIEF Three-phase SQL+Jinja table name extractor for virtual datasets as per FR-003.\n# Phase 1: Detect Jinja spans vs SQL spans\n# Phase 2: In Jinja spans, extract \"schema.table\" from string values\n# Phase 3: In SQL spans, regex pattern + sqlparse filter to reject string literal false positives\n# @LAYER Service\n# @RELATION DEPENDS_ON -> [[EXT:internal:re_sqlparse]]\n# @INVARIANT Only exact schema.table matches (case-insensitive); unqualified references are NOT matched.\n# @INVARIANT Returns a set[str] of fully-qualified table names (lowercased for case-insensitive matching).\n\nimport re\nfrom typing import Iterable\n\nimport sqlparse\nfrom sqlparse.sql import Identifier, Parenthesis, Token, TokenList\nfrom sqlparse.tokens import Literal, Name, Punctuation, Whitespace\n\n# ── Phase 1: Jinja span detection ───────────────────────────\n\n# Minimal Jinja token detection: {% ... %}, {{ ... }}, {# ... #}\n_JINJA_BLOCK_RE = re.compile(r\"{%-?\\s*.*?\\s*-?%}\", re.DOTALL)\n_JINJA_EXPR_RE = re.compile(r\"{{-?\\s*.*?\\s*-?}}\", re.DOTALL)\n_JINJA_COMMENT_RE = re.compile(r\"{#.*?#}\", re.DOTALL)\n\n# ── Phase 3: schema.table regex (case-insensitive) ───────────\n_SCHEMA_TABLE_RE = re.compile(\n r\"\"\"\n (? list[tuple[str, str]]:\n \"\"\"Split raw SQL+Jinja text into alternating Jinja and SQL spans.\n\n Phase 1 detects Jinja blocks ({%%}, {{}}, {##}) and returns the\n remaining text as SQL spans.\n \"\"\"\n if not raw_sql or not raw_sql.strip():\n return [(\"sql\", raw_sql or \"\")]\n\n spans: list[tuple[str, str]] = []\n # Collect all Jinja match positions\n jinja_matches: list[tuple[int, int]] = []\n for pattern in (_JINJA_BLOCK_RE, _JINJA_EXPR_RE, _JINJA_COMMENT_RE):\n for m in pattern.finditer(raw_sql):\n jinja_matches.append((m.start(), m.end()))\n\n # Merge overlapping Jinja spans\n if jinja_matches:\n jinja_matches.sort()\n merged: list[tuple[int, int]] = [jinja_matches[0]]\n for start, end in jinja_matches[1:]:\n if start <= merged[-1][1]:\n merged[-1] = (merged[-1][0], max(merged[-1][1], end))\n else:\n merged.append((start, end))\n\n # Build alternating sql/jinja spans\n cursor = 0\n for start, end in merged:\n if cursor < start:\n sql_chunk = raw_sql[cursor:start].strip()\n if sql_chunk:\n spans.append((\"sql\", sql_chunk))\n jinja_chunk = raw_sql[start:end].strip()\n if jinja_chunk:\n spans.append((\"jinja\", jinja_chunk))\n cursor = end\n if cursor < len(raw_sql):\n remaining = raw_sql[cursor:].strip()\n if remaining:\n spans.append((\"sql\", remaining))\n else:\n spans.append((\"sql\", raw_sql.strip()))\n\n return spans\n# #endregion detect_jinja_spans\n\n\n# #region extract_tables_from_jinja [C:2] [TYPE Function]\n# @BRIEF Phase 2: Extract \"schema.table\" references from Jinja string values.\n# Looks for patterns like \"raw.sales\" inside Jinja text.\n# @PRE jinja_text is a string from a Jinja span.\n# @POST Returns a set of lowercased schema.table strings.\ndef extract_tables_from_jinja(jinja_text: str) -> set[str]:\n \"\"\"Extract ``schema.table`` references from within Jinja template blocks.\n\n Looks for double-quoted or single-quoted string values that match\n the ``schema.table`` pattern, e.g. ``\"raw.sales\"`` or ``'raw.inventory'``.\n \"\"\"\n tables: set[str] = set()\n # Match string values: \"schema.table\" or 'schema.table'\n string_pattern = re.compile(\n r\"\"\"[\"']([a-zA-Z_][\\w]*\\.[a-zA-Z_][\\w]*)[\"']\"\"\"\n )\n for m in string_pattern.finditer(jinja_text):\n tables.add(m.group(1).lower())\n return tables\n# #endregion extract_tables_from_jinja\n\n\n# #region is_string_literal [C:1] [TYPE Function]\n# @BRIEF Check if a sqlparse Token is a string literal (not a schema.table identifier).\n# @PRE token is a sqlparse Token.\n# @POST Returns True if the token is a string/Single/Literal.String.\ndef is_string_literal(token: Token) -> bool:\n \"\"\"Return True if token is a string literal type in sqlparse.\"\"\"\n return token.ttype is Literal.String.Single or token.ttype is Literal.String\n# #endregion is_string_literal\n\n\n# #region extract_tables_from_sql_span [C:2] [TYPE Function]\n# @BRIEF Phase 3: Extract schema.table references from SQL text using regex + sqlparse filtering.\n# Uses regex to find all schema.table candidates, then sqlparse to filter out\n# false positives inside string literals.\n# @PRE sql_text is a string from a SQL span (non-Jinja).\n# @POST Returns a set of lowercased schema.table strings.\ndef extract_tables_from_sql_span(sql_text: str) -> set[str]:\n \"\"\"Extract ``schema.table`` references from plain SQL text.\n\n Uses regex to find all ``schema.table`` candidates, then sqlparse\n to reject matches that fall inside string literals.\n \"\"\"\n tables: set[str] = set()\n raw_matches = _SCHEMA_TABLE_RE.findall(sql_text)\n if not raw_matches:\n return tables\n\n # Use sqlparse to identify string literal positions\n parsed = sqlparse.parse(sql_text)\n string_literal_ranges: list[tuple[int, int]] = []\n\n def walk_tokens(tokens: Iterable[Token], base_offset: int = 0) -> None:\n offset = base_offset\n for token in tokens:\n if isinstance(token, TokenList):\n walk_tokens(token.flatten(), offset)\n else:\n ttype = token.ttype\n val = token.value\n if is_string_literal(token):\n string_literal_ranges.append(\n (offset, offset + len(val))\n )\n offset += len(val)\n\n for stmt in parsed:\n if stmt is None:\n continue\n walk_tokens(stmt.flatten(), base_offset=0)\n\n def is_in_string(pos: int) -> bool:\n for s_start, s_end in string_literal_ranges:\n if s_start <= pos <= s_end:\n return True\n return False\n\n # Re-scan with full match positions to filter\n for m in _SCHEMA_TABLE_RE.finditer(sql_text):\n if not is_in_string(m.start()):\n # Extract schema and table from match groups\n schema = m.group(2) or m.group(1) or \"\"\n table = m.group(3) or \"\"\n # Filter out column aliases (single-char schemas like \"a.id\", \"o.id\")\n if len(schema) < 2 and schema.isalpha() and schema.islower():\n continue\n if schema and table:\n tables.add(f\"{schema.lower()}.{table.lower()}\")\n\n return tables\n# #endregion extract_tables_from_sql_span\n\n\n# #region extract_tables_from_sql [C:2] [TYPE Function]\n# @BRIEF Three-phase entry point: extract all schema.table references from raw SQL+Jinja text.\n# @PRE raw_sql is a string (possibly empty).\n# @POST Returns a set of lowercased fully-qualified table names (schema.table format).\n# @RELATION CALLS -> [detect_jinja_spans]\n# @RELATION CALLS -> [extract_tables_from_jinja]\n# @RELATION CALLS -> [extract_tables_from_sql_span]\ndef extract_tables_from_sql(raw_sql: str) -> set[str]:\n \"\"\"Extract all ``schema.table`` references from raw SQL + Jinja text.\n\n Three-phase approach per FR-003:\n 1. Detect Jinja spans vs SQL spans\n 2. In Jinja spans, extract ``schema.table`` from quoted string values\n 3. In SQL spans, regex + sqlparse filter to reject string literal false positives\n\n Returns a set of lowercased ``schema.table`` strings for case-insensitive matching.\n\n Example:\n >>> extract_tables_from_sql(\"SELECT * FROM raw.sales JOIN raw.inventory ON ...\")\n {'raw.sales', 'raw.inventory'}\n \"\"\"\n if not raw_sql or not raw_sql.strip():\n return set()\n\n all_tables: set[str] = set()\n spans = detect_jinja_spans(raw_sql)\n\n for span_type, text in spans:\n if span_type == \"jinja\":\n all_tables.update(extract_tables_from_jinja(text))\n else:\n all_tables.update(extract_tables_from_sql_span(text))\n\n return all_tables\n# #endregion extract_tables_from_sql\n\n# #endregion SqlTableExtractorModule\n"
+ "body": "# #region SqlTableExtractorModule [C:2] [TYPE Module] [SEMANTICS sql, jinja, table, extraction, parsing]\n# @BRIEF Three-phase SQL+Jinja table name extractor for virtual datasets as per FR-003.\n# Phase 1: Detect Jinja spans vs SQL spans\n# Phase 2: In Jinja spans, extract \"schema.table\" from string values\n# Phase 3: In SQL spans, regex pattern + sqlparse filter to reject string literal false positives\n# @LAYER Service\n# @RELATION DEPENDS_ON -> [EXT:Library:sqlparse]\n# @INVARIANT Only exact schema.table matches (case-insensitive); unqualified references are NOT matched.\n# @INVARIANT Returns a set[str] of fully-qualified table names (lowercased for case-insensitive matching).\n\nimport re\nfrom typing import Iterable\n\nimport sqlparse\nfrom sqlparse.sql import Identifier, Parenthesis, Token, TokenList\nfrom sqlparse.tokens import Literal, Name, Punctuation, Whitespace\n\n# ── Phase 1: Jinja span detection ───────────────────────────\n\n# Minimal Jinja token detection: {% ... %}, {{ ... }}, {# ... #}\n_JINJA_BLOCK_RE = re.compile(r\"{%-?\\s*.*?\\s*-?%}\", re.DOTALL)\n_JINJA_EXPR_RE = re.compile(r\"{{-?\\s*.*?\\s*-?}}\", re.DOTALL)\n_JINJA_COMMENT_RE = re.compile(r\"{#.*?#}\", re.DOTALL)\n\n# ── Phase 3: schema.table regex (case-insensitive) ───────────\n_SCHEMA_TABLE_RE = re.compile(\n r\"\"\"\n (? list[tuple[str, str]]:\n \"\"\"Split raw SQL+Jinja text into alternating Jinja and SQL spans.\n\n Phase 1 detects Jinja blocks ({%%}, {{}}, {##}) and returns the\n remaining text as SQL spans.\n \"\"\"\n if not raw_sql or not raw_sql.strip():\n return [(\"sql\", raw_sql or \"\")]\n\n spans: list[tuple[str, str]] = []\n # Collect all Jinja match positions\n jinja_matches: list[tuple[int, int]] = []\n for pattern in (_JINJA_BLOCK_RE, _JINJA_EXPR_RE, _JINJA_COMMENT_RE):\n for m in pattern.finditer(raw_sql):\n jinja_matches.append((m.start(), m.end()))\n\n # Merge overlapping Jinja spans\n if jinja_matches:\n jinja_matches.sort()\n merged: list[tuple[int, int]] = [jinja_matches[0]]\n for start, end in jinja_matches[1:]:\n if start <= merged[-1][1]:\n merged[-1] = (merged[-1][0], max(merged[-1][1], end))\n else:\n merged.append((start, end))\n\n # Build alternating sql/jinja spans\n cursor = 0\n for start, end in merged:\n if cursor < start:\n sql_chunk = raw_sql[cursor:start].strip()\n if sql_chunk:\n spans.append((\"sql\", sql_chunk))\n jinja_chunk = raw_sql[start:end].strip()\n if jinja_chunk:\n spans.append((\"jinja\", jinja_chunk))\n cursor = end\n if cursor < len(raw_sql):\n remaining = raw_sql[cursor:].strip()\n if remaining:\n spans.append((\"sql\", remaining))\n else:\n spans.append((\"sql\", raw_sql.strip()))\n\n return spans\n# #endregion detect_jinja_spans\n\n\n# #region extract_tables_from_jinja [C:2] [TYPE Function]\n# @BRIEF Phase 2: Extract \"schema.table\" references from Jinja string values.\n# Looks for patterns like \"raw.sales\" inside Jinja text.\n# @PRE jinja_text is a string from a Jinja span.\n# @POST Returns a set of lowercased schema.table strings.\ndef extract_tables_from_jinja(jinja_text: str) -> set[str]:\n \"\"\"Extract ``schema.table`` references from within Jinja template blocks.\n\n Looks for double-quoted or single-quoted string values that match\n the ``schema.table`` pattern, e.g. ``\"raw.sales\"`` or ``'raw.inventory'``.\n \"\"\"\n tables: set[str] = set()\n # Match string values: \"schema.table\" or 'schema.table'\n string_pattern = re.compile(\n r\"\"\"[\"']([a-zA-Z_][\\w]*\\.[a-zA-Z_][\\w]*)[\"']\"\"\"\n )\n for m in string_pattern.finditer(jinja_text):\n tables.add(m.group(1).lower())\n return tables\n# #endregion extract_tables_from_jinja\n\n\n# #region is_string_literal [C:1] [TYPE Function]\n# @BRIEF Check if a sqlparse Token is a string literal (not a schema.table identifier).\n# @PRE token is a sqlparse Token.\n# @POST Returns True if the token is a string/Single/Literal.String.\ndef is_string_literal(token: Token) -> bool:\n \"\"\"Return True if token is a string literal type in sqlparse.\"\"\"\n return token.ttype is Literal.String.Single or token.ttype is Literal.String\n# #endregion is_string_literal\n\n\n# #region extract_tables_from_sql_span [C:2] [TYPE Function]\n# @BRIEF Phase 3: Extract schema.table references from SQL text using regex + sqlparse filtering.\n# Uses regex to find all schema.table candidates, then sqlparse to filter out\n# false positives inside string literals.\n# @PRE sql_text is a string from a SQL span (non-Jinja).\n# @POST Returns a set of lowercased schema.table strings.\ndef extract_tables_from_sql_span(sql_text: str) -> set[str]:\n \"\"\"Extract ``schema.table`` references from plain SQL text.\n\n Uses regex to find all ``schema.table`` candidates, then sqlparse\n to reject matches that fall inside string literals.\n \"\"\"\n tables: set[str] = set()\n raw_matches = _SCHEMA_TABLE_RE.findall(sql_text)\n if not raw_matches:\n return tables\n\n # Use sqlparse to identify string literal positions\n parsed = sqlparse.parse(sql_text)\n string_literal_ranges: list[tuple[int, int]] = []\n\n def walk_tokens(tokens: Iterable[Token], base_offset: int = 0) -> None:\n offset = base_offset\n for token in tokens:\n if isinstance(token, TokenList):\n walk_tokens(token.flatten(), offset)\n else:\n ttype = token.ttype\n val = token.value\n if is_string_literal(token):\n string_literal_ranges.append(\n (offset, offset + len(val))\n )\n offset += len(val)\n\n for stmt in parsed:\n if stmt is None:\n continue\n walk_tokens(stmt.flatten(), base_offset=0)\n\n def is_in_string(pos: int) -> bool:\n for s_start, s_end in string_literal_ranges:\n if s_start <= pos <= s_end:\n return True\n return False\n\n # Re-scan with full match positions to filter\n for m in _SCHEMA_TABLE_RE.finditer(sql_text):\n if not is_in_string(m.start()):\n # Extract schema and table from match groups\n schema = m.group(2) or m.group(1) or \"\"\n table = m.group(3) or \"\"\n # Filter out column aliases (single-char schemas like \"a.id\", \"o.id\")\n if len(schema) < 2 and schema.isalpha() and schema.islower():\n continue\n if schema and table:\n tables.add(f\"{schema.lower()}.{table.lower()}\")\n\n return tables\n# #endregion extract_tables_from_sql_span\n\n\n# #region extract_tables_from_sql [C:2] [TYPE Function]\n# @BRIEF Three-phase entry point: extract all schema.table references from raw SQL+Jinja text.\n# @PRE raw_sql is a string (possibly empty).\n# @POST Returns a set of lowercased fully-qualified table names (schema.table format).\n# @RELATION CALLS -> [detect_jinja_spans]\n# @RELATION CALLS -> [extract_tables_from_jinja]\n# @RELATION CALLS -> [extract_tables_from_sql_span]\ndef extract_tables_from_sql(raw_sql: str) -> set[str]:\n \"\"\"Extract all ``schema.table`` references from raw SQL + Jinja text.\n\n Three-phase approach per FR-003:\n 1. Detect Jinja spans vs SQL spans\n 2. In Jinja spans, extract ``schema.table`` from quoted string values\n 3. In SQL spans, regex + sqlparse filter to reject string literal false positives\n\n Returns a set of lowercased ``schema.table`` strings for case-insensitive matching.\n\n Example:\n >>> extract_tables_from_sql(\"SELECT * FROM raw.sales JOIN raw.inventory ON ...\")\n {'raw.sales', 'raw.inventory'}\n \"\"\"\n if not raw_sql or not raw_sql.strip():\n return set()\n\n all_tables: set[str] = set()\n spans = detect_jinja_spans(raw_sql)\n\n for span_type, text in spans:\n if span_type == \"jinja\":\n all_tables.update(extract_tables_from_jinja(text))\n else:\n all_tables.update(extract_tables_from_sql_span(text))\n\n return all_tables\n# #endregion extract_tables_from_sql\n\n# #endregion SqlTableExtractorModule\n"
},
{
"contract_id": "detect_jinja_spans",
@@ -53498,14 +48676,14 @@
{
"source_id": "superset_lookup_service",
"relation_type": "DEPENDS_ON",
- "target_id": "profile[EXT:internal:_utils]",
- "target_ref": "[profile[EXT:internal:_utils]]"
+ "target_id": "ProfileUtils",
+ "target_ref": "[ProfileUtils]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region superset_lookup_service [C:4] [TYPE Module] [SEMANTICS superset,account,lookup,environment]\n# @BRIEF Environment-scoped Superset account lookup with degradation fallback for network failures.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetAccountLookupAdapter]\n# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]\n# @RATIONALE Extracted from ProfileService to satisfy INV_7. Superset account lookup has distinct\n# I/O patterns (external HTTP calls, environment resolution) that isolate cleanly from\n# preference persistence and security badge logic.\n# @REJECTED Keeping lookup inside ProfileService was rejected — it adds network I/O and\n# environment coupling to preference operations that only need DB access, and inflates\n# the class past 150 lines.\n# @PRE current_user is authenticated; environment_id must be resolvable.\n# @POST Returns success or degraded SupersetAccountLookupResponse with stable shape.\n# @SIDE_EFFECT Performs external Superset HTTP calls via SupersetClient + adapter.\n# @RAISES EnvironmentNotFoundError when environment_id is unknown.\n\nfrom typing import Any\n\nfrom ..core.logger import belief_scope, logger\nfrom ..core.superset_client import SupersetClient\nfrom ..core.superset_profile_lookup import SupersetAccountLookupAdapter\nfrom ..schemas.profile import (\n SupersetAccountCandidate,\n SupersetAccountLookupRequest,\n SupersetAccountLookupResponse,\n)\nfrom .profile[EXT:internal:_utils] import EnvironmentNotFoundError\n\n\n# #region SupersetLookupService [C:4] [TYPE Class] [SEMANTICS superset,lookup,environment,degradation]\n# @BRIEF Resolves environments and queries Superset users in selected environment,\n# returning canonical account candidates with degradation fallback.\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetAccountLookupAdapter]\n# @RELATION CALLS -> [SupersetClient]\n# @PRE config_manager supports get_environments().\n# @POST lookup_superset_accounts returns success payload or degraded payload with warning.\nclass SupersetLookupService:\n \"\"\"Environment-scoped Superset account lookup with degradation fallback.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize with config manager for environment resolution.\n def __init__(self, config_manager: Any):\n self.config_manager = config_manager\n # #endregion __init__\n\n # #region lookup_superset_accounts [TYPE Function]\n # @BRIEF Query Superset users in selected environment and project canonical account candidates.\n # @PRE current_user is authenticated and environment_id exists.\n # @POST Returns success payload or degraded payload with warning while preserving manual fallback.\n def lookup_superset_accounts(\n self,\n current_user: Any,\n request: SupersetAccountLookupRequest,\n ) -> SupersetAccountLookupResponse:\n with belief_scope(\n \"SupersetLookupService.lookup_superset_accounts\",\n f\"user_id={getattr(current_user, 'id', '?')}, environment_id={request.environment_id}\",\n ):\n environment = self._resolve_environment(request.environment_id)\n if environment is None:\n logger.explore(\"Lookup aborted: environment not found\")\n raise EnvironmentNotFoundError(\n f\"Environment '{request.environment_id}' not found\"\n )\n\n sort_column = str(request.sort_column or \"username\").strip().lower()\n sort_order = str(request.sort_order or \"desc\").strip().lower()\n allowed_columns = {\"username\", \"first_name\", \"last_name\", \"email\"}\n if sort_column not in allowed_columns:\n sort_column = \"username\"\n if sort_order not in {\"asc\", \"desc\"}:\n sort_order = \"desc\"\n\n logger.reflect(\n \"Normalized lookup request \"\n f\"(env={request.environment_id}, sort_column={sort_column}, sort_order={sort_order}, \"\n f\"page_index={request.page_index}, page_size={request.page_size}, \"\n f\"search={(request.search or '').strip()!r})\"\n )\n\n try:\n logger.reason(\"Performing Superset account lookup\")\n superset_client = SupersetClient(environment)\n adapter = SupersetAccountLookupAdapter(\n network_client=superset_client.network,\n environment_id=request.environment_id,\n )\n lookup_result = adapter.get_users_page(\n search=request.search,\n page_index=request.page_index,\n page_size=request.page_size,\n sort_column=sort_column,\n sort_order=sort_order,\n )\n items = [\n SupersetAccountCandidate.model_validate(item)\n for item in lookup_result.get(\"items\", [])\n ]\n return SupersetAccountLookupResponse(\n status=\"success\",\n environment_id=request.environment_id,\n page_index=request.page_index,\n page_size=request.page_size,\n total=max(int(lookup_result.get(\"total\", len(items))), 0),\n warning=None,\n items=items,\n )\n except Exception as exc:\n logger.explore(\n f\"Lookup degraded due to upstream error: {exc}\"\n )\n return SupersetAccountLookupResponse(\n status=\"degraded\",\n environment_id=request.environment_id,\n page_index=request.page_index,\n page_size=request.page_size,\n total=0,\n warning=(\n \"Cannot load Superset accounts for this environment right now. \"\n \"You can enter username manually.\"\n ),\n items=[],\n )\n # #endregion lookup_superset_accounts\n\n # #region _resolve_environment [C:2] [TYPE Function]\n # @BRIEF Resolve environment model from configured environments by id.\n # @PRE environment_id is provided.\n # @POST Returns environment object when found else None.\n def _resolve_environment(self, environment_id: str):\n environments = self.config_manager.get_environments()\n for env in environments:\n if str(getattr(env, \"id\", \"\")) == str(environment_id):\n return env\n return None\n # #endregion _resolve_environment\n# #endregion SupersetLookupService\n# #endregion superset_lookup_service\n"
+ "body": "# #region superset_lookup_service [C:4] [TYPE Module] [SEMANTICS superset,account,lookup,environment]\n# @BRIEF Environment-scoped Superset account lookup with degradation fallback for network failures.\n# @LAYER Domain\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetAccountLookupAdapter]\n# @RELATION DEPENDS_ON -> [ProfileUtils]\n# @RATIONALE Extracted from ProfileService to satisfy INV_7. Superset account lookup has distinct\n# I/O patterns (external HTTP calls, environment resolution) that isolate cleanly from\n# preference persistence and security badge logic.\n# @REJECTED Keeping lookup inside ProfileService was rejected — it adds network I/O and\n# environment coupling to preference operations that only need DB access, and inflates\n# the class past 150 lines.\n# @PRE current_user is authenticated; environment_id must be resolvable.\n# @POST Returns success or degraded SupersetAccountLookupResponse with stable shape.\n# @SIDE_EFFECT Performs external Superset HTTP calls via SupersetClient + adapter.\n# @RAISES EnvironmentNotFoundError when environment_id is unknown.\n\nfrom typing import Any\n\nfrom ..core.logger import belief_scope, logger\nfrom ..core.superset_client import SupersetClient\nfrom ..core.superset_profile_lookup import SupersetAccountLookupAdapter\nfrom ..schemas.profile import (\n SupersetAccountCandidate,\n SupersetAccountLookupRequest,\n SupersetAccountLookupResponse,\n)\nfrom .profile_utils import EnvironmentNotFoundError\n\n\n# #region SupersetLookupService [C:4] [TYPE Class] [SEMANTICS superset,lookup,environment,degradation]\n# @BRIEF Resolves environments and queries Superset users in selected environment,\n# returning canonical account candidates with degradation fallback.\n# @RELATION DEPENDS_ON -> [SupersetClient]\n# @RELATION DEPENDS_ON -> [SupersetAccountLookupAdapter]\n# @RELATION CALLS -> [SupersetClient]\n# @PRE config_manager supports get_environments().\n# @POST lookup_superset_accounts returns success payload or degraded payload with warning.\nclass SupersetLookupService:\n \"\"\"Environment-scoped Superset account lookup with degradation fallback.\"\"\"\n\n # #region __init__ [TYPE Function]\n # @BRIEF Initialize with config manager for environment resolution.\n def __init__(self, config_manager: Any):\n self.config_manager = config_manager\n # #endregion __init__\n\n # #region lookup_superset_accounts [TYPE Function]\n # @BRIEF Query Superset users in selected environment and project canonical account candidates.\n # @PRE current_user is authenticated and environment_id exists.\n # @POST Returns success payload or degraded payload with warning while preserving manual fallback.\n def lookup_superset_accounts(\n self,\n current_user: Any,\n request: SupersetAccountLookupRequest,\n ) -> SupersetAccountLookupResponse:\n with belief_scope(\n \"SupersetLookupService.lookup_superset_accounts\",\n f\"user_id={getattr(current_user, 'id', '?')}, environment_id={request.environment_id}\",\n ):\n environment = self._resolve_environment(request.environment_id)\n if environment is None:\n logger.explore(\"Lookup aborted: environment not found\")\n raise EnvironmentNotFoundError(\n f\"Environment '{request.environment_id}' not found\"\n )\n\n sort_column = str(request.sort_column or \"username\").strip().lower()\n sort_order = str(request.sort_order or \"desc\").strip().lower()\n allowed_columns = {\"username\", \"first_name\", \"last_name\", \"email\"}\n if sort_column not in allowed_columns:\n sort_column = \"username\"\n if sort_order not in {\"asc\", \"desc\"}:\n sort_order = \"desc\"\n\n logger.reflect(\n \"Normalized lookup request \"\n f\"(env={request.environment_id}, sort_column={sort_column}, sort_order={sort_order}, \"\n f\"page_index={request.page_index}, page_size={request.page_size}, \"\n f\"search={(request.search or '').strip()!r})\"\n )\n\n try:\n logger.reason(\"Performing Superset account lookup\")\n superset_client = SupersetClient(environment)\n adapter = SupersetAccountLookupAdapter(\n network_client=superset_client.network,\n environment_id=request.environment_id,\n )\n lookup_result = adapter.get_users_page(\n search=request.search,\n page_index=request.page_index,\n page_size=request.page_size,\n sort_column=sort_column,\n sort_order=sort_order,\n )\n items = [\n SupersetAccountCandidate.model_validate(item)\n for item in lookup_result.get(\"items\", [])\n ]\n return SupersetAccountLookupResponse(\n status=\"success\",\n environment_id=request.environment_id,\n page_index=request.page_index,\n page_size=request.page_size,\n total=max(int(lookup_result.get(\"total\", len(items))), 0),\n warning=None,\n items=items,\n )\n except Exception as exc:\n logger.explore(\n f\"Lookup degraded due to upstream error: {exc}\"\n )\n return SupersetAccountLookupResponse(\n status=\"degraded\",\n environment_id=request.environment_id,\n page_index=request.page_index,\n page_size=request.page_size,\n total=0,\n warning=(\n \"Cannot load Superset accounts for this environment right now. \"\n \"You can enter username manually.\"\n ),\n items=[],\n )\n # #endregion lookup_superset_accounts\n\n # #region _resolve_environment [C:2] [TYPE Function]\n # @BRIEF Resolve environment model from configured environments by id.\n # @PRE environment_id is provided.\n # @POST Returns environment object when found else None.\n def _resolve_environment(self, environment_id: str):\n environments = self.config_manager.get_environments()\n for env in environments:\n if str(getattr(env, \"id\", \"\")) == str(environment_id):\n return env\n return None\n # #endregion _resolve_environment\n# #endregion SupersetLookupService\n# #endregion superset_lookup_service\n"
},
{
"contract_id": "SupersetLookupService",
@@ -55958,14 +51136,14 @@
{
"source_id": "TestDemoModeIsolation",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:backend.src.services.clean_release.demo_data_service",
- "target_ref": "[EXT:path:backend.src.services.clean_release.demo_data_service]"
+ "target_id": "DemoDataService",
+ "target_ref": "[DemoDataService]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TestDemoModeIsolation [C:2] [TYPE Module]\n# @SEMANTICS: clean-release, demo-mode, isolation, namespace, repository\n# @PURPOSE: Verify demo and real mode namespace isolation contracts before TUI integration.\n# @LAYER Tests\n# @RELATION DEPENDS_ON -> [EXT:path:backend.src.services.clean_release.demo_data_service]\n\nfrom __future__ import annotations\n\nfrom datetime import UTC, datetime\n\nfrom src.models.clean_release import ReleaseCandidate\nfrom src.services.clean_release.demo_data_service import (\n build_namespaced_id,\n create_isolated_repository,\n resolve_namespace,\n)\n\n\n# #region test_resolve_namespace_separates_demo_and_real [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestDemoModeIsolation\n# @PURPOSE: Ensure namespace resolver returns deterministic and distinct namespaces.\n# @PRE: Mode names are provided as user/runtime strings.\n# @POST: Demo and real namespaces are different and stable.\ndef test_resolve_namespace_separates_demo_and_real() -> None:\n demo = resolve_namespace(\"demo\")\n real = resolve_namespace(\"real\")\n\n assert demo == \"clean-release:demo\"\n assert real == \"clean-release:real\"\n assert demo != real\n# #endregion test_resolve_namespace_separates_demo_and_real\n\n\n# #region test_build_namespaced_id_prevents_cross_mode_collisions [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestDemoModeIsolation\n# @PURPOSE: Ensure ID generation prevents demo/real collisions for identical logical IDs.\n# @PRE: Same logical candidate id is used in two different namespaces.\n# @POST: Produced physical IDs differ by namespace prefix.\ndef test_build_namespaced_id_prevents_cross_mode_collisions() -> None:\n logical_id = \"2026.03.09-rc1\"\n demo_id = build_namespaced_id(resolve_namespace(\"demo\"), logical_id)\n real_id = build_namespaced_id(resolve_namespace(\"real\"), logical_id)\n\n assert demo_id != real_id\n assert demo_id.startswith(\"clean-release:demo::\")\n assert real_id.startswith(\"clean-release:real::\")\n# #endregion test_build_namespaced_id_prevents_cross_mode_collisions\n\n\n# #region test_create_isolated_repository_keeps_mode_data_separate [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestDemoModeIsolation\n# @PURPOSE: Verify demo and real repositories do not leak state across mode boundaries.\n# @PRE: Two repositories are created for distinct modes.\n# @POST: Candidate mutations in one mode are not visible in the other mode.\ndef test_create_isolated_repository_keeps_mode_data_separate() -> None:\n demo_repo = create_isolated_repository(\"demo\")\n real_repo = create_isolated_repository(\"real\")\n\n demo_candidate_id = build_namespaced_id(resolve_namespace(\"demo\"), \"candidate-1\")\n real_candidate_id = build_namespaced_id(resolve_namespace(\"real\"), \"candidate-1\")\n\n demo_repo.save_candidate(\n ReleaseCandidate(\n id=demo_candidate_id,\n version=\"1.0.0\",\n source_snapshot_ref=\"git:sha-demo\",\n created_by=\"demo-operator\",\n created_at=datetime.now(UTC),\n status=\"DRAFT\",\n )\n )\n real_repo.save_candidate(\n ReleaseCandidate(\n id=real_candidate_id,\n version=\"1.0.0\",\n source_snapshot_ref=\"git:sha-real\",\n created_by=\"real-operator\",\n created_at=datetime.now(UTC),\n status=\"DRAFT\",\n )\n )\n\n assert demo_repo.get_candidate(demo_candidate_id) is not None\n assert demo_repo.get_candidate(real_candidate_id) is None\n assert real_repo.get_candidate(real_candidate_id) is not None\n assert real_repo.get_candidate(demo_candidate_id) is None\n# #endregion test_create_isolated_repository_keeps_mode_data_separate\n\n# #endregion TestDemoModeIsolation\n"
+ "body": "# #region TestDemoModeIsolation [C:2] [TYPE Module]\n# @SEMANTICS: clean-release, demo-mode, isolation, namespace, repository\n# @PURPOSE: Verify demo and real mode namespace isolation contracts before TUI integration.\n# @LAYER Tests\n# @RELATION DEPENDS_ON -> [DemoDataService]\n\nfrom __future__ import annotations\n\nfrom datetime import UTC, datetime\n\nfrom src.models.clean_release import ReleaseCandidate\nfrom src.services.clean_release.demo_data_service import (\n build_namespaced_id,\n create_isolated_repository,\n resolve_namespace,\n)\n\n\n# #region test_resolve_namespace_separates_demo_and_real [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestDemoModeIsolation\n# @PURPOSE: Ensure namespace resolver returns deterministic and distinct namespaces.\n# @PRE: Mode names are provided as user/runtime strings.\n# @POST: Demo and real namespaces are different and stable.\ndef test_resolve_namespace_separates_demo_and_real() -> None:\n demo = resolve_namespace(\"demo\")\n real = resolve_namespace(\"real\")\n\n assert demo == \"clean-release:demo\"\n assert real == \"clean-release:real\"\n assert demo != real\n# #endregion test_resolve_namespace_separates_demo_and_real\n\n\n# #region test_build_namespaced_id_prevents_cross_mode_collisions [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestDemoModeIsolation\n# @PURPOSE: Ensure ID generation prevents demo/real collisions for identical logical IDs.\n# @PRE: Same logical candidate id is used in two different namespaces.\n# @POST: Produced physical IDs differ by namespace prefix.\ndef test_build_namespaced_id_prevents_cross_mode_collisions() -> None:\n logical_id = \"2026.03.09-rc1\"\n demo_id = build_namespaced_id(resolve_namespace(\"demo\"), logical_id)\n real_id = build_namespaced_id(resolve_namespace(\"real\"), logical_id)\n\n assert demo_id != real_id\n assert demo_id.startswith(\"clean-release:demo::\")\n assert real_id.startswith(\"clean-release:real::\")\n# #endregion test_build_namespaced_id_prevents_cross_mode_collisions\n\n\n# #region test_create_isolated_repository_keeps_mode_data_separate [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestDemoModeIsolation\n# @PURPOSE: Verify demo and real repositories do not leak state across mode boundaries.\n# @PRE: Two repositories are created for distinct modes.\n# @POST: Candidate mutations in one mode are not visible in the other mode.\ndef test_create_isolated_repository_keeps_mode_data_separate() -> None:\n demo_repo = create_isolated_repository(\"demo\")\n real_repo = create_isolated_repository(\"real\")\n\n demo_candidate_id = build_namespaced_id(resolve_namespace(\"demo\"), \"candidate-1\")\n real_candidate_id = build_namespaced_id(resolve_namespace(\"real\"), \"candidate-1\")\n\n demo_repo.save_candidate(\n ReleaseCandidate(\n id=demo_candidate_id,\n version=\"1.0.0\",\n source_snapshot_ref=\"git:sha-demo\",\n created_by=\"demo-operator\",\n created_at=datetime.now(UTC),\n status=\"DRAFT\",\n )\n )\n real_repo.save_candidate(\n ReleaseCandidate(\n id=real_candidate_id,\n version=\"1.0.0\",\n source_snapshot_ref=\"git:sha-real\",\n created_by=\"real-operator\",\n created_at=datetime.now(UTC),\n status=\"DRAFT\",\n )\n )\n\n assert demo_repo.get_candidate(demo_candidate_id) is not None\n assert demo_repo.get_candidate(real_candidate_id) is None\n assert real_repo.get_candidate(real_candidate_id) is not None\n assert real_repo.get_candidate(demo_candidate_id) is None\n# #endregion test_create_isolated_repository_keeps_mode_data_separate\n\n# #endregion TestDemoModeIsolation\n"
},
{
"contract_id": "test_resolve_namespace_separates_demo_and_real",
@@ -58112,7 +53290,7 @@
"body": " # #region test_deprecation_comment_exists [C:2] [TYPE Function]\n # @BRIEF The source module documents the @DEPRECATED rationale in the region header.\n def test_deprecation_comment_exists(self):\n \"\"\"Verify the source file documents the is_multimodal_model deprecation.\n\n The @DEPRECATED tag is in the region header (line 127), not in the function body.\n inspect.getsource(function) only returns the body (lines 137-167).\n \"\"\"\n module_path = Path(__file__).parent.parent / \"src\" / \"services\" / \"llm_prompt_templates.py\"\n source = module_path.read_text(encoding=\"utf-8\")\n assert \"DEPRECATED\" in source, \"Source must document @DEPRECATED status\"\n assert \"is_multimodal_model is deprecated\" in source.lower() or \"deprecated\" in source.lower()\n # #endregion test_deprecation_comment_exists\n"
},
{
- "contract_id": "test_layout[EXT:internal:_utils]",
+ "contract_id": "TestLayoutUtils",
"contract_type": "TestModule",
"file_path": "backend/tests/test_layout_utils.py",
"start_line": 1,
@@ -58127,7 +53305,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region test_layout[EXT:internal:_utils] [C:3] [TYPE TestModule] [SEMANTICS test, layout, superset, height, estimation]\n# @BRIEF Contract tests for layout utility functions — _estimate_markdown_height.\n# Verifies the height estimation formula: empty → 19, short text → computed,\n# padding accounted for, and long text capped at 200.\n# @LAYER Test\n# @RELATION BINDS_TO -> [LayoutUtils]\n# @TEST_CONTRACT: _estimate_markdown_height(str) -> int in [19, 200]\n# @TEST_EDGE: empty_content -> returns minimum height (19)\n# @TEST_EDGE: html_only_content -> returns minimum height (19)\n# @TEST_EDGE: content_with_padding -> padding:12 correctly increases height\n# @TEST_EDGE: very_long_content -> capped at maximum height (200)\nimport pytest\n\nfrom src.core.superset_client._layout[EXT:internal:_utils] import _estimate_markdown_height\n\n\nclass TestEstimateMarkdownHeight:\n \"\"\"Tests for _estimate_markdown_height pure function.\"\"\"\n\n # #region test_empty_content [C:2] [TYPE Function]\n # @BRIEF Empty string returns minimum height 19.\n def test_empty_content(self):\n assert _estimate_markdown_height(\"\") == 19\n # #endregion test_empty_content\n\n # #region test_single_line_text [C:2] [TYPE Function]\n # @BRIEF Short text without padding returns expected computed height.\n # 200 chars → 200//40+1 = 6 lines → 6*22 = 132px → 40+132 = 172px → 172//8 = 21\n def test_single_line_text(self):\n text = \"A\" * 200\n assert _estimate_markdown_height(text) == 21\n # #endregion test_single_line_text\n\n # #region test_content_with_padding [C:2] [TYPE Function]\n # @BRIEF Content with padding:12 — 24px added to content height.\n # 200 chars + padding:12 → 6*22 + 24 = 156 → 40+156 = 196 → 196//8 = 24\n def test_content_with_padding(self):\n content = '' + \"A\" * 200 + \"
\"\n assert _estimate_markdown_height(content) == 24\n # #endregion test_content_with_padding\n\n # #region test_very_long_content [C:2] [TYPE Function]\n # @BRIEF Very long content (3000 chars) capped at max height 200.\n def test_very_long_content(self):\n text = \"A\" * 3000\n assert _estimate_markdown_height(text) == 200\n # #endregion test_very_long_content\n\n # #region test_html_only_content [C:2] [TYPE Function]\n # @BRIEF HTML-only content (no visible text) returns minimum height 19.\n def test_html_only_content(self):\n content = \"
\"\n assert _estimate_markdown_height(content) == 19\n # #endregion test_html_only_content\n# #endregion test_layout[EXT:internal:_utils]\n"
+ "body": "# #region TestLayoutUtils [C:3] [TYPE TestModule] [SEMANTICS test, layout, superset, height, estimation]\n# @BRIEF Contract tests for layout utility functions — _estimate_markdown_height.\n# Verifies the height estimation formula: empty → 19, short text → computed,\n# padding accounted for, and long text capped at 200.\n# @LAYER Test\n# @RELATION BINDS_TO -> [LayoutUtils]\n# @TEST_CONTRACT: _estimate_markdown_height(str) -> int in [19, 200]\n# @TEST_EDGE: empty_content -> returns minimum height (19)\n# @TEST_EDGE: html_only_content -> returns minimum height (19)\n# @TEST_EDGE: content_with_padding -> padding:12 correctly increases height\n# @TEST_EDGE: very_long_content -> capped at maximum height (200)\nimport pytest\n\nfrom src.core.superset_client._layout_utils import _estimate_markdown_height\n\n\nclass TestEstimateMarkdownHeight:\n \"\"\"Tests for _estimate_markdown_height pure function.\"\"\"\n\n # #region test_empty_content [C:2] [TYPE Function]\n # @BRIEF Empty string returns minimum height 19.\n def test_empty_content(self):\n assert _estimate_markdown_height(\"\") == 19\n # #endregion test_empty_content\n\n # #region test_single_line_text [C:2] [TYPE Function]\n # @BRIEF Short text without padding returns expected computed height.\n # 200 chars → 200//40+1 = 6 lines → 6*22 = 132px → 40+132 = 172px → 172//8 = 21\n def test_single_line_text(self):\n text = \"A\" * 200\n assert _estimate_markdown_height(text) == 21\n # #endregion test_single_line_text\n\n # #region test_content_with_padding [C:2] [TYPE Function]\n # @BRIEF Content with padding:12 — 24px added to content height.\n # 200 chars + padding:12 → 6*22 + 24 = 156 → 40+156 = 196 → 196//8 = 24\n def test_content_with_padding(self):\n content = '' + \"A\" * 200 + \"
\"\n assert _estimate_markdown_height(content) == 24\n # #endregion test_content_with_padding\n\n # #region test_very_long_content [C:2] [TYPE Function]\n # @BRIEF Very long content (3000 chars) capped at max height 200.\n def test_very_long_content(self):\n text = \"A\" * 3000\n assert _estimate_markdown_height(text) == 200\n # #endregion test_very_long_content\n\n # #region test_html_only_content [C:2] [TYPE Function]\n # @BRIEF HTML-only content (no visible text) returns minimum height 19.\n def test_html_only_content(self):\n content = \"
\"\n assert _estimate_markdown_height(content) == 19\n # #endregion test_html_only_content\n# #endregion TestLayoutUtils\n"
},
{
"contract_id": "test_empty_content",
@@ -58542,14 +53720,14 @@
{
"source_id": "TestLogger",
"relation_type": "BINDS_TO",
- "target_id": "EXT:path:src/core/logger.py",
- "target_ref": "[EXT:path:src/core/logger.py]"
+ "target_id": "LoggerModule",
+ "target_ref": "[LoggerModule]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "# #region TestLogger [C:2] [TYPE Module]\n# @SEMANTICS: logging, tests, belief_state, cot, json\n# @PURPOSE: Unit tests for the custom logger CoT JSON formatters and configuration context manager.\n# @LAYER Tests\n# @RELATION BINDS_TO -> [EXT:path:src/core/logger.py]\n# @INVARIANT: All required log statements must correctly check the threshold.\n\nimport logging\n\nimport pytest\n\nfrom src.core.config_models import LoggingConfig\nfrom src.core.logger import (\n CotJsonFormatter,\n belief_scope,\n configure_logger,\n get_task_log_level,\n logger,\n should_log_task_level,\n)\n\n\n@pytest.fixture(autouse=True)\ndef reset_logger_state():\n \"\"\"Reset logger state before each test to avoid cross-test contamination.\"\"\"\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n # Also reset the logger level for caplog to work correctly\n logging.getLogger(\"superset_tools_app\").setLevel(logging.DEBUG)\n yield\n # Reset after test too\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n\n# #region test_belief_scope_logs_reason_reflect_at_debug [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope generates REASON and REFLECT CoT markers at DEBUG level.\n# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST: Logs are verified to contain REASON (entry) and REFLECT (coherence) markers.\ndef test_belief_scope_logs_reason_reflect_at_debug(caplog):\n \"\"\"Test that belief_scope generates REASON and REFLECT CoT markers at DEBUG level.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"TestFunction\"):\n logger.info(\"Doing something important\")\n\n # Check that the records contain the expected markers\n reason_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REASON' and getattr(r, 'src', None) == 'TestFunction'\n ]\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT' and getattr(r, 'src', None) == 'TestFunction'\n ]\n info_records = [\n r for r in caplog.records\n if r.levelname == 'INFO' and 'Doing something important' in r.getMessage()\n ]\n\n assert len(reason_records) >= 1, \"REASON marker not found for TestFunction\"\n assert len(reflect_records) >= 1, \"REFLECT marker not found for TestFunction\"\n assert len(info_records) >= 1, \"INFO log 'Doing something important' not found\"\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_logs_reason_reflect_at_debug\n\n\n# #region test_belief_scope_error_handling [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope logs EXPLORE marker on exception.\n# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST: Logs are verified to contain EXPLORE marker with error context.\ndef test_belief_scope_error_handling(caplog):\n \"\"\"Test that belief_scope logs EXPLORE marker on exception.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with pytest.raises(ValueError), belief_scope(\"FailingFunction\"):\n raise ValueError(\"Something went wrong\")\n\n # Check that an EXPLORE marker was emitted\n explore_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'EXPLORE'\n and getattr(r, 'src', None) == 'FailingFunction'\n ]\n\n assert len(explore_records) >= 1, f\"EXPLORE marker not found for FailingFunction. Logs: {[(r.levelname, getattr(r, 'marker', ''), r.getMessage()) for r in caplog.records]}\"\n assert 'Something went wrong' in explore_records[0].getMessage() or \\\n 'Something went wrong' in str(getattr(explore_records[0], 'error', ''))\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_error_handling\n\n\n# #region test_belief_scope_success_coherence [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope logs REFLECT marker on success.\n# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST: Logs are verified to contain REFLECT marker.\ndef test_belief_scope_success_coherence(caplog):\n \"\"\"Test that belief_scope logs REFLECT marker on success.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"SuccessFunction\"):\n pass\n\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT'\n and getattr(r, 'src', None) == 'SuccessFunction'\n ]\n\n assert len(reflect_records) >= 1, f\"REFLECT marker not found for SuccessFunction. Logs: {[(r.levelname, getattr(r, 'marker', ''), r.getMessage()) for r in caplog.records]}\"\n assert 'Coherence OK' in reflect_records[0].getMessage() or \\\n getattr(reflect_records[0], 'intent', '') == 'Coherence OK'\n\n\n# #endregion test_belief_scope_success_coherence\n\n\n# #region test_belief_scope_reason_not_visible_at_info [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.\n# @PRE: belief_scope is available. caplog fixture is used.\n# @POST: REASON/REFLECT markers are not captured at INFO level.\ndef test_belief_scope_reason_not_visible_at_info(caplog):\n \"\"\"Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.\"\"\"\n caplog.set_level(\"INFO\")\n\n with belief_scope(\"InfoLevelFunction\"):\n logger.info(\"Doing something important\")\n\n # The REASON and REFLECT markers are debug-level, so they should NOT appear at INFO\n reason_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REASON' and getattr(r, 'src', None) == 'InfoLevelFunction'\n ]\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT' and getattr(r, 'src', None) == 'InfoLevelFunction'\n ]\n\n assert len(reason_records) == 0, \"REASON marker should not be visible at INFO\"\n assert len(reflect_records) == 0, \"REFLECT marker should not be visible at INFO\"\n\n # But the INFO-level message should be visible\n info_records = [\n r for r in caplog.records\n if r.levelname == 'INFO' and 'Doing something important' in r.getMessage()\n ]\n assert len(info_records) >= 1, \"INFO log 'Doing something important' should be visible\"\n# #endregion test_belief_scope_reason_not_visible_at_info\n\n\n# #region test_task_log_level_default [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that default task log level is INFO.\n# @PRE: None.\n# @POST: Default level is INFO.\ndef test_task_log_level_default():\n \"\"\"Test that default task log level is INFO.\"\"\"\n level = get_task_log_level()\n assert level == \"INFO\"\n# #endregion test_task_log_level_default\n\n\n# #region test_should_log_task_level [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that should_log_task_level correctly filters log levels.\n# @PRE: None.\n# @POST: Filtering works correctly for all level combinations.\ndef test_should_log_task_level():\n \"\"\"Test that should_log_task_level correctly filters log levels.\"\"\"\n # Default level is INFO\n assert should_log_task_level(\"ERROR\") is True, \"ERROR should be logged at INFO threshold\"\n assert should_log_task_level(\"WARNING\") is True, \"WARNING should be logged at INFO threshold\"\n assert should_log_task_level(\"INFO\") is True, \"INFO should be logged at INFO threshold\"\n assert should_log_task_level(\"DEBUG\") is False, \"DEBUG should NOT be logged at INFO threshold\"\n# #endregion test_should_log_task_level\n\n\n# #region test_configure_logger_task_log_level [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that configure_logger updates task_log_level.\n# @PRE: LoggingConfig is available.\n# @POST: task_log_level is updated correctly.\ndef test_configure_logger_task_log_level():\n \"\"\"Test that configure_logger updates task_log_level.\"\"\"\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n assert get_task_log_level() == \"DEBUG\", \"task_log_level should be DEBUG\"\n assert should_log_task_level(\"DEBUG\") is True, \"DEBUG should be logged at DEBUG threshold\"\n\n # Reset to INFO\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n assert get_task_log_level() == \"INFO\", \"task_log_level should be reset to INFO\"\n# #endregion test_configure_logger_task_log_level\n\n\n# #region test_enable_belief_state_flag [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that enable_belief_state flag controls belief_scope entry logging.\n# @PRE: LoggingConfig is available. caplog fixture is used.\n# @POST: REASON entry marker suppressed when disabled; REFLECT coherence still logged.\ndef test_enable_belief_state_flag(caplog):\n \"\"\"Test that enable_belief_state flag controls belief_scope REASON entry logging.\"\"\"\n # Disable belief state\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=False\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"DisabledFunction\"):\n logger.info(\"Doing something\")\n\n # REASON entry marker should NOT be logged when disabled\n reason_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REASON' and getattr(r, 'src', None) == 'DisabledFunction'\n ]\n assert len(reason_records) == 0, \"REASON entry should not be logged when disabled\"\n\n # REFLECT coherence marker should still be logged (internal tracking)\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT' and getattr(r, 'src', None) == 'DisabledFunction'\n ]\n assert len(reflect_records) >= 1, \"REFLECT coherence should still be logged\"\n\n # Re-enable for other tests\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n# #endregion test_enable_belief_state_flag\n\n# #region test_cot_json_formatter_output [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that CotJsonFormatter produces valid JSON with expected fields.\ndef test_cot_json_formatter_output():\n \"\"\"Test that CotJsonFormatter produces valid JSON with expected fields.\"\"\"\n import json\n\n formatter = CotJsonFormatter()\n\n # Create a LogRecord with structured extra data\n record = logging.LogRecord(\n name=\"test.module\",\n level=logging.INFO,\n pathname=\"/fake/path.py\",\n lineno=42,\n msg=\"Test action\",\n args=(),\n exc_info=None,\n )\n record.marker = \"REASON\"\n record.intent = \"Test action\"\n record.src = \"TestModule\"\n record.payload = {\"key\": \"value\"}\n\n output = formatter.format(record)\n parsed = json.loads(output)\n\n assert parsed[\"level\"] == \"INFO\"\n assert parsed[\"marker\"] == \"REASON\"\n assert parsed[\"intent\"] == \"Test action\"\n assert parsed[\"src\"] == \"TestModule\"\n assert parsed[\"payload\"] == {\"key\": \"value\"}\n assert \"ts\" in parsed\n assert \"trace_id\" in parsed\n# #endregion test_cot_json_formatter_output\n\n# #region test_cot_json_formatter_plain_message [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that CotJsonFormatter wraps plain messages (no extra) with default marker.\ndef test_cot_json_formatter_plain_message():\n \"\"\"Test that CotJsonFormatter wraps plain messages with default marker.\"\"\"\n import json\n\n formatter = CotJsonFormatter()\n\n # Create a LogRecord WITHOUT extra data (plain message)\n record = logging.LogRecord(\n name=\"test.module\",\n level=logging.INFO,\n pathname=\"/fake/path.py\",\n lineno=42,\n msg=\"Plain info message\",\n args=(),\n exc_info=None,\n )\n\n output = formatter.format(record)\n parsed = json.loads(output)\n\n assert parsed[\"level\"] == \"INFO\"\n assert parsed[\"marker\"] == \"REASON\" # default for plain messages\n assert parsed[\"intent\"] == \"Plain info message\"\n assert parsed[\"src\"] == \"test.module\"\n assert \"ts\" in parsed\n assert \"trace_id\" in parsed\n# #endregion test_cot_json_formatter_plain_message\n\n# #endregion TestLogger\n"
+ "body": "# #region TestLogger [C:2] [TYPE Module]\n# @SEMANTICS: logging, tests, belief_state, cot, json\n# @PURPOSE: Unit tests for the custom logger CoT JSON formatters and configuration context manager.\n# @LAYER Tests\n# @RELATION BINDS_TO -> [LoggerModule]\n# @INVARIANT: All required log statements must correctly check the threshold.\n\nimport logging\n\nimport pytest\n\nfrom src.core.config_models import LoggingConfig\nfrom src.core.logger import (\n CotJsonFormatter,\n belief_scope,\n configure_logger,\n get_task_log_level,\n logger,\n should_log_task_level,\n)\n\n\n@pytest.fixture(autouse=True)\ndef reset_logger_state():\n \"\"\"Reset logger state before each test to avoid cross-test contamination.\"\"\"\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n # Also reset the logger level for caplog to work correctly\n logging.getLogger(\"superset_tools_app\").setLevel(logging.DEBUG)\n yield\n # Reset after test too\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n\n# #region test_belief_scope_logs_reason_reflect_at_debug [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope generates REASON and REFLECT CoT markers at DEBUG level.\n# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST: Logs are verified to contain REASON (entry) and REFLECT (coherence) markers.\ndef test_belief_scope_logs_reason_reflect_at_debug(caplog):\n \"\"\"Test that belief_scope generates REASON and REFLECT CoT markers at DEBUG level.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"TestFunction\"):\n logger.info(\"Doing something important\")\n\n # Check that the records contain the expected markers\n reason_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REASON' and getattr(r, 'src', None) == 'TestFunction'\n ]\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT' and getattr(r, 'src', None) == 'TestFunction'\n ]\n info_records = [\n r for r in caplog.records\n if r.levelname == 'INFO' and 'Doing something important' in r.getMessage()\n ]\n\n assert len(reason_records) >= 1, \"REASON marker not found for TestFunction\"\n assert len(reflect_records) >= 1, \"REFLECT marker not found for TestFunction\"\n assert len(info_records) >= 1, \"INFO log 'Doing something important' not found\"\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_logs_reason_reflect_at_debug\n\n\n# #region test_belief_scope_error_handling [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope logs EXPLORE marker on exception.\n# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST: Logs are verified to contain EXPLORE marker with error context.\ndef test_belief_scope_error_handling(caplog):\n \"\"\"Test that belief_scope logs EXPLORE marker on exception.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with pytest.raises(ValueError), belief_scope(\"FailingFunction\"):\n raise ValueError(\"Something went wrong\")\n\n # Check that an EXPLORE marker was emitted\n explore_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'EXPLORE'\n and getattr(r, 'src', None) == 'FailingFunction'\n ]\n\n assert len(explore_records) >= 1, f\"EXPLORE marker not found for FailingFunction. Logs: {[(r.levelname, getattr(r, 'marker', ''), r.getMessage()) for r in caplog.records]}\"\n assert 'Something went wrong' in explore_records[0].getMessage() or \\\n 'Something went wrong' in str(getattr(explore_records[0], 'error', ''))\n\n # Reset to INFO\n config = LoggingConfig(level=\"INFO\", task_log_level=\"INFO\", enable_belief_state=True)\n configure_logger(config)\n# #endregion test_belief_scope_error_handling\n\n\n# #region test_belief_scope_success_coherence [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope logs REFLECT marker on success.\n# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.\n# @POST: Logs are verified to contain REFLECT marker.\ndef test_belief_scope_success_coherence(caplog):\n \"\"\"Test that belief_scope logs REFLECT marker on success.\"\"\"\n # Configure logger to DEBUG level\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"SuccessFunction\"):\n pass\n\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT'\n and getattr(r, 'src', None) == 'SuccessFunction'\n ]\n\n assert len(reflect_records) >= 1, f\"REFLECT marker not found for SuccessFunction. Logs: {[(r.levelname, getattr(r, 'marker', ''), r.getMessage()) for r in caplog.records]}\"\n assert 'Coherence OK' in reflect_records[0].getMessage() or \\\n getattr(reflect_records[0], 'intent', '') == 'Coherence OK'\n\n\n# #endregion test_belief_scope_success_coherence\n\n\n# #region test_belief_scope_reason_not_visible_at_info [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.\n# @PRE: belief_scope is available. caplog fixture is used.\n# @POST: REASON/REFLECT markers are not captured at INFO level.\ndef test_belief_scope_reason_not_visible_at_info(caplog):\n \"\"\"Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.\"\"\"\n caplog.set_level(\"INFO\")\n\n with belief_scope(\"InfoLevelFunction\"):\n logger.info(\"Doing something important\")\n\n # The REASON and REFLECT markers are debug-level, so they should NOT appear at INFO\n reason_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REASON' and getattr(r, 'src', None) == 'InfoLevelFunction'\n ]\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT' and getattr(r, 'src', None) == 'InfoLevelFunction'\n ]\n\n assert len(reason_records) == 0, \"REASON marker should not be visible at INFO\"\n assert len(reflect_records) == 0, \"REFLECT marker should not be visible at INFO\"\n\n # But the INFO-level message should be visible\n info_records = [\n r for r in caplog.records\n if r.levelname == 'INFO' and 'Doing something important' in r.getMessage()\n ]\n assert len(info_records) >= 1, \"INFO log 'Doing something important' should be visible\"\n# #endregion test_belief_scope_reason_not_visible_at_info\n\n\n# #region test_task_log_level_default [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that default task log level is INFO.\n# @PRE: None.\n# @POST: Default level is INFO.\ndef test_task_log_level_default():\n \"\"\"Test that default task log level is INFO.\"\"\"\n level = get_task_log_level()\n assert level == \"INFO\"\n# #endregion test_task_log_level_default\n\n\n# #region test_should_log_task_level [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that should_log_task_level correctly filters log levels.\n# @PRE: None.\n# @POST: Filtering works correctly for all level combinations.\ndef test_should_log_task_level():\n \"\"\"Test that should_log_task_level correctly filters log levels.\"\"\"\n # Default level is INFO\n assert should_log_task_level(\"ERROR\") is True, \"ERROR should be logged at INFO threshold\"\n assert should_log_task_level(\"WARNING\") is True, \"WARNING should be logged at INFO threshold\"\n assert should_log_task_level(\"INFO\") is True, \"INFO should be logged at INFO threshold\"\n assert should_log_task_level(\"DEBUG\") is False, \"DEBUG should NOT be logged at INFO threshold\"\n# #endregion test_should_log_task_level\n\n\n# #region test_configure_logger_task_log_level [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that configure_logger updates task_log_level.\n# @PRE: LoggingConfig is available.\n# @POST: task_log_level is updated correctly.\ndef test_configure_logger_task_log_level():\n \"\"\"Test that configure_logger updates task_log_level.\"\"\"\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n\n assert get_task_log_level() == \"DEBUG\", \"task_log_level should be DEBUG\"\n assert should_log_task_level(\"DEBUG\") is True, \"DEBUG should be logged at DEBUG threshold\"\n\n # Reset to INFO\n config = LoggingConfig(\n level=\"INFO\",\n task_log_level=\"INFO\",\n enable_belief_state=True\n )\n configure_logger(config)\n assert get_task_log_level() == \"INFO\", \"task_log_level should be reset to INFO\"\n# #endregion test_configure_logger_task_log_level\n\n\n# #region test_enable_belief_state_flag [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that enable_belief_state flag controls belief_scope entry logging.\n# @PRE: LoggingConfig is available. caplog fixture is used.\n# @POST: REASON entry marker suppressed when disabled; REFLECT coherence still logged.\ndef test_enable_belief_state_flag(caplog):\n \"\"\"Test that enable_belief_state flag controls belief_scope REASON entry logging.\"\"\"\n # Disable belief state\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=False\n )\n configure_logger(config)\n\n caplog.set_level(\"DEBUG\")\n\n with belief_scope(\"DisabledFunction\"):\n logger.info(\"Doing something\")\n\n # REASON entry marker should NOT be logged when disabled\n reason_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REASON' and getattr(r, 'src', None) == 'DisabledFunction'\n ]\n assert len(reason_records) == 0, \"REASON entry should not be logged when disabled\"\n\n # REFLECT coherence marker should still be logged (internal tracking)\n reflect_records = [\n r for r in caplog.records\n if getattr(r, 'marker', None) == 'REFLECT' and getattr(r, 'src', None) == 'DisabledFunction'\n ]\n assert len(reflect_records) >= 1, \"REFLECT coherence should still be logged\"\n\n # Re-enable for other tests\n config = LoggingConfig(\n level=\"DEBUG\",\n task_log_level=\"DEBUG\",\n enable_belief_state=True\n )\n configure_logger(config)\n# #endregion test_enable_belief_state_flag\n\n# #region test_cot_json_formatter_output [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that CotJsonFormatter produces valid JSON with expected fields.\ndef test_cot_json_formatter_output():\n \"\"\"Test that CotJsonFormatter produces valid JSON with expected fields.\"\"\"\n import json\n\n formatter = CotJsonFormatter()\n\n # Create a LogRecord with structured extra data\n record = logging.LogRecord(\n name=\"test.module\",\n level=logging.INFO,\n pathname=\"/fake/path.py\",\n lineno=42,\n msg=\"Test action\",\n args=(),\n exc_info=None,\n )\n record.marker = \"REASON\"\n record.intent = \"Test action\"\n record.src = \"TestModule\"\n record.payload = {\"key\": \"value\"}\n\n output = formatter.format(record)\n parsed = json.loads(output)\n\n assert parsed[\"level\"] == \"INFO\"\n assert parsed[\"marker\"] == \"REASON\"\n assert parsed[\"intent\"] == \"Test action\"\n assert parsed[\"src\"] == \"TestModule\"\n assert parsed[\"payload\"] == {\"key\": \"value\"}\n assert \"ts\" in parsed\n assert \"trace_id\" in parsed\n# #endregion test_cot_json_formatter_output\n\n# #region test_cot_json_formatter_plain_message [C:2] [TYPE Function]\n# @RELATION BINDS_TO -> TestLogger\n# @PURPOSE: Test that CotJsonFormatter wraps plain messages (no extra) with default marker.\ndef test_cot_json_formatter_plain_message():\n \"\"\"Test that CotJsonFormatter wraps plain messages with default marker.\"\"\"\n import json\n\n formatter = CotJsonFormatter()\n\n # Create a LogRecord WITHOUT extra data (plain message)\n record = logging.LogRecord(\n name=\"test.module\",\n level=logging.INFO,\n pathname=\"/fake/path.py\",\n lineno=42,\n msg=\"Plain info message\",\n args=(),\n exc_info=None,\n )\n\n output = formatter.format(record)\n parsed = json.loads(output)\n\n assert parsed[\"level\"] == \"INFO\"\n assert parsed[\"marker\"] == \"REASON\" # default for plain messages\n assert parsed[\"intent\"] == \"Plain info message\"\n assert parsed[\"src\"] == \"test.module\"\n assert \"ts\" in parsed\n assert \"trace_id\" in parsed\n# #endregion test_cot_json_formatter_plain_message\n\n# #endregion TestLogger\n"
},
{
"contract_id": "test_belief_scope_success_coherence",
@@ -63570,7 +58748,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region EnterpriseCleanSetupE2E [C:4] [TYPE Test] [SEMANTICS e2e, enterprise-clean, setup, onboarding, environment]\n// @BRIEF Stage 1: E2E test for enterprise-clean empty image — first-run setup via StartupEnvironmentWizard.\n// @@RATIONALE All 4 tests pass after fixing: (1) button ambiguity — zero-state page and wizard modal both have 'Начать настройку' button, resolved by scoping to wizard modal via .fixed.inset-0.z-50; (2) wizard detection — changed from waitForSelector('text=...') to getByText() with regex for locale-robust matching; (3) form fill — connections.* i18n keys missing in Docker build, switched to placeholder-based locators scoped within wizard; (4) settings navigation — use authPage fixture for consistent login\n// @@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues\n\n// Validates: bundle deployment, PostgreSQL fresh DB, initial admin bootstrap, environment creation wizard.\n// @RELATION BINDS_TO -> [[EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab]]\n// @RELATION DEPENDS_ON -> [ApiHelper]\n// @UX_STATE WizardIntro -> Wizard explains setup purpose with \"Start setup\" button.\n// @UX_STATE WizardForm -> Form collects environment ID, name, URL, username, password, stage.\n// @UX_STATE WizardSaving -> Submit disabled, progress label shown.\n// @UX_STATE EnvironmentCreated -> Wizard closes, environment appears in selector, dashboards load.\n// @RATIONALE Enterprise-clean bundle ships with an empty PostgreSQL. First login MUST trigger the\n// StartupEnvironmentWizard (blocking experience). Creating the first Superset environment is the\n// critical path — if this fails, the bundle is not deliverable.\n// @REJECTED Skipping wizard via API pre-config — must test the actual user-facing wizard UX.\n// @INVARIANT Wizard appears on first login when no environments exist.\n// @INVARIANT After env creation, dashboard hub loads without wizard.\n//\n// Usage:\n// Deploy enterprise-clean stack first (docker compose -f docker-compose.enterprise-clean.yml up -d)\n// Then run: npx playwright test --grep \"Enterprise Clean Setup\"\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8000';\nconst SUPERSET_URL = 'https://ss-dev.bebesh.ru';\nconst SUPERSET_USER = 'admin';\nconst SUPERSET_PASS = 'payroll-unadorned-many';\n\ntest.describe('Enterprise Clean Setup — Stage 1: Empty Image', () => {\n\n\t// ── 1.1. FIRST LOGIN — WIZARD TRIGGER ─────────────────────\n\ttest('first login triggers StartupEnvironmentWizard on empty instance', async ({ page }) => {\n\t\tawait test.step('Login to clean instance', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.waitForSelector('form', { timeout: 15_000 });\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\t// Should redirect away from /login\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Login successful');\n\t\t});\n\n\t\tawait test.step('Dashboard redirect triggers StartupEnvironmentWizard', async () => {\n\t\t\t// After login, the HomePage redirects to /dashboards.\n\t\t\t// If no environments exist, the StartupEnvironmentWizard should appear.\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 15_000 });\n\n\t\t\t// Look for the wizard modal — it has \"Configure your first environment\" heading\n\t\t\tconst wizardVisible = await page.getByText(/Configure your first environment|Настройте|setup_title/)\n\t\t\t\t.isVisible({ timeout: 10_000 })\n\t\t\t\t.catch(() => false);\n\n\t\t\tif (!wizardVisible) {\n\t\t\t\t// Fallback: the wizard may be in Russian locale\n\t\t\t\tconst wizardFallback = await page.getByText(/первое окружение|first environment/)\n\t\t\t\t\t.isVisible({ timeout: 5_000 })\n\t\t\t\t\t.catch(() => false);\n\t\t\t\texpect(wizardFallback).toBeTruthy();\n\t\t\t} else {\n\t\t\t\texpect(wizardVisible).toBeTruthy();\n\t\t\t}\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard triggered (no environments found)');\n\t\t});\n\n\t\tawait test.step('Wizard intro screen shows \"Start setup\" button', async () => {\n\t\t\t// There are TWO buttons with \"Start setup\"/\"Начать настройку\" text:\n\t\t\t// 1. Zero-state button on the dashboard hub page (outside modal)\n\t\t\t// 2. Wizard modal button (inside .fixed.inset-0.z-50 overlay)\n\t\t\t// Scope to the wizard modal to avoid the zero-state button\n\t\t\tconst wizardModal = page.locator('.fixed.inset-0.z-50');\n\t\t\tawait expect(wizardModal.getByRole('button', { name: /Start setup|Начать/ })).toBeVisible({ timeout: 5_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard intro \"Start setup\" button visible');\n\t\t});\n\t});\n\n\t// ── 1.2. WIZARD — CREATE ENVIRONMENT ──────────────────────\n\ttest('StartupEnvironmentWizard creates first Superset environment', async ({ page }) => {\n\t\tawait test.step('Login and wait for wizard', async () => {\n\t\t\t// Use manual login same as test 1 (proven to show wizard)\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.waitForSelector('form', { timeout: 15_000 });\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 15_000 });\n\n\t\t\t// Wait for wizard — use getByText regex (same approach as test 1 which works)\n\t\t\tconst wizardVisible = await page.getByText(/Configure your first environment|Настройте первое окружение|setup_title/)\n\t\t\t\t.isVisible({ timeout: 15_000 })\n\t\t\t\t.catch(() => false);\n\t\t\texpect(wizardVisible).toBeTruthy();\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Logged in, wizard visible');\n\t\t});\n\n\t\tawait test.step('Click \"Start setup\" to open form', async () => {\n\t\t\t// Scope to wizard modal to avoid the zero-state button outside\n\t\t\tconst wizardModal = page.locator('.fixed.inset-0.z-50');\n\t\t\tawait wizardModal.getByRole('button', { name: /Start setup|Начать/ }).click();\n\t\t\t// Form should now be visible — look for ID, URL, username, password fields\n\t\t\tawait expect(page.getByText(/ID/).first()).toBeVisible({ timeout: 5_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard form opened');\n\t\t});\n\n\t\tawait test.step('Fill environment form and create', async () => {\n\t\t\tconst wizard = page.locator('.fixed.inset-0.z-50');\n\n\t\t\t// Fill environment details for ss-dev.bebesh.ru\n\t\t\t// Note: connections.* i18n keys may be missing, so use placeholder-based locators\n\t\t\tawait wizard.getByPlaceholder('dev-superset').fill('ss-dev');\n\t\t\t// Name field — placeholder \"Development\", no accessible label\n\t\t\tawait wizard.getByPlaceholder('Development').fill('ss-dev');\n\t\t\t// URL field — placeholder \"https://superset.example.com\"\n\t\t\tawait wizard.getByPlaceholder(/superset\\.example\\.com/).fill(SUPERSET_URL);\n\t\t\t// Username field — placeholder \"admin\" (scope to wizard to avoid login field)\n\t\t\tawait wizard.getByPlaceholder('admin').fill(SUPERSET_USER);\n\t\t\t// Password field — use password input type\n\t\t\tawait wizard.locator('input[type=\"password\"]').fill(SUPERSET_PASS);\n\n\t\t\t// Click \"Create environment\" button\n\t\t\tawait wizard.getByRole('button', { name: /Create environment|Создать окружение/ }).click();\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Environment form submitted');\n\t\t});\n\n\t\tawait test.step('Wizard closes, dashboard hub loads without wizard', async () => {\n\t\t\t// After successful creation, wizard should close\n\t\t\t// Wait for wizard to disappear (either \"Configure your first environment\" gone, or dashboard content appears)\n\t\t\tawait page.waitForTimeout(3_000);\n\n\t\t\t// Verify wizard is closed\n\t\t\tconst wizardStillVisible = await page.getByText(/Configure your first environment/)\n\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t.catch(() => false);\n\t\t\texpect(wizardStillVisible).toBeFalsy();\n\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard closed after environment creation');\n\t\t});\n\t});\n\n\t// ── 1.3. VERIFY ENVIRONMENT PERSISTED ─────────────────────\n\ttest('environment persists after creation and appears in settings', async ({ authPage }) => {\n\t\tconst page = authPage;\n\t\tawait test.step('Navigate to settings environments tab', async () => {\n\t\t\t// authPage fixture already logged in; go to settings\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/environments`);\n\t\t\t// Wait for settings page to load — look for the environments page content\n\t\t\tawait page.waitForTimeout(2_000);\n\t\t\t// Try to find \"Окружения\" or \"Environments\" heading\n\t\t\tconst envHeadingVisible = await page.getByText(/Окружения|Environments|Environment/)\n\t\t\t\t.first()\n\t\t\t\t.isVisible({ timeout: 15_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tconsole.log(`[E2E] ✅ Stage 1: Settings → Environments tab visible: ${envHeadingVisible}`);\n\t\t});\n\n\t\tawait test.step('Verify via API that environment is persisted', async () => {\n\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\tconst ssDevEnv = envs.find(e => e.id === 'ss-dev');\n\t\t\tif (!ssDevEnv) {\n\t\t\t\tconsole.log('[E2E] ⚠️ Stage 1: Environment ss-dev not found via API, may have failed to create');\n\t\t\t} else {\n\t\t\t\texpect(ssDevEnv).toBeDefined();\n\t\t\t\texpect(ssDevEnv.url).toContain('ss-dev.bebesh.ru');\n\t\t\t\texpect(ssDevEnv.username).toBe('admin');\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 1: API confirms env ss-dev: ${ssDevEnv.url}`);\n\t\t\t}\n\t\t});\n\t});\n\n\t// ── 1.4. DASHBOARD HUB LOADS WITHOUT WIZARD ───────────────\n\ttest('dashboard hub loads normally after environment creation', async ({ authPage }) => {\n\t\tconst page = authPage;\n\t\tawait test.step('Navigate to dashboards', async () => {\n\t\t\t// authPage fixture already logged in; go to dashboards\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards`);\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 10_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Dashboard hub reached');\n\t\t});\n\n\t\tawait test.step('No wizard appears on subsequent visits', async () => {\n\t\t\t// Verify wizard is NOT present (if environment was created in previous tests)\n\t\t\tconst wizardPresent = await page.getByText(/Configure your first environment|Настройте первое окружение/)\n\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tif (wizardPresent) {\n\t\t\t\tconsole.log('[E2E] ⚠️ Stage 1: Wizard still visible — env was not created or creation failed');\n\t\t\t} else {\n\t\t\t\tconsole.log('[E2E] ✅ Stage 1: No wizard on repeat visit');\n\t\t\t}\n\t\t});\n\n\t\tawait test.step('Environment selector visible in header', async () => {\n\t\t\t// Environment selector should now show the ss-dev environment\n\t\t\tconst envSelectorVisible = await page.getByText(/ss-dev/).first()\n\t\t\t\t.isVisible({ timeout: 5_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tconsole.log(`[E2E] ✅ Stage 1: Environment selector visible: ${envSelectorVisible}`);\n\t\t});\n\t});\n});\n// #endregion EnterpriseCleanSetupE2E\n"
+ "body": "// #region EnterpriseCleanSetupE2E [C:4] [TYPE Test] [SEMANTICS e2e, enterprise-clean, setup, onboarding, environment]\n// @BRIEF Stage 1: E2E test for enterprise-clean empty image — first-run setup via StartupEnvironmentWizard.\n// @@RATIONALE All 4 tests pass after fixing: (1) button ambiguity — zero-state page and wizard modal both have 'Начать настройку' button, resolved by scoping to wizard modal via .fixed.inset-0.z-50; (2) wizard detection — changed from waitForSelector('text=...') to getByText() with regex for locale-robust matching; (3) form fill — connections.* i18n keys missing in Docker build, switched to placeholder-based locators scoped within wizard; (4) settings navigation — use authPage fixture for consistent login\n// @@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues\n\n// Validates: bundle deployment, PostgreSQL fresh DB, initial admin bootstrap, environment creation wizard.\n// @RELATION BINDS_TO -> [StartupEnvironmentWizard]\n// @RELATION DEPENDS_ON -> [ApiHelper]\n// @UX_STATE WizardIntro -> Wizard explains setup purpose with \"Start setup\" button.\n// @UX_STATE WizardForm -> Form collects environment ID, name, URL, username, password, stage.\n// @UX_STATE WizardSaving -> Submit disabled, progress label shown.\n// @UX_STATE EnvironmentCreated -> Wizard closes, environment appears in selector, dashboards load.\n// @RATIONALE Enterprise-clean bundle ships with an empty PostgreSQL. First login MUST trigger the\n// StartupEnvironmentWizard (blocking experience). Creating the first Superset environment is the\n// critical path — if this fails, the bundle is not deliverable.\n// @REJECTED Skipping wizard via API pre-config — must test the actual user-facing wizard UX.\n// @INVARIANT Wizard appears on first login when no environments exist.\n// @INVARIANT After env creation, dashboard hub loads without wizard.\n//\n// Usage:\n// Deploy enterprise-clean stack first (docker compose -f docker-compose.enterprise-clean.yml up -d)\n// Then run: npx playwright test --grep \"Enterprise Clean Setup\"\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8000';\nconst SUPERSET_URL = 'https://ss-dev.bebesh.ru';\nconst SUPERSET_USER = 'admin';\nconst SUPERSET_PASS = 'payroll-unadorned-many';\n\ntest.describe('Enterprise Clean Setup — Stage 1: Empty Image', () => {\n\n\t// ── 1.1. FIRST LOGIN — WIZARD TRIGGER ─────────────────────\n\ttest('first login triggers StartupEnvironmentWizard on empty instance', async ({ page }) => {\n\t\tawait test.step('Login to clean instance', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.waitForSelector('form', { timeout: 15_000 });\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\t// Should redirect away from /login\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Login successful');\n\t\t});\n\n\t\tawait test.step('Dashboard redirect triggers StartupEnvironmentWizard', async () => {\n\t\t\t// After login, the HomePage redirects to /dashboards.\n\t\t\t// If no environments exist, the StartupEnvironmentWizard should appear.\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 15_000 });\n\n\t\t\t// Look for the wizard modal — it has \"Configure your first environment\" heading\n\t\t\tconst wizardVisible = await page.getByText(/Configure your first environment|Настройте|setup_title/)\n\t\t\t\t.isVisible({ timeout: 10_000 })\n\t\t\t\t.catch(() => false);\n\n\t\t\tif (!wizardVisible) {\n\t\t\t\t// Fallback: the wizard may be in Russian locale\n\t\t\t\tconst wizardFallback = await page.getByText(/первое окружение|first environment/)\n\t\t\t\t\t.isVisible({ timeout: 5_000 })\n\t\t\t\t\t.catch(() => false);\n\t\t\t\texpect(wizardFallback).toBeTruthy();\n\t\t\t} else {\n\t\t\t\texpect(wizardVisible).toBeTruthy();\n\t\t\t}\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard triggered (no environments found)');\n\t\t});\n\n\t\tawait test.step('Wizard intro screen shows \"Start setup\" button', async () => {\n\t\t\t// There are TWO buttons with \"Start setup\"/\"Начать настройку\" text:\n\t\t\t// 1. Zero-state button on the dashboard hub page (outside modal)\n\t\t\t// 2. Wizard modal button (inside .fixed.inset-0.z-50 overlay)\n\t\t\t// Scope to the wizard modal to avoid the zero-state button\n\t\t\tconst wizardModal = page.locator('.fixed.inset-0.z-50');\n\t\t\tawait expect(wizardModal.getByRole('button', { name: /Start setup|Начать/ })).toBeVisible({ timeout: 5_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard intro \"Start setup\" button visible');\n\t\t});\n\t});\n\n\t// ── 1.2. WIZARD — CREATE ENVIRONMENT ──────────────────────\n\ttest('StartupEnvironmentWizard creates first Superset environment', async ({ page }) => {\n\t\tawait test.step('Login and wait for wizard', async () => {\n\t\t\t// Use manual login same as test 1 (proven to show wizard)\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.waitForSelector('form', { timeout: 15_000 });\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 15_000 });\n\n\t\t\t// Wait for wizard — use getByText regex (same approach as test 1 which works)\n\t\t\tconst wizardVisible = await page.getByText(/Configure your first environment|Настройте первое окружение|setup_title/)\n\t\t\t\t.isVisible({ timeout: 15_000 })\n\t\t\t\t.catch(() => false);\n\t\t\texpect(wizardVisible).toBeTruthy();\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Logged in, wizard visible');\n\t\t});\n\n\t\tawait test.step('Click \"Start setup\" to open form', async () => {\n\t\t\t// Scope to wizard modal to avoid the zero-state button outside\n\t\t\tconst wizardModal = page.locator('.fixed.inset-0.z-50');\n\t\t\tawait wizardModal.getByRole('button', { name: /Start setup|Начать/ }).click();\n\t\t\t// Form should now be visible — look for ID, URL, username, password fields\n\t\t\tawait expect(page.getByText(/ID/).first()).toBeVisible({ timeout: 5_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard form opened');\n\t\t});\n\n\t\tawait test.step('Fill environment form and create', async () => {\n\t\t\tconst wizard = page.locator('.fixed.inset-0.z-50');\n\n\t\t\t// Fill environment details for ss-dev.bebesh.ru\n\t\t\t// Note: connections.* i18n keys may be missing, so use placeholder-based locators\n\t\t\tawait wizard.getByPlaceholder('dev-superset').fill('ss-dev');\n\t\t\t// Name field — placeholder \"Development\", no accessible label\n\t\t\tawait wizard.getByPlaceholder('Development').fill('ss-dev');\n\t\t\t// URL field — placeholder \"https://superset.example.com\"\n\t\t\tawait wizard.getByPlaceholder(/superset\\.example\\.com/).fill(SUPERSET_URL);\n\t\t\t// Username field — placeholder \"admin\" (scope to wizard to avoid login field)\n\t\t\tawait wizard.getByPlaceholder('admin').fill(SUPERSET_USER);\n\t\t\t// Password field — use password input type\n\t\t\tawait wizard.locator('input[type=\"password\"]').fill(SUPERSET_PASS);\n\n\t\t\t// Click \"Create environment\" button\n\t\t\tawait wizard.getByRole('button', { name: /Create environment|Создать окружение/ }).click();\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Environment form submitted');\n\t\t});\n\n\t\tawait test.step('Wizard closes, dashboard hub loads without wizard', async () => {\n\t\t\t// After successful creation, wizard should close\n\t\t\t// Wait for wizard to disappear (either \"Configure your first environment\" gone, or dashboard content appears)\n\t\t\tawait page.waitForTimeout(3_000);\n\n\t\t\t// Verify wizard is closed\n\t\t\tconst wizardStillVisible = await page.getByText(/Configure your first environment/)\n\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t.catch(() => false);\n\t\t\texpect(wizardStillVisible).toBeFalsy();\n\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Wizard closed after environment creation');\n\t\t});\n\t});\n\n\t// ── 1.3. VERIFY ENVIRONMENT PERSISTED ─────────────────────\n\ttest('environment persists after creation and appears in settings', async ({ authPage }) => {\n\t\tconst page = authPage;\n\t\tawait test.step('Navigate to settings environments tab', async () => {\n\t\t\t// authPage fixture already logged in; go to settings\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/environments`);\n\t\t\t// Wait for settings page to load — look for the environments page content\n\t\t\tawait page.waitForTimeout(2_000);\n\t\t\t// Try to find \"Окружения\" or \"Environments\" heading\n\t\t\tconst envHeadingVisible = await page.getByText(/Окружения|Environments|Environment/)\n\t\t\t\t.first()\n\t\t\t\t.isVisible({ timeout: 15_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tconsole.log(`[E2E] ✅ Stage 1: Settings → Environments tab visible: ${envHeadingVisible}`);\n\t\t});\n\n\t\tawait test.step('Verify via API that environment is persisted', async () => {\n\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\tconst ssDevEnv = envs.find(e => e.id === 'ss-dev');\n\t\t\tif (!ssDevEnv) {\n\t\t\t\tconsole.log('[E2E] ⚠️ Stage 1: Environment ss-dev not found via API, may have failed to create');\n\t\t\t} else {\n\t\t\t\texpect(ssDevEnv).toBeDefined();\n\t\t\t\texpect(ssDevEnv.url).toContain('ss-dev.bebesh.ru');\n\t\t\t\texpect(ssDevEnv.username).toBe('admin');\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 1: API confirms env ss-dev: ${ssDevEnv.url}`);\n\t\t\t}\n\t\t});\n\t});\n\n\t// ── 1.4. DASHBOARD HUB LOADS WITHOUT WIZARD ───────────────\n\ttest('dashboard hub loads normally after environment creation', async ({ authPage }) => {\n\t\tconst page = authPage;\n\t\tawait test.step('Navigate to dashboards', async () => {\n\t\t\t// authPage fixture already logged in; go to dashboards\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards`);\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 10_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 1: Dashboard hub reached');\n\t\t});\n\n\t\tawait test.step('No wizard appears on subsequent visits', async () => {\n\t\t\t// Verify wizard is NOT present (if environment was created in previous tests)\n\t\t\tconst wizardPresent = await page.getByText(/Configure your first environment|Настройте первое окружение/)\n\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tif (wizardPresent) {\n\t\t\t\tconsole.log('[E2E] ⚠️ Stage 1: Wizard still visible — env was not created or creation failed');\n\t\t\t} else {\n\t\t\t\tconsole.log('[E2E] ✅ Stage 1: No wizard on repeat visit');\n\t\t\t}\n\t\t});\n\n\t\tawait test.step('Environment selector visible in header', async () => {\n\t\t\t// Environment selector should now show the ss-dev environment\n\t\t\tconst envSelectorVisible = await page.getByText(/ss-dev/).first()\n\t\t\t\t.isVisible({ timeout: 5_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tconsole.log(`[E2E] ✅ Stage 1: Environment selector visible: ${envSelectorVisible}`);\n\t\t});\n\t});\n});\n// #endregion EnterpriseCleanSetupE2E\n"
},
{
"contract_id": "GitE2E",
@@ -63589,14 +58767,14 @@
{
"source_id": "GitE2E",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:list:GitDashboardPage_GitConfigRoutes]",
- "target_ref": "[[EXT:list:GitDashboardPage_GitConfigRoutes]]"
+ "target_id": "GitSettingsPage",
+ "target_ref": "[GitSettingsPage]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region GitE2E [C:3] [TYPE Test] [SEMANTICS e2e, git, integration, config]\n// @BRIEF E2E tests for Git integration — config CRUD, connection test.\n// @RELATION BINDS_TO -> [[EXT:list:GitDashboardPage_GitConfigRoutes]]\n// @UX_STATE ConfigCreated -> Git server appears in configured list.\n// @UX_STATE ConnectionTested -> Success/failure toast feedback.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost, apiDelete } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\nconst GITEA_URL = process.env.GITEA_URL || 'https://git.bebesh.ru';\nconst GITEA_TOKEN = process.env.GITEA_TOKEN || 'd5e3a0bea62121dcafbf33070e85d65e8a383c20';\n\ntest.describe('Git Integration', () => {\n\ttest('should have git config visible in settings UI', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\tawait authPage.waitForSelector('text=Интеграция Git', { timeout: 10_000 });\n\n\t\t// Configured servers section visible\n\t\tawait expect(authPage.getByText(/Настроенные серверы/)).toBeVisible();\n\t\t// Add git server form visible\n\t\tawait expect(authPage.getByText(/Добавить Git-сервер|Add Git server/)).toBeVisible();\n\t});\n\n\ttest('should create git config via API and verify in UI', async ({ authPage }) => {\n\t\tconst configName = `E2E-Gitea-${Date.now()}`;\n\n\t\t// Create via API\n\t\tconst config = await apiPost('/api/git/config', {\n\t\t\tname: configName,\n\t\t\tprovider: 'GITEA',\n\t\t\turl: GITEA_URL,\n\t\t\tpat: GITEA_TOKEN,\n\t\t\tdefault_repository: 'busya/ss-tools',\n\t\t\tdefault_branch: 'main',\n\t\t});\n\t\texpect(config).toBeDefined();\n\t\texpect(config.id).toBeTruthy();\n\t\texpect(config.provider).toBe('GITEA');\n\n\t\t// Verify in UI\n\t\tawait authPage.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\tawait authPage.waitForSelector('text=Интеграция Git', { timeout: 10_000 });\n\t\tawait expect(authPage.getByText(configName).first()).toBeVisible({ timeout: 10_000 });\n\n\t\t// Cleanup\n\t\tawait apiDelete(`/api/git/config/${config.id}`);\n\t});\n\n\ttest('should test git connection successfully', async ({ authPage }) => {\n\t\t// Get existing configs\n\t\tconst configs = await apiGet('/api/git/config');\n\t\tif (configs.length === 0) {\n\t\t\tconsole.log('[E2E] No git configs to test, skipping');\n\t\t\treturn;\n\t\t}\n\n\t\tconst config = configs[0];\n\t\tconst result = await apiPost('/api/git/config/test', {\n\t\t\tname: config.name,\n\t\t\tprovider: config.provider,\n\t\t\turl: config.url,\n\t\t\tpat: GITEA_TOKEN,\n\t\t\tconfig_id: config.id,\n\t\t});\n\t\texpect(result.status).toBe('success');\n\t});\n\n\ttest('should list Gitea repositories', async ({ authPage }) => {\n\t\tconst configs = await apiGet('/api/git/config');\n\t\tif (configs.length === 0) {\n\t\t\tconsole.log('[E2E] No git configs to list repos, skipping');\n\t\t\treturn;\n\t\t}\n\n\t\tconst config = configs[0];\n\t\tif (config.provider !== 'GITEA') {\n\t\t\tconsole.log('[E2E] Provider is not GITEA, skipping');\n\t\t\treturn;\n\t\t}\n\n\t\tconst repos = await apiGet(`/api/git/config/${config.id}/gitea/repos`);\n\t\texpect(Array.isArray(repos)).toBeTruthy();\n\t\texpect(repos.length).toBeGreaterThan(0);\n\t\t// Should include the ss-tools repo\n\t\tconst hasSsTools = repos.some(r => r.full_name?.includes('ss-tools'));\n\t\texpect(hasSsTools).toBeTruthy();\n\t});\n});\n// #endregion GitE2E\n"
+ "body": "// #region GitE2E [C:3] [TYPE Test] [SEMANTICS e2e, git, integration, config]\n// @BRIEF E2E tests for Git integration — config CRUD, connection test.\n// @RELATION BINDS_TO -> [GitSettingsPage]\n// @UX_STATE ConfigCreated -> Git server appears in configured list.\n// @UX_STATE ConnectionTested -> Success/failure toast feedback.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost, apiDelete } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\nconst GITEA_URL = process.env.GITEA_URL || 'https://git.bebesh.ru';\nconst GITEA_TOKEN = process.env.GITEA_TOKEN || 'd5e3a0bea62121dcafbf33070e85d65e8a383c20';\n\ntest.describe('Git Integration', () => {\n\ttest('should have git config visible in settings UI', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\tawait authPage.waitForSelector('text=Интеграция Git', { timeout: 10_000 });\n\n\t\t// Configured servers section visible\n\t\tawait expect(authPage.getByText(/Настроенные серверы/)).toBeVisible();\n\t\t// Add git server form visible\n\t\tawait expect(authPage.getByText(/Добавить Git-сервер|Add Git server/)).toBeVisible();\n\t});\n\n\ttest('should create git config via API and verify in UI', async ({ authPage }) => {\n\t\tconst configName = `E2E-Gitea-${Date.now()}`;\n\n\t\t// Create via API\n\t\tconst config = await apiPost('/api/git/config', {\n\t\t\tname: configName,\n\t\t\tprovider: 'GITEA',\n\t\t\turl: GITEA_URL,\n\t\t\tpat: GITEA_TOKEN,\n\t\t\tdefault_repository: 'busya/ss-tools',\n\t\t\tdefault_branch: 'main',\n\t\t});\n\t\texpect(config).toBeDefined();\n\t\texpect(config.id).toBeTruthy();\n\t\texpect(config.provider).toBe('GITEA');\n\n\t\t// Verify in UI\n\t\tawait authPage.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\tawait authPage.waitForSelector('text=Интеграция Git', { timeout: 10_000 });\n\t\tawait expect(authPage.getByText(configName).first()).toBeVisible({ timeout: 10_000 });\n\n\t\t// Cleanup\n\t\tawait apiDelete(`/api/git/config/${config.id}`);\n\t});\n\n\ttest('should test git connection successfully', async ({ authPage }) => {\n\t\t// Get existing configs\n\t\tconst configs = await apiGet('/api/git/config');\n\t\tif (configs.length === 0) {\n\t\t\tconsole.log('[E2E] No git configs to test, skipping');\n\t\t\treturn;\n\t\t}\n\n\t\tconst config = configs[0];\n\t\tconst result = await apiPost('/api/git/config/test', {\n\t\t\tname: config.name,\n\t\t\tprovider: config.provider,\n\t\t\turl: config.url,\n\t\t\tpat: GITEA_TOKEN,\n\t\t\tconfig_id: config.id,\n\t\t});\n\t\texpect(result.status).toBe('success');\n\t});\n\n\ttest('should list Gitea repositories', async ({ authPage }) => {\n\t\tconst configs = await apiGet('/api/git/config');\n\t\tif (configs.length === 0) {\n\t\t\tconsole.log('[E2E] No git configs to list repos, skipping');\n\t\t\treturn;\n\t\t}\n\n\t\tconst config = configs[0];\n\t\tif (config.provider !== 'GITEA') {\n\t\t\tconsole.log('[E2E] Provider is not GITEA, skipping');\n\t\t\treturn;\n\t\t}\n\n\t\tconst repos = await apiGet(`/api/git/config/${config.id}/gitea/repos`);\n\t\texpect(Array.isArray(repos)).toBeTruthy();\n\t\texpect(repos.length).toBeGreaterThan(0);\n\t\t// Should include the ss-tools repo\n\t\tconst hasSsTools = repos.some(r => r.full_name?.includes('ss-tools'));\n\t\texpect(hasSsTools).toBeTruthy();\n\t});\n});\n// #endregion GitE2E\n"
},
{
"contract_id": "LiveProjectCheckE2E",
@@ -63614,7 +58792,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region LiveProjectCheckE2E [C:4] [TYPE Test] [SEMANTICS e2e, live-project, verification, dashboard, llm, settings]\n// @BRIEF Stage 2: E2E test for live project verification — validates dashboard LLM analysis,\n// settings modification, and overall project health after ./run.sh startup.\n// @RELATION BINDS_TO -> [[EXT:list:DashboardHub_LLM_SettingsPage]]\n// @RELATION DEPENDS_ON -> [ApiHelper]\n// @UX_STATE DashboardsLoaded -> Dashboard hub with environment context, dashboard cards visible.\n// @UX_STATE LLMAnalysis -> LLM analysis triggered and report generated for a dashboard.\n// @UX_STATE SettingsChanged -> Setting value modified and persisted across reload.\n// @RATIONALE After ./run.sh launches the local dev stack, the project should be fully operational.\n// This test verifies the critical paths: login, dashboard rendering with LLM analysis,\n// and settings persistence — ensuring dev stack is healthy before image delivery.\n// @REJECTED Testing individual API endpoints in isolation — must test full UI flow for delivery sign-off.\n// @INVARIANT LLM provider must be configured for LLM analysis to work.\n// @INVARIANT Settings changes persist after page reload.\n//\n// Usage:\n// Start dev stack: ./run.sh\n// Then run: npx playwright test --grep \"Live Project Check\"\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\nconst BACKEND_URL = process.env.BACKEND_URL || 'http://127.0.0.1:8101';\n\ntest.describe('Live Project Check — Stage 2: Verification', () => {\n\n\t// ── 2.1. LOGIN ───────────────────────────────────────────\n\ttest('login to live project with admin/admin123', async ({ page }) => {\n\t\tawait test.step('Navigate to login page', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.waitForSelector('form', { timeout: 15_000 });\n\t\t\tawait expect(page.getByRole('heading', { name: /Вход|Login/ })).toBeVisible();\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Login page loaded');\n\t\t});\n\n\t\tawait test.step('Submit credentials', async () => {\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\t// Use .first() to avoid strict mode violation with multiple elements\n\t\t\tconst navVisible = await page.locator('nav').first().isVisible({ timeout: 10_000 }).catch(() => false);\n\t\t\texpect(navVisible).toBeTruthy();\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Login successful, sidebar visible');\n\t\t});\n\t});\n\n\t// ── 2.2. DASHBOARD HUB — VERIFY DASHBOARDS LOAD ──────────\n\ttest('dashboard hub loads with environment and dashboard list', async ({ page }) => {\n\t\tawait test.step('Login and navigate to dashboards', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\n\t\t\t// Navigate to dashboards hub\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards`);\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 10_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Dashboard hub page reached');\n\t\t});\n\n\t\tawait test.step('Environment context is loaded', async () => {\n\t\t\t// Environment selector should be visible — check via API that envs exist\n\t\t\t// and verify UI has loaded content\n\t\t\ttry {\n\t\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\t\texpect(Array.isArray(envs)).toBeTruthy();\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: ${envs.length} environments configured via API`);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: API env check: ${e.message}`);\n\t\t\t}\n\t\t\t// Check that the dashboard page rendered content\n\t\t\tconst pageContent = await page.locator('body').textContent();\n\t\t\tconst hasContent = pageContent && pageContent.length > 100;\n\t\t\texpect(hasContent).toBeTruthy();\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Dashboard page rendered (content length: ${pageContent?.length || 0})`);\n\t\t});\n\n\t\tawait test.step('Dashboards list loads or empty state renders', async () => {\n\t\t\t// Wait for either dashboard cards or a \"no dashboards\" state\n\t\t\tawait page.waitForTimeout(3_000);\n\n\t\t\t// Try to find dashboard-related content\n\t\t\tconst hasContent = await page.getByText(/дашборд|dashboard|no dashboards|нет дашбордов/i)\n\t\t\t\t.first()\n\t\t\t\t.isVisible({ timeout: 5_000 })\n\t\t\t\t.catch(() => false);\n\n\t\t\t// Either dashboards exist or empty state is shown — both are valid\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Dashboard hub rendered (has content: ${hasContent})`);\n\t\t});\n\t});\n\n\t// ── 2.3. LLM ANALYSIS OF DASHBOARD ───────────────────────\n\ttest('LLM analysis and dashboard check', async ({ page }) => {\n\t\tawait test.step('Verify LLM provider is configured', async () => {\n\t\t\t// Check via API that LLM is set up\n\t\t\tconst llmConfigs = await apiGet('/api/llm/status');\n\t\t\texpect(llmConfigs.configured).toBe(true);\n\t\t\texpect(llmConfigs.provider_count).toBeGreaterThanOrEqual(1);\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: LLM configured (${llmConfigs.provider_name})`);\n\t\t});\n\n\t\tawait test.step('Login and go to dashboards', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards`);\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 10_000 });\n\t\t});\n\n\t\tawait test.step('Trigger LLM analysis on a dashboard', async () => {\n\t\t\t// Try to find an LLM analyze button or menu item\n\t\t\tconst llmButton = page.getByRole('button', { name: /LLM|Анализ|Analyze|Проверить/i }).first();\n\t\t\tconst llmButtonVisible = await llmButton.isVisible({ timeout: 5_000 }).catch(() => false);\n\n\t\t\tif (llmButtonVisible) {\n\t\t\t\tawait llmButton.click();\n\t\t\t\tconsole.log('[E2E] ✅ Stage 2: LLM analysis triggered via button');\n\t\t\t\t// Wait for analysis to complete or modal to appear\n\t\t\t\tawait page.waitForTimeout(5_000);\n\t\t\t} else {\n\t\t\t\t// Direct API approach: trigger LLM analysis on a dashboard in the ss-dev env\n\t\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\t\t// Find a non-prod environment that's likely reachable\n\t\t\t\tconst targetEnv = envs.find(e => e.id !== 'prod' && e.id !== 'ss-prod') || envs[0];\n\t\t\t\tif (targetEnv && targetEnv.id) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dashboards = await apiGet(`/api/dashboards?env_id=${targetEnv.id}`);\n\t\t\t\t\t\tif (dashboards.length > 0) {\n\t\t\t\t\t\t\tconst dashboardId = dashboards[0].id || dashboards[0].dashboard_id;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst analysis = await apiPost(`/api/dashboards/${dashboardId}/llm-analyze`, {\n\t\t\t\t\t\t\t\t\tenv_id: targetEnv.id,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: LLM analysis launched for dashboard ${dashboardId} (env: ${targetEnv.id}): ${analysis?.task_id || 'completed'}`);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM analysis API call: ${e.message}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: No dashboards available in env '${targetEnv.id}'`);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: Dashboards fetch for env '${targetEnv.id}': ${e.message}`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: No environments configured for LLM analysis');\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait test.step('Verify LLM analysis results exist', async () => {\n\t\t\t// Check if LLM analysis reports exist\n\t\t\ttry {\n\t\t\t\tconst reports = await apiGet('/api/reports/llm');\n\t\t\t\tif (Array.isArray(reports) && reports.length > 0) {\n\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: ${reports.length} LLM analysis reports found`);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: No LLM reports yet (analysis may still be running)');\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM reports endpoint: ${e.message}`);\n\t\t\t}\n\t\t});\n\t});\n\n\t// ── 2.4. SETTINGS CHANGE ──────────────────────────────────\n\ttest('settings modification persists', async ({ page }) => {\n\t\tconst testSettingKey = 'e2e_test_timestamp';\n\t\tconst testSettingValue = `e2e-${Date.now()}`;\n\n\t\tawait test.step('Login and navigate to settings', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings`);\n\t\t\tawait page.waitForURL(/\\/settings/, { timeout: 10_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Settings page loaded');\n\t\t});\n\n\t\tawait test.step('Modify a setting and save', async () => {\n\t\t\t// Try to find settings that can be changed — look for inputs, toggles, selects\n\t\t\t// First, try LLM settings tab\n\t\t\ttry {\n\t\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/llm`);\n\t\t\t\tawait page.waitForTimeout(2_000);\n\n\t\t\t\t// Check if we can access LLM settings\n\t\t\t\tconst llmSection = await page.getByText(/LLM/).first()\n\t\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t\t.catch(() => false);\n\n\t\t\t\tif (llmSection) {\n\t\t\t\t\tconsole.log('[E2E] ✅ Stage 2: LLM settings tab accessible');\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM settings navigation: ${e.message}`);\n\t\t\t}\n\n\t\t\t// Try global settings or consolidated settings via API to verify write path\n\t\t\ttry {\n\t\t\t\tconst settings = await apiGet('/api/settings/consolidated');\n\t\t\t\texpect(settings).toBeDefined();\n\n\t\t\t\t// Attempt to update settings\n\t\t\t\tconst updatePayload = {\n\t\t\t\t\t...settings,\n\t\t\t\t\t[testSettingKey]: testSettingValue,\n\t\t\t\t};\n\t\t\t\tawait apiPost('/api/settings/consolidated', updatePayload);\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Setting ${testSettingKey} updated via API`);\n\n\t\t\t\t// Verify the change persisted\n\t\t\t\tconst verifySettings = await apiGet('/api/settings/consolidated');\n\t\t\t\t// eslint-disable-next-line no-prototype-builtins\n\t\t\t\tconst saved = verifySettings[testSettingKey] || verifySettings?.settings?.[testSettingKey];\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Setting persistence verified: ${saved === testSettingValue}`);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: Settings API: ${e.message}`);\n\t\t\t}\n\t\t});\n\n\t\tawait test.step('Verify settings tab navigation works', async () => {\n\t\t\t// Verify the settings UI structure is intact\n\t\t\t// Navigate to specific settings tabs via URL hash for reliability\n\t\t\tconst tabHashes = ['/settings/environments', '/settings/llm', '/settings/git'];\n\t\t\tlet loadedTabs = 0;\n\n\t\t\tfor (const hash of tabHashes) {\n\t\t\t\ttry {\n\t\t\t\t\tawait page.goto(`${FRONTEND_URL}/settings#${hash}`, { waitUntil: 'domcontentloaded', timeout: 10_000 });\n\t\t\t\t\tawait page.waitForTimeout(2_000);\n\t\t\t\t\t// Check if page has any content (not blank)\n\t\t\t\t\tconst bodyText = await page.locator('body').textContent();\n\t\t\t\t\tif (bodyText && bodyText.length > 50) {\n\t\t\t\t\t\tloadedTabs++;\n\t\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Settings tab ${hash} loaded (${bodyText.length} chars)`);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: Settings tab ${hash}: ${e.message}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(loadedTabs).toBeGreaterThanOrEqual(1);\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Settings tabs loaded: ${loadedTabs}/${tabHashes.length}`);\n\t\t});\n\t});\n\n\t// ── 2.5. HEALTH CHECK ────────────────────────────────────\n\ttest('backend health summary is healthy', async ({ page }) => {\n\t\tawait test.step('Fetch health summary via API', async () => {\n\t\t\tconst health = await apiGet('/api/health/summary');\n\t\t\texpect(health).toBeDefined();\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Backend health summary: ${JSON.stringify(health).slice(0, 200)}`);\n\t\t});\n\n\t\tawait test.step('Login and verify health page loads', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\n\t\t\t// Try health page if it exists\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards/health`).catch(() => {\n\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: Health page route not available');\n\t\t\t});\n\t\t});\n\t});\n\n\t// ── 2.6. LLM ANALYSIS REPORT (if LLM configured) ─────────\n\ttest('LLM dashboard check report can be viewed', async ({ page }) => {\n\t\tawait test.step('Login and check for LLM reports', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t});\n\n\t\tawait test.step('Navigate to reports page', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/reports`);\n\t\t\tawait page.waitForTimeout(3_000);\n\n\t\t\tconst reportsContent = await page.getByText(/отчет|report|llm/i)\n\t\t\t\t.first()\n\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Reports page loaded (LLM content: ${reportsContent})`);\n\t\t});\n\n\t\tawait test.step('Check LLM reports via API', async () => {\n\t\t\ttry {\n\t\t\t\tconst reports = await apiGet('/api/reports/llm');\n\t\t\t\tif (Array.isArray(reports) && reports.length > 0) {\n\t\t\t\t\tconst latestReport = reports[reports.length - 1];\n\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Latest LLM report: ${latestReport.id || 'N/A'} — ${latestReport.status || 'unknown'}`);\n\n\t\t\t\t\t// Try to view a specific report if there's a detail page\n\t\t\t\t\tif (latestReport.task_id) {\n\t\t\t\t\t\tawait page.goto(`${FRONTEND_URL}/reports/llm/${latestReport.task_id}`).catch(() => {\n\t\t\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: LLM report detail page not available');\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: No LLM reports available yet');\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM reports: ${e.message}`);\n\t\t\t}\n\t\t});\n\t});\n});\n// #endregion LiveProjectCheckE2E\n"
+ "body": "// #region LiveProjectCheckE2E [C:4] [TYPE Test] [SEMANTICS e2e, live-project, verification, dashboard, llm, settings]\n// @BRIEF Stage 2: E2E test for live project verification — validates dashboard LLM analysis,\n// settings modification, and overall project health after ./run.sh startup.\n// @RELATION BINDS_TO -> [DashboardHub]\n// @RELATION DEPENDS_ON -> [ApiHelper]\n// @UX_STATE DashboardsLoaded -> Dashboard hub with environment context, dashboard cards visible.\n// @UX_STATE LLMAnalysis -> LLM analysis triggered and report generated for a dashboard.\n// @UX_STATE SettingsChanged -> Setting value modified and persisted across reload.\n// @RATIONALE After ./run.sh launches the local dev stack, the project should be fully operational.\n// This test verifies the critical paths: login, dashboard rendering with LLM analysis,\n// and settings persistence — ensuring dev stack is healthy before image delivery.\n// @REJECTED Testing individual API endpoints in isolation — must test full UI flow for delivery sign-off.\n// @INVARIANT LLM provider must be configured for LLM analysis to work.\n// @INVARIANT Settings changes persist after page reload.\n//\n// Usage:\n// Start dev stack: ./run.sh\n// Then run: npx playwright test --grep \"Live Project Check\"\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\nconst BACKEND_URL = process.env.BACKEND_URL || 'http://127.0.0.1:8101';\n\ntest.describe('Live Project Check — Stage 2: Verification', () => {\n\n\t// ── 2.1. LOGIN ───────────────────────────────────────────\n\ttest('login to live project with admin/admin123', async ({ page }) => {\n\t\tawait test.step('Navigate to login page', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.waitForSelector('form', { timeout: 15_000 });\n\t\t\tawait expect(page.getByRole('heading', { name: /Вход|Login/ })).toBeVisible();\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Login page loaded');\n\t\t});\n\n\t\tawait test.step('Submit credentials', async () => {\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\t// Use .first() to avoid strict mode violation with multiple elements\n\t\t\tconst navVisible = await page.locator('nav').first().isVisible({ timeout: 10_000 }).catch(() => false);\n\t\t\texpect(navVisible).toBeTruthy();\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Login successful, sidebar visible');\n\t\t});\n\t});\n\n\t// ── 2.2. DASHBOARD HUB — VERIFY DASHBOARDS LOAD ──────────\n\ttest('dashboard hub loads with environment and dashboard list', async ({ page }) => {\n\t\tawait test.step('Login and navigate to dashboards', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\n\t\t\t// Navigate to dashboards hub\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards`);\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 10_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Dashboard hub page reached');\n\t\t});\n\n\t\tawait test.step('Environment context is loaded', async () => {\n\t\t\t// Environment selector should be visible — check via API that envs exist\n\t\t\t// and verify UI has loaded content\n\t\t\ttry {\n\t\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\t\texpect(Array.isArray(envs)).toBeTruthy();\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: ${envs.length} environments configured via API`);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: API env check: ${e.message}`);\n\t\t\t}\n\t\t\t// Check that the dashboard page rendered content\n\t\t\tconst pageContent = await page.locator('body').textContent();\n\t\t\tconst hasContent = pageContent && pageContent.length > 100;\n\t\t\texpect(hasContent).toBeTruthy();\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Dashboard page rendered (content length: ${pageContent?.length || 0})`);\n\t\t});\n\n\t\tawait test.step('Dashboards list loads or empty state renders', async () => {\n\t\t\t// Wait for either dashboard cards or a \"no dashboards\" state\n\t\t\tawait page.waitForTimeout(3_000);\n\n\t\t\t// Try to find dashboard-related content\n\t\t\tconst hasContent = await page.getByText(/дашборд|dashboard|no dashboards|нет дашбордов/i)\n\t\t\t\t.first()\n\t\t\t\t.isVisible({ timeout: 5_000 })\n\t\t\t\t.catch(() => false);\n\n\t\t\t// Either dashboards exist or empty state is shown — both are valid\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Dashboard hub rendered (has content: ${hasContent})`);\n\t\t});\n\t});\n\n\t// ── 2.3. LLM ANALYSIS OF DASHBOARD ───────────────────────\n\ttest('LLM analysis and dashboard check', async ({ page }) => {\n\t\tawait test.step('Verify LLM provider is configured', async () => {\n\t\t\t// Check via API that LLM is set up\n\t\t\tconst llmConfigs = await apiGet('/api/llm/status');\n\t\t\texpect(llmConfigs.configured).toBe(true);\n\t\t\texpect(llmConfigs.provider_count).toBeGreaterThanOrEqual(1);\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: LLM configured (${llmConfigs.provider_name})`);\n\t\t});\n\n\t\tawait test.step('Login and go to dashboards', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards`);\n\t\t\tawait page.waitForURL(/\\/dashboards/, { timeout: 10_000 });\n\t\t});\n\n\t\tawait test.step('Trigger LLM analysis on a dashboard', async () => {\n\t\t\t// Try to find an LLM analyze button or menu item\n\t\t\tconst llmButton = page.getByRole('button', { name: /LLM|Анализ|Analyze|Проверить/i }).first();\n\t\t\tconst llmButtonVisible = await llmButton.isVisible({ timeout: 5_000 }).catch(() => false);\n\n\t\t\tif (llmButtonVisible) {\n\t\t\t\tawait llmButton.click();\n\t\t\t\tconsole.log('[E2E] ✅ Stage 2: LLM analysis triggered via button');\n\t\t\t\t// Wait for analysis to complete or modal to appear\n\t\t\t\tawait page.waitForTimeout(5_000);\n\t\t\t} else {\n\t\t\t\t// Direct API approach: trigger LLM analysis on a dashboard in the ss-dev env\n\t\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\t\t// Find a non-prod environment that's likely reachable\n\t\t\t\tconst targetEnv = envs.find(e => e.id !== 'prod' && e.id !== 'ss-prod') || envs[0];\n\t\t\t\tif (targetEnv && targetEnv.id) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dashboards = await apiGet(`/api/dashboards?env_id=${targetEnv.id}`);\n\t\t\t\t\t\tif (dashboards.length > 0) {\n\t\t\t\t\t\t\tconst dashboardId = dashboards[0].id || dashboards[0].dashboard_id;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst analysis = await apiPost(`/api/dashboards/${dashboardId}/llm-analyze`, {\n\t\t\t\t\t\t\t\t\tenv_id: targetEnv.id,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: LLM analysis launched for dashboard ${dashboardId} (env: ${targetEnv.id}): ${analysis?.task_id || 'completed'}`);\n\t\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM analysis API call: ${e.message}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: No dashboards available in env '${targetEnv.id}'`);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: Dashboards fetch for env '${targetEnv.id}': ${e.message}`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: No environments configured for LLM analysis');\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tawait test.step('Verify LLM analysis results exist', async () => {\n\t\t\t// Check if LLM analysis reports exist\n\t\t\ttry {\n\t\t\t\tconst reports = await apiGet('/api/reports/llm');\n\t\t\t\tif (Array.isArray(reports) && reports.length > 0) {\n\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: ${reports.length} LLM analysis reports found`);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: No LLM reports yet (analysis may still be running)');\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM reports endpoint: ${e.message}`);\n\t\t\t}\n\t\t});\n\t});\n\n\t// ── 2.4. SETTINGS CHANGE ──────────────────────────────────\n\ttest('settings modification persists', async ({ page }) => {\n\t\tconst testSettingKey = 'e2e_test_timestamp';\n\t\tconst testSettingValue = `e2e-${Date.now()}`;\n\n\t\tawait test.step('Login and navigate to settings', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings`);\n\t\t\tawait page.waitForURL(/\\/settings/, { timeout: 10_000 });\n\t\t\tconsole.log('[E2E] ✅ Stage 2: Settings page loaded');\n\t\t});\n\n\t\tawait test.step('Modify a setting and save', async () => {\n\t\t\t// Try to find settings that can be changed — look for inputs, toggles, selects\n\t\t\t// First, try LLM settings tab\n\t\t\ttry {\n\t\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/llm`);\n\t\t\t\tawait page.waitForTimeout(2_000);\n\n\t\t\t\t// Check if we can access LLM settings\n\t\t\t\tconst llmSection = await page.getByText(/LLM/).first()\n\t\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t\t.catch(() => false);\n\n\t\t\t\tif (llmSection) {\n\t\t\t\t\tconsole.log('[E2E] ✅ Stage 2: LLM settings tab accessible');\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM settings navigation: ${e.message}`);\n\t\t\t}\n\n\t\t\t// Try global settings or consolidated settings via API to verify write path\n\t\t\ttry {\n\t\t\t\tconst settings = await apiGet('/api/settings/consolidated');\n\t\t\t\texpect(settings).toBeDefined();\n\n\t\t\t\t// Attempt to update settings\n\t\t\t\tconst updatePayload = {\n\t\t\t\t\t...settings,\n\t\t\t\t\t[testSettingKey]: testSettingValue,\n\t\t\t\t};\n\t\t\t\tawait apiPost('/api/settings/consolidated', updatePayload);\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Setting ${testSettingKey} updated via API`);\n\n\t\t\t\t// Verify the change persisted\n\t\t\t\tconst verifySettings = await apiGet('/api/settings/consolidated');\n\t\t\t\t// eslint-disable-next-line no-prototype-builtins\n\t\t\t\tconst saved = verifySettings[testSettingKey] || verifySettings?.settings?.[testSettingKey];\n\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Setting persistence verified: ${saved === testSettingValue}`);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: Settings API: ${e.message}`);\n\t\t\t}\n\t\t});\n\n\t\tawait test.step('Verify settings tab navigation works', async () => {\n\t\t\t// Verify the settings UI structure is intact\n\t\t\t// Navigate to specific settings tabs via URL hash for reliability\n\t\t\tconst tabHashes = ['/settings/environments', '/settings/llm', '/settings/git'];\n\t\t\tlet loadedTabs = 0;\n\n\t\t\tfor (const hash of tabHashes) {\n\t\t\t\ttry {\n\t\t\t\t\tawait page.goto(`${FRONTEND_URL}/settings#${hash}`, { waitUntil: 'domcontentloaded', timeout: 10_000 });\n\t\t\t\t\tawait page.waitForTimeout(2_000);\n\t\t\t\t\t// Check if page has any content (not blank)\n\t\t\t\t\tconst bodyText = await page.locator('body').textContent();\n\t\t\t\t\tif (bodyText && bodyText.length > 50) {\n\t\t\t\t\t\tloadedTabs++;\n\t\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Settings tab ${hash} loaded (${bodyText.length} chars)`);\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: Settings tab ${hash}: ${e.message}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(loadedTabs).toBeGreaterThanOrEqual(1);\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Settings tabs loaded: ${loadedTabs}/${tabHashes.length}`);\n\t\t});\n\t});\n\n\t// ── 2.5. HEALTH CHECK ────────────────────────────────────\n\ttest('backend health summary is healthy', async ({ page }) => {\n\t\tawait test.step('Fetch health summary via API', async () => {\n\t\t\tconst health = await apiGet('/api/health/summary');\n\t\t\texpect(health).toBeDefined();\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Backend health summary: ${JSON.stringify(health).slice(0, 200)}`);\n\t\t});\n\n\t\tawait test.step('Login and verify health page loads', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\n\t\t\t// Try health page if it exists\n\t\t\tawait page.goto(`${FRONTEND_URL}/dashboards/health`).catch(() => {\n\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: Health page route not available');\n\t\t\t});\n\t\t});\n\t});\n\n\t// ── 2.6. LLM ANALYSIS REPORT (if LLM configured) ─────────\n\ttest('LLM dashboard check report can be viewed', async ({ page }) => {\n\t\tawait test.step('Login and check for LLM reports', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t});\n\n\t\tawait test.step('Navigate to reports page', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/reports`);\n\t\t\tawait page.waitForTimeout(3_000);\n\n\t\t\tconst reportsContent = await page.getByText(/отчет|report|llm/i)\n\t\t\t\t.first()\n\t\t\t\t.isVisible({ timeout: 3_000 })\n\t\t\t\t.catch(() => false);\n\t\t\tconsole.log(`[E2E] ✅ Stage 2: Reports page loaded (LLM content: ${reportsContent})`);\n\t\t});\n\n\t\tawait test.step('Check LLM reports via API', async () => {\n\t\t\ttry {\n\t\t\t\tconst reports = await apiGet('/api/reports/llm');\n\t\t\t\tif (Array.isArray(reports) && reports.length > 0) {\n\t\t\t\t\tconst latestReport = reports[reports.length - 1];\n\t\t\t\t\tconsole.log(`[E2E] ✅ Stage 2: Latest LLM report: ${latestReport.id || 'N/A'} — ${latestReport.status || 'unknown'}`);\n\n\t\t\t\t\t// Try to view a specific report if there's a detail page\n\t\t\t\t\tif (latestReport.task_id) {\n\t\t\t\t\t\tawait page.goto(`${FRONTEND_URL}/reports/llm/${latestReport.task_id}`).catch(() => {\n\t\t\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: LLM report detail page not available');\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log('[E2E] ℹ️ Stage 2: No LLM reports available yet');\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tconsole.log(`[E2E] ℹ️ Stage 2: LLM reports: ${e.message}`);\n\t\t\t}\n\t\t});\n\t});\n});\n// #endregion LiveProjectCheckE2E\n"
},
{
"contract_id": "LoginE2E",
@@ -63659,14 +58837,14 @@
{
"source_id": "MigrationE2E",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:list:MigrationApi_SettingsPage]",
- "target_ref": "[[EXT:list:MigrationApi_SettingsPage]]"
+ "target_id": "MigrationApi",
+ "target_ref": "[MigrationApi]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region MigrationE2E [C:3] [TYPE Test] [SEMANTICS e2e, migration, sync, datasets]\n// @BRIEF E2E tests for dataset/environment migration and sync.\n// @RELATION BINDS_TO -> [[EXT:list:MigrationApi_SettingsPage]]\n// @UX_STATE SyncTriggered -> Sync-now request accepted.\n// @UX_STATE MappingsLoaded -> Synchronized resources table populated.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\n\ntest.describe('Dataset Environment Sync', () => {\n\ttest('should show migration settings tab', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/settings#/settings/migration`);\n\t\tawait authPage.waitForSelector('text=Синхронизация', { timeout: 10_000 });\n\t\t// Schedule section visible\n\t\tawait expect(authPage.getByText(/Cron-выражение|Schedule/)).toBeVisible();\n\t});\n\n\ttest('should trigger sync and check results via API', async ({ authPage }) => {\n\t\t// Get pre-sync settings\n\t\tconst settingsBefore = await apiGet('/api/migration/settings');\n\t\texpect(settingsBefore).toBeDefined();\n\t\texpect(settingsBefore.cron).toBeDefined();\n\n\t\t// Trigger sync (fire-and-forget, it runs async)\n\t\tlet syncResult;\n\t\ttry {\n\t\t\tsyncResult = await apiPost('/api/migration/sync-now', {});\n\t\t\tconsole.log('[E2E] Sync triggered:', JSON.stringify(syncResult).slice(0, 200));\n\t\t} catch (err) {\n\t\t\t// Sync may timeout or fail if Superset is unreachable — that's acceptable for CI\n\t\t\tconsole.log('[E2E] Sync note (non-blocking):', err.message.slice(0, 200));\n\t\t}\n\n\t\t// Verify sync mappings endpoint responds\n\t\tconst mappings = await apiGet('/api/migration/mappings-data?skip=0&limit=5').catch(() => []);\n\t\tconsole.log(`[E2E] Mappings count: ${Array.isArray(mappings) ? mappings.length : 'N/A'}`);\n\n\t\t// If mappings exist, verify structure\n\t\tif (Array.isArray(mappings) && mappings.length > 0) {\n\t\t\tconst mapping = mappings[0];\n\t\t\texpect(mapping.resource_name).toBeDefined();\n\t\t\texpect(mapping.resource_type).toBeDefined();\n\t\t}\n\t});\n});\n\ntest.describe('Datasets', () => {\n\ttest('should list datasets from ss-dev', async ({ authPage }) => {\n\t\tconst datasets = await apiGet('/api/datasets?env_id=ss-dev&skip=0&limit=10');\n\t\texpect(Array.isArray(datasets)).toBeTruthy();\n\t\tif (datasets.length > 0) {\n\t\t\texpect(datasets[0].id || datasets[0].table_name).toBeTruthy();\n\t\t}\n\t});\n\n\ttest('should show datasets page in UI', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/datasets`);\n\t\tawait authPage.waitForSelector('text=Датасеты', { timeout: 10_000 });\n\t\t// Dataset table/list skeleton\n\t\tawait expect(authPage.locator('main')).toBeVisible();\n\t});\n\n\ttest('should show translate_fact dataset detail', async ({ authPage }) => {\n\t\t// Get translate_fact datasource ID\n\t\tconst datasources = await apiGet('/api/translate/datasources?env_id=ss-dev');\n\t\tconst translateFact = datasources.find(ds =>\n\t\t\tds.table_name === 'translate_fact' && ds.schema === 'dm_view'\n\t\t);\n\t\texpect(translateFact).toBeDefined();\n\t\texpect(translateFact.id).toBeDefined();\n\n\t\t// Navigate to dataset detail in UI\n\t\tawait authPage.goto(`${FRONTEND_URL}/datasets/${translateFact.id}?env_id=ss-dev`);\n\t\tawait authPage.waitForTimeout(3000);\n\t\t// Page should load\n\t\tconst bodyText = await authPage.locator('body').innerText();\n\t\texpect(bodyText.length).toBeGreaterThan(0);\n\t});\n});\n// #endregion MigrationE2E\n"
+ "body": "// #region MigrationE2E [C:3] [TYPE Test] [SEMANTICS e2e, migration, sync, datasets]\n// @BRIEF E2E tests for dataset/environment migration and sync.\n// @RELATION BINDS_TO -> [MigrationApi]\n// @UX_STATE SyncTriggered -> Sync-now request accepted.\n// @UX_STATE MappingsLoaded -> Synchronized resources table populated.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\n\ntest.describe('Dataset Environment Sync', () => {\n\ttest('should show migration settings tab', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/settings#/settings/migration`);\n\t\tawait authPage.waitForSelector('text=Синхронизация', { timeout: 10_000 });\n\t\t// Schedule section visible\n\t\tawait expect(authPage.getByText(/Cron-выражение|Schedule/)).toBeVisible();\n\t});\n\n\ttest('should trigger sync and check results via API', async ({ authPage }) => {\n\t\t// Get pre-sync settings\n\t\tconst settingsBefore = await apiGet('/api/migration/settings');\n\t\texpect(settingsBefore).toBeDefined();\n\t\texpect(settingsBefore.cron).toBeDefined();\n\n\t\t// Trigger sync (fire-and-forget, it runs async)\n\t\tlet syncResult;\n\t\ttry {\n\t\t\tsyncResult = await apiPost('/api/migration/sync-now', {});\n\t\t\tconsole.log('[E2E] Sync triggered:', JSON.stringify(syncResult).slice(0, 200));\n\t\t} catch (err) {\n\t\t\t// Sync may timeout or fail if Superset is unreachable — that's acceptable for CI\n\t\t\tconsole.log('[E2E] Sync note (non-blocking):', err.message.slice(0, 200));\n\t\t}\n\n\t\t// Verify sync mappings endpoint responds\n\t\tconst mappings = await apiGet('/api/migration/mappings-data?skip=0&limit=5').catch(() => []);\n\t\tconsole.log(`[E2E] Mappings count: ${Array.isArray(mappings) ? mappings.length : 'N/A'}`);\n\n\t\t// If mappings exist, verify structure\n\t\tif (Array.isArray(mappings) && mappings.length > 0) {\n\t\t\tconst mapping = mappings[0];\n\t\t\texpect(mapping.resource_name).toBeDefined();\n\t\t\texpect(mapping.resource_type).toBeDefined();\n\t\t}\n\t});\n});\n\ntest.describe('Datasets', () => {\n\ttest('should list datasets from ss-dev', async ({ authPage }) => {\n\t\tconst datasets = await apiGet('/api/datasets?env_id=ss-dev&skip=0&limit=10');\n\t\texpect(Array.isArray(datasets)).toBeTruthy();\n\t\tif (datasets.length > 0) {\n\t\t\texpect(datasets[0].id || datasets[0].table_name).toBeTruthy();\n\t\t}\n\t});\n\n\ttest('should show datasets page in UI', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/datasets`);\n\t\tawait authPage.waitForSelector('text=Датасеты', { timeout: 10_000 });\n\t\t// Dataset table/list skeleton\n\t\tawait expect(authPage.locator('main')).toBeVisible();\n\t});\n\n\ttest('should show translate_fact dataset detail', async ({ authPage }) => {\n\t\t// Get translate_fact datasource ID\n\t\tconst datasources = await apiGet('/api/translate/datasources?env_id=ss-dev');\n\t\tconst translateFact = datasources.find(ds =>\n\t\t\tds.table_name === 'translate_fact' && ds.schema === 'dm_view'\n\t\t);\n\t\texpect(translateFact).toBeDefined();\n\t\texpect(translateFact.id).toBeDefined();\n\n\t\t// Navigate to dataset detail in UI\n\t\tawait authPage.goto(`${FRONTEND_URL}/datasets/${translateFact.id}?env_id=ss-dev`);\n\t\tawait authPage.waitForTimeout(3000);\n\t\t// Page should load\n\t\tconst bodyText = await authPage.locator('body').innerText();\n\t\texpect(bodyText.length).toBeGreaterThan(0);\n\t});\n});\n// #endregion MigrationE2E\n"
},
{
"contract_id": "SettingsE2E",
@@ -63712,14 +58890,14 @@
{
"source_id": "SmokeE2E",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig]",
- "target_ref": "[[EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig]]"
+ "target_id": "E2E.Smoke",
+ "target_ref": "[E2E.Smoke]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region SmokeE2E [C:4] [TYPE Test] [SEMANTICS e2e, smoke, golden-path, full-stack]\n// @BRIEF Golden-path smoke test: login → settings → translate → git → verify.\n// @RELATION BINDS_TO -> [[EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig]]\n// @UX_STATE FullCycle -> All key user journeys executed sequentially.\n// @RATIONALE Single sequential test verifies the entire stack without per-test setup overhead.\n// Runs in ~30s when backend is warm. Mirrors the manual E2E check.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost, apiPut } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\n\ntest.describe('Golden Path — Full Stack E2E', () => {\n\n\ttest('complete user journey: login → settings → translate → git', async ({ page }) => {\n\t\t// ── 1. LOGIN ───────────────────────────────────────────\n\t\tawait test.step('Login as admin', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tawait expect(page.locator('nav')).toBeVisible();\n\t\t\tconsole.log('[E2E] ✅ Login successful');\n\t\t});\n\n\t\t// ── 2. DASHBOARDS LANDING ──────────────────────────────\n\t\tawait test.step('Dashboard page loads', async () => {\n\t\t\tconst currentUrl = page.url();\n\t\t\texpect(currentUrl).toMatch(/dashboards|\\/datasets|\\//);\n\t\t\tconsole.log(`[E2E] ✅ Redirected to: ${currentUrl}`);\n\t\t});\n\n\t\t// ── 3. SETTINGS — check environments via UI ────────────\n\t\tawait test.step('Settings — environments tab', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/environments`);\n\t\t\tawait page.waitForSelector('text=Окружения', { timeout: 10_000 });\n\n\t\t\t// Verify environments exist via API\n\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\texpect(envs.length).toBeGreaterThanOrEqual(3);\n\t\t\tconst envNames = envs.map(e => e.id);\n\t\t\texpect(envNames).toContain('ss-dev');\n\t\t\texpect(envNames).toContain('ss-preprod');\n\t\t\texpect(envNames).toContain('ss-prod');\n\t\t\tconsole.log('[E2E] ✅ Environments configured:', envNames.join(', '));\n\t\t});\n\n\t\t// ── 4. SETTINGS — check LLM via API ────────────────────\n\t\tawait test.step('Settings — LLM provider', async () => {\n\t\t\tconst status = await apiGet('/api/llm/status');\n\t\t\texpect(status.configured).toBe(true);\n\t\t\texpect(status.provider_count).toBeGreaterThanOrEqual(1);\n\t\t\tconsole.log(`[E2E] ✅ LLM configured: ${status.provider_name} (${status.default_model})`);\n\t\t});\n\n\t\t// ── 5. SETTINGS — check Git via UI ─────────────────────\n\t\tawait test.step('Settings — Git integration', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\t\tawait page.waitForSelector('text=Интеграция Git', { timeout: 10_000 });\n\n\t\t\tconst configs = await apiGet('/api/git/config');\n\t\t\texpect(configs.length).toBeGreaterThanOrEqual(1);\n\t\t\t// At least one config visible in UI\n\t\t\tawait expect(page.getByText(configs[0].name).first()).toBeVisible({ timeout: 5_000 });\n\t\t\tconsole.log(`[E2E] ✅ Git configured: ${configs[0].name} (${configs[0].provider})`);\n\t\t});\n\n\t\t// ── 6. DATASETS — verify datasources ───────────────────\n\t\tawait test.step('Datasets — verify datasources', async () => {\n\t\t\tconst datasources = await apiGet('/api/translate/datasources?env_id=ss-dev');\n\t\t\tconst translateFact = datasources.find(ds =>\n\t\t\t\tds.table_name === 'translate_fact' && ds.schema === 'dm_view'\n\t\t\t);\n\t\t\texpect(translateFact).toBeDefined();\n\t\t\texpect(translateFact.id).toBe('33');\n\t\t\tconsole.log(`[E2E] ✅ Dataset dm_view.translate_found (id=${translateFact.id})`);\n\t\t});\n\n\t\t// ── 7. TRANSLATION — create job via API ────────────────\n\t\tawait test.step('Translation — create job', async () => {\n\t\t\tconst providers = await apiGet('/api/llm/providers');\n\t\t\tconst job = await apiPost('/api/translate/jobs', {\n\t\t\t\tname: `E2E Smoke Test ${Date.now()}`,\n\t\t\t\tdescription: 'Golden path E2E test',\n\t\t\t\tsource_dialect: 'postgresql',\n\t\t\t\ttarget_dialect: 'postgresql',\n\t\t\t\tsource_datasource_id: '33',\n\t\t\t\tsource_table: 'dm_view.translate_fact',\n\t\t\t\ttarget_schema: 'dm_view',\n\t\t\t\ttarget_table: 'financial_comments_translated',\n\t\t\t\ttranslation_column: 'comment',\n\t\t\t\ttarget_column: 'comment_translated',\n\t\t\t\ttarget_languages: ['ru'],\n\t\t\t\tbatch_size: 10,\n\t\t\t\tenvironment_id: 'ss-dev',\n\t\t\t\tprovider_id: providers[0]?.id || null,\n\t\t\t});\n\t\t\texpect(job.id).toBeTruthy();\n\t\t\texpect(job.status).toBe('DRAFT');\n\t\t\tconsole.log(`[E2E] ✅ Translation job created: ${job.id} (${job.status})`);\n\n\t\t\t// Verify in UI\n\t\t\tawait page.goto(`${FRONTEND_URL}/translate`);\n\t\t\tawait page.waitForSelector('text=Задания перевода', { timeout: 10_000 });\n\t\t\tawait expect(page.getByText(job.name).first()).toBeVisible({ timeout: 10_000 });\n\t\t});\n\n\t\t// ── 8. GIT — verify repositories ───────────────────────\n\t\tawait test.step('Git — list repositories', async () => {\n\t\t\tconst configs = await apiGet('/api/git/config');\n\t\t\tif (configs.length > 0 && configs[0].provider === 'GITEA') {\n\t\t\t\tconst repos = await apiGet(`/api/git/config/${configs[0].id}/gitea/repos`);\n\t\t\t\texpect(Array.isArray(repos)).toBe(true);\n\t\t\t\tconsole.log(`[E2E] ✅ Gitea repos: ${repos.length} found`);\n\n\t\t\t\t// Verify in git UI\n\t\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\t\t\tawait page.waitForTimeout(2000);\n\t\t\t}\n\t\t});\n\n\t\t// ── 9. RUN TRANSLATION (or verify it was attempted) ────\n\t\tawait test.step('Translation — run job (verify pipeline)', async () => {\n\t\t\tconst jobs = await apiGet('/api/translate/jobs');\n\t\t\texpect(Array.isArray(jobs)).toBe(true);\n\t\t\tif (jobs.length > 0) {\n\t\t\t\tconst latestJob = jobs[jobs.length - 1];\n\t\t\t\tconsole.log(`[E2E] ✅ Latest job: ${latestJob.name} — ${latestJob.status}`);\n\t\t\t}\n\t\t});\n\n\t\tconsole.log('[E2E] 🎉 Golden path E2E completed successfully');\n\t});\n});\n// #endregion SmokeE2E\n"
+ "body": "// #region SmokeE2E [C:4] [TYPE Test] [SEMANTICS e2e, smoke, golden-path, full-stack]\n// @BRIEF Golden-path smoke test: login → settings → translate → git → verify.\n// @RELATION BINDS_TO -> [E2E.Smoke]\n// @UX_STATE FullCycle -> All key user journeys executed sequentially.\n// @RATIONALE Single sequential test verifies the entire stack without per-test setup overhead.\n// Runs in ~30s when backend is warm. Mirrors the manual E2E check.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiGet, apiPost, apiPut } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\n\ntest.describe('Golden Path — Full Stack E2E', () => {\n\n\ttest('complete user journey: login → settings → translate → git', async ({ page }) => {\n\t\t// ── 1. LOGIN ───────────────────────────────────────────\n\t\tawait test.step('Login as admin', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/login`);\n\t\t\tawait page.getByLabel(/Имя пользователя|Username/).fill('admin');\n\t\t\tawait page.getByLabel(/Пароль|Password/).fill('admin123');\n\t\t\tawait page.getByRole('button', { name: /Вход|Login/ }).click();\n\t\t\tawait page.waitForURL(/\\/(?!login)/, { timeout: 15_000 });\n\t\t\tawait expect(page.locator('nav')).toBeVisible();\n\t\t\tconsole.log('[E2E] ✅ Login successful');\n\t\t});\n\n\t\t// ── 2. DASHBOARDS LANDING ──────────────────────────────\n\t\tawait test.step('Dashboard page loads', async () => {\n\t\t\tconst currentUrl = page.url();\n\t\t\texpect(currentUrl).toMatch(/dashboards|\\/datasets|\\//);\n\t\t\tconsole.log(`[E2E] ✅ Redirected to: ${currentUrl}`);\n\t\t});\n\n\t\t// ── 3. SETTINGS — check environments via UI ────────────\n\t\tawait test.step('Settings — environments tab', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/environments`);\n\t\t\tawait page.waitForSelector('text=Окружения', { timeout: 10_000 });\n\n\t\t\t// Verify environments exist via API\n\t\t\tconst envs = await apiGet('/api/settings/environments');\n\t\t\texpect(envs.length).toBeGreaterThanOrEqual(3);\n\t\t\tconst envNames = envs.map(e => e.id);\n\t\t\texpect(envNames).toContain('ss-dev');\n\t\t\texpect(envNames).toContain('ss-preprod');\n\t\t\texpect(envNames).toContain('ss-prod');\n\t\t\tconsole.log('[E2E] ✅ Environments configured:', envNames.join(', '));\n\t\t});\n\n\t\t// ── 4. SETTINGS — check LLM via API ────────────────────\n\t\tawait test.step('Settings — LLM provider', async () => {\n\t\t\tconst status = await apiGet('/api/llm/status');\n\t\t\texpect(status.configured).toBe(true);\n\t\t\texpect(status.provider_count).toBeGreaterThanOrEqual(1);\n\t\t\tconsole.log(`[E2E] ✅ LLM configured: ${status.provider_name} (${status.default_model})`);\n\t\t});\n\n\t\t// ── 5. SETTINGS — check Git via UI ─────────────────────\n\t\tawait test.step('Settings — Git integration', async () => {\n\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\t\tawait page.waitForSelector('text=Интеграция Git', { timeout: 10_000 });\n\n\t\t\tconst configs = await apiGet('/api/git/config');\n\t\t\texpect(configs.length).toBeGreaterThanOrEqual(1);\n\t\t\t// At least one config visible in UI\n\t\t\tawait expect(page.getByText(configs[0].name).first()).toBeVisible({ timeout: 5_000 });\n\t\t\tconsole.log(`[E2E] ✅ Git configured: ${configs[0].name} (${configs[0].provider})`);\n\t\t});\n\n\t\t// ── 6. DATASETS — verify datasources ───────────────────\n\t\tawait test.step('Datasets — verify datasources', async () => {\n\t\t\tconst datasources = await apiGet('/api/translate/datasources?env_id=ss-dev');\n\t\t\tconst translateFact = datasources.find(ds =>\n\t\t\t\tds.table_name === 'translate_fact' && ds.schema === 'dm_view'\n\t\t\t);\n\t\t\texpect(translateFact).toBeDefined();\n\t\t\texpect(translateFact.id).toBe('33');\n\t\t\tconsole.log(`[E2E] ✅ Dataset dm_view.translate_found (id=${translateFact.id})`);\n\t\t});\n\n\t\t// ── 7. TRANSLATION — create job via API ────────────────\n\t\tawait test.step('Translation — create job', async () => {\n\t\t\tconst providers = await apiGet('/api/llm/providers');\n\t\t\tconst job = await apiPost('/api/translate/jobs', {\n\t\t\t\tname: `E2E Smoke Test ${Date.now()}`,\n\t\t\t\tdescription: 'Golden path E2E test',\n\t\t\t\tsource_dialect: 'postgresql',\n\t\t\t\ttarget_dialect: 'postgresql',\n\t\t\t\tsource_datasource_id: '33',\n\t\t\t\tsource_table: 'dm_view.translate_fact',\n\t\t\t\ttarget_schema: 'dm_view',\n\t\t\t\ttarget_table: 'financial_comments_translated',\n\t\t\t\ttranslation_column: 'comment',\n\t\t\t\ttarget_column: 'comment_translated',\n\t\t\t\ttarget_languages: ['ru'],\n\t\t\t\tbatch_size: 10,\n\t\t\t\tenvironment_id: 'ss-dev',\n\t\t\t\tprovider_id: providers[0]?.id || null,\n\t\t\t});\n\t\t\texpect(job.id).toBeTruthy();\n\t\t\texpect(job.status).toBe('DRAFT');\n\t\t\tconsole.log(`[E2E] ✅ Translation job created: ${job.id} (${job.status})`);\n\n\t\t\t// Verify in UI\n\t\t\tawait page.goto(`${FRONTEND_URL}/translate`);\n\t\t\tawait page.waitForSelector('text=Задания перевода', { timeout: 10_000 });\n\t\t\tawait expect(page.getByText(job.name).first()).toBeVisible({ timeout: 10_000 });\n\t\t});\n\n\t\t// ── 8. GIT — verify repositories ───────────────────────\n\t\tawait test.step('Git — list repositories', async () => {\n\t\t\tconst configs = await apiGet('/api/git/config');\n\t\t\tif (configs.length > 0 && configs[0].provider === 'GITEA') {\n\t\t\t\tconst repos = await apiGet(`/api/git/config/${configs[0].id}/gitea/repos`);\n\t\t\t\texpect(Array.isArray(repos)).toBe(true);\n\t\t\t\tconsole.log(`[E2E] ✅ Gitea repos: ${repos.length} found`);\n\n\t\t\t\t// Verify in git UI\n\t\t\t\tawait page.goto(`${FRONTEND_URL}/settings#/settings/git`);\n\t\t\t\tawait page.waitForTimeout(2000);\n\t\t\t}\n\t\t});\n\n\t\t// ── 9. RUN TRANSLATION (or verify it was attempted) ────\n\t\tawait test.step('Translation — run job (verify pipeline)', async () => {\n\t\t\tconst jobs = await apiGet('/api/translate/jobs');\n\t\t\texpect(Array.isArray(jobs)).toBe(true);\n\t\t\tif (jobs.length > 0) {\n\t\t\t\tconst latestJob = jobs[jobs.length - 1];\n\t\t\t\tconsole.log(`[E2E] ✅ Latest job: ${latestJob.name} — ${latestJob.status}`);\n\t\t\t}\n\t\t});\n\n\t\tconsole.log('[E2E] 🎉 Golden path E2E completed successfully');\n\t});\n});\n// #endregion SmokeE2E\n"
},
{
"contract_id": "TranslationE2E",
@@ -63738,14 +58916,14 @@
{
"source_id": "TranslationE2E",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:list:TranslatePage_TranslateJobRoutes]",
- "target_ref": "[[EXT:list:TranslatePage_TranslateJobRoutes]]"
+ "target_id": "TranslatePage",
+ "target_ref": "[TranslatePage]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region TranslationE2E [C:3] [TYPE Test] [SEMANTICS e2e, translate, job, preview, run]\n// @BRIEF E2E tests for the translation job lifecycle: create → preview → accept → run.\n// @RELATION BINDS_TO -> [[EXT:list:TranslatePage_TranslateJobRoutes]]\n// @UX_STATE JobCreated -> Job appears in list with DRAFT status.\n// @UX_STATE PreviewCreated -> Preview session with sample rows visible.\n// @UX_STATE JobRunning -> Run object created with PENDING status.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiPost, apiGet, apiPut } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\n\ntest.describe('Translation Job Lifecycle', () => {\n\t// Unique identifier for test isolation\n\tconst testSuffix = Date.now();\n\tconst jobName = `E2E Test Job ${testSuffix}`;\n\tlet jobId = null;\n\tlet runId = null;\n\n\ttest.afterEach(async () => {\n\t\t// Cleanup: delete the job if it was created\n\t\tif (jobId) {\n\t\t\ttry {\n\t\t\t\tawait apiPost(`/api/translate/jobs/${jobId}/run`, { full_translation: true }).catch(() => {});\n\t\t\t} catch (_) { /* ignore */ }\n\t\t}\n\t});\n\n\ttest('1. should create a translation job via UI', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/translate`);\n\t\tawait authPage.waitForSelector('text=Задания перевода', { timeout: 10_000 });\n\n\t\t// Click \"New Job\" button\n\t\tawait authPage.getByRole('button', { name: /Новое задание|New/ }).click();\n\n\t\t// Fill job creation form — adapt selectors to actual form\n\t\tawait authPage.waitForTimeout(1000);\n\n\t\t// Fallback: create via API for reliability, then verify in UI list\n\t\tconst job = await apiPost('/api/translate/jobs', {\n\t\t\tname: jobName,\n\t\t\tdescription: 'E2E test translation job',\n\t\t\tsource_dialect: 'postgresql',\n\t\t\ttarget_dialect: 'postgresql',\n\t\t\tsource_table: 'dm_view.translate_fact',\n\t\t\ttarget_schema: 'dm_view',\n\t\t\ttarget_table: 'financial_comments_translated',\n\t\t\ttranslation_column: 'comment',\n\t\t\ttarget_column: 'comment_translated',\n\t\t\ttarget_languages: ['ru'],\n\t\t\tsource_key_cols: ['id'],\n\t\t\ttarget_key_cols: ['id'],\n\t\t\tbatch_size: 10,\n\t\t\tenvironment_id: 'ss-dev',\n\t\t});\n\t\texpect(job).toBeDefined();\n\t\texpect(job.id).toBeTruthy();\n\t\texpect(job.status).toBe('DRAFT');\n\t\tjobId = job.id;\n\n\t\t// Verify job appears in the UI list — refresh page\n\t\tawait authPage.reload();\n\t\tawait authPage.waitForSelector('text=Задания перевода', { timeout: 10_000 });\n\t\tawait expect(authPage.getByText(jobName).first()).toBeVisible({ timeout: 10_000 });\n\t});\n\n\ttest('2. should prepare and run a translation job via API', async ({ authPage }) => {\n\t\t// Create job via API\n\t\tconst job = await apiPost('/api/translate/jobs', {\n\t\t\tname: `${jobName}-api`,\n\t\t\tdescription: 'E2E test via API',\n\t\t\tsource_dialect: 'postgresql',\n\t\t\ttarget_dialect: 'postgresql',\n\t\t\tsource_datasource_id: '33', // dm_view.translate_fact on ss-dev\n\t\t\tsource_table: 'dm_view.translate_fact',\n\t\t\ttarget_schema: 'dm_view',\n\t\t\ttarget_table: 'financial_comments_translated',\n\t\t\ttranslation_column: 'comment',\n\t\t\ttarget_column: 'comment_translated',\n\t\t\ttarget_languages: ['ru'],\n\t\t\tbatch_size: 10,\n\t\t\tenvironment_id: 'ss-dev',\n\t\t});\n\t\tjobId = job.id;\n\t\texpect(job.status).toBe('DRAFT');\n\n\t\t// Assign LLM provider and set READY\n\t\tconst providers = await apiGet('/api/llm/providers');\n\t\texpect(providers.length).toBeGreaterThan(0);\n\t\tconst providerId = providers[0].id;\n\n\t\tawait apiPut(`/api/translate/jobs/${job.id}`, {\n\t\t\tprovider_id: providerId,\n\t\t\tstatus: 'READY',\n\t\t});\n\n\t\t// Create preview\n\t\tconst preview = await apiPost(`/api/translate/jobs/${job.id}/preview`, {\n\t\t\tsample_size: 2,\n\t\t});\n\t\texpect(preview).toBeDefined();\n\t\texpect(preview.id).toBeTruthy();\n\t\texpect(preview.status).toBe('ACTIVE');\n\n\t\t// Accept preview\n\t\tconst accepted = await apiPost(`/api/translate/jobs/${job.id}/preview/accept`, {});\n\t\texpect(accepted.status).toBe('APPLIED');\n\n\t\t// Run the job\n\t\tconst run = await apiPost(`/api/translate/jobs/${job.id}/run`, {\n\t\t\tfull_translation: true,\n\t\t});\n\t\texpect(run).toBeDefined();\n\t\texpect(run.id).toBeTruthy();\n\t\texpect(run.status).toBe('PENDING');\n\t\trunId = run.id;\n\n\t\t// Poll for run completion (up to 30s)\n\t\tlet attempts = 0;\n\t\tconst maxAttempts = 15;\n\t\tlet finalStatus = 'PENDING';\n\t\twhile (attempts < maxAttempts) {\n\t\t\tawait new Promise(r => setTimeout(r, 2000));\n\t\t\tconst status = await apiGet(`/api/translate/runs/${run.id}`);\n\t\t\tfinalStatus = status.status;\n\t\t\tif (['COMPLETED', 'FAILED', 'CANCELLED'].includes(finalStatus)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tattempts++;\n\t\t}\n\t\tconsole.log(`[E2E] Run final status: ${finalStatus} (attempts: ${attempts})`);\n\t\texpect(['COMPLETED', 'FAILED']).toContain(finalStatus);\n\t});\n\n\ttest('3. should show translation history page', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/translate/history`);\n\t\tawait authPage.waitForSelector('text=История', { timeout: 10_000 });\n\t\t// History page loaded\n\t\tawait expect(authPage.locator('main')).toBeVisible();\n\t});\n});\n// #endregion TranslationE2E\n"
+ "body": "// #region TranslationE2E [C:3] [TYPE Test] [SEMANTICS e2e, translate, job, preview, run]\n// @BRIEF E2E tests for the translation job lifecycle: create → preview → accept → run.\n// @RELATION BINDS_TO -> [TranslatePage]\n// @UX_STATE JobCreated -> Job appears in list with DRAFT status.\n// @UX_STATE PreviewCreated -> Preview session with sample rows visible.\n// @UX_STATE JobRunning -> Run object created with PENDING status.\n\nimport { test, expect } from '../fixtures/auth.fixture.js';\nimport { apiPost, apiGet, apiPut } from '../helpers/api.helper.js';\n\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\n\ntest.describe('Translation Job Lifecycle', () => {\n\t// Unique identifier for test isolation\n\tconst testSuffix = Date.now();\n\tconst jobName = `E2E Test Job ${testSuffix}`;\n\tlet jobId = null;\n\tlet runId = null;\n\n\ttest.afterEach(async () => {\n\t\t// Cleanup: delete the job if it was created\n\t\tif (jobId) {\n\t\t\ttry {\n\t\t\t\tawait apiPost(`/api/translate/jobs/${jobId}/run`, { full_translation: true }).catch(() => {});\n\t\t\t} catch (_) { /* ignore */ }\n\t\t}\n\t});\n\n\ttest('1. should create a translation job via UI', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/translate`);\n\t\tawait authPage.waitForSelector('text=Задания перевода', { timeout: 10_000 });\n\n\t\t// Click \"New Job\" button\n\t\tawait authPage.getByRole('button', { name: /Новое задание|New/ }).click();\n\n\t\t// Fill job creation form — adapt selectors to actual form\n\t\tawait authPage.waitForTimeout(1000);\n\n\t\t// Fallback: create via API for reliability, then verify in UI list\n\t\tconst job = await apiPost('/api/translate/jobs', {\n\t\t\tname: jobName,\n\t\t\tdescription: 'E2E test translation job',\n\t\t\tsource_dialect: 'postgresql',\n\t\t\ttarget_dialect: 'postgresql',\n\t\t\tsource_table: 'dm_view.translate_fact',\n\t\t\ttarget_schema: 'dm_view',\n\t\t\ttarget_table: 'financial_comments_translated',\n\t\t\ttranslation_column: 'comment',\n\t\t\ttarget_column: 'comment_translated',\n\t\t\ttarget_languages: ['ru'],\n\t\t\tsource_key_cols: ['id'],\n\t\t\ttarget_key_cols: ['id'],\n\t\t\tbatch_size: 10,\n\t\t\tenvironment_id: 'ss-dev',\n\t\t});\n\t\texpect(job).toBeDefined();\n\t\texpect(job.id).toBeTruthy();\n\t\texpect(job.status).toBe('DRAFT');\n\t\tjobId = job.id;\n\n\t\t// Verify job appears in the UI list — refresh page\n\t\tawait authPage.reload();\n\t\tawait authPage.waitForSelector('text=Задания перевода', { timeout: 10_000 });\n\t\tawait expect(authPage.getByText(jobName).first()).toBeVisible({ timeout: 10_000 });\n\t});\n\n\ttest('2. should prepare and run a translation job via API', async ({ authPage }) => {\n\t\t// Create job via API\n\t\tconst job = await apiPost('/api/translate/jobs', {\n\t\t\tname: `${jobName}-api`,\n\t\t\tdescription: 'E2E test via API',\n\t\t\tsource_dialect: 'postgresql',\n\t\t\ttarget_dialect: 'postgresql',\n\t\t\tsource_datasource_id: '33', // dm_view.translate_fact on ss-dev\n\t\t\tsource_table: 'dm_view.translate_fact',\n\t\t\ttarget_schema: 'dm_view',\n\t\t\ttarget_table: 'financial_comments_translated',\n\t\t\ttranslation_column: 'comment',\n\t\t\ttarget_column: 'comment_translated',\n\t\t\ttarget_languages: ['ru'],\n\t\t\tbatch_size: 10,\n\t\t\tenvironment_id: 'ss-dev',\n\t\t});\n\t\tjobId = job.id;\n\t\texpect(job.status).toBe('DRAFT');\n\n\t\t// Assign LLM provider and set READY\n\t\tconst providers = await apiGet('/api/llm/providers');\n\t\texpect(providers.length).toBeGreaterThan(0);\n\t\tconst providerId = providers[0].id;\n\n\t\tawait apiPut(`/api/translate/jobs/${job.id}`, {\n\t\t\tprovider_id: providerId,\n\t\t\tstatus: 'READY',\n\t\t});\n\n\t\t// Create preview\n\t\tconst preview = await apiPost(`/api/translate/jobs/${job.id}/preview`, {\n\t\t\tsample_size: 2,\n\t\t});\n\t\texpect(preview).toBeDefined();\n\t\texpect(preview.id).toBeTruthy();\n\t\texpect(preview.status).toBe('ACTIVE');\n\n\t\t// Accept preview\n\t\tconst accepted = await apiPost(`/api/translate/jobs/${job.id}/preview/accept`, {});\n\t\texpect(accepted.status).toBe('APPLIED');\n\n\t\t// Run the job\n\t\tconst run = await apiPost(`/api/translate/jobs/${job.id}/run`, {\n\t\t\tfull_translation: true,\n\t\t});\n\t\texpect(run).toBeDefined();\n\t\texpect(run.id).toBeTruthy();\n\t\texpect(run.status).toBe('PENDING');\n\t\trunId = run.id;\n\n\t\t// Poll for run completion (up to 30s)\n\t\tlet attempts = 0;\n\t\tconst maxAttempts = 15;\n\t\tlet finalStatus = 'PENDING';\n\t\twhile (attempts < maxAttempts) {\n\t\t\tawait new Promise(r => setTimeout(r, 2000));\n\t\t\tconst status = await apiGet(`/api/translate/runs/${run.id}`);\n\t\t\tfinalStatus = status.status;\n\t\t\tif (['COMPLETED', 'FAILED', 'CANCELLED'].includes(finalStatus)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tattempts++;\n\t\t}\n\t\tconsole.log(`[E2E] Run final status: ${finalStatus} (attempts: ${attempts})`);\n\t\texpect(['COMPLETED', 'FAILED']).toContain(finalStatus);\n\t});\n\n\ttest('3. should show translation history page', async ({ authPage }) => {\n\t\tawait authPage.goto(`${FRONTEND_URL}/translate/history`);\n\t\tawait authPage.waitForSelector('text=История', { timeout: 10_000 });\n\t\t// History page loaded\n\t\tawait expect(authPage.locator('main')).toBeVisible();\n\t});\n});\n// #endregion TranslationE2E\n"
},
{
"contract_id": "PlaywrightConfig",
@@ -63765,14 +58943,14 @@
{
"source_id": "PlaywrightConfig",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:frontend:EnvConfig]",
- "target_ref": "[[EXT:frontend:EnvConfig]]"
+ "target_id": "EXT:frontend:EnvConfig]",
+ "target_ref": "[EXT:frontend:EnvConfig]]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region PlaywrightConfig [C:3] [TYPE Config] [SEMANTICS e2e, playwright, test, config]\n// @BRIEF Playwright E2E test configuration for ss-tools frontend.\n// @RELATION DEPENDS_ON -> [[EXT:frontend:EnvConfig]]\n// @INVARIANT All E2E tests run against a fully deployed stack (DB + backend + frontend).\n// @UX_STATE ConfigLoaded -> Browser contexts are created with predefined env settings.\n\nimport { defineConfig, devices } from '@playwright/test';\n\nconst BACKEND_URL = process.env.BACKEND_URL || 'http://127.0.0.1:8101';\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\nconst AUTH_USERNAME = process.env.E2E_USERNAME || 'admin';\nconst AUTH_PASSWORD = process.env.E2E_PASSWORD || 'admin123';\n\nexport default defineConfig({\n\ttestDir: './e2e/tests',\n\ttestMatch: '**/*.e2e.js',\n\tfullyParallel: false,\n\tretries: process.env.CI ? 1 : 0,\n\tworkers: 1, // sequential tests — settings mutate global state\n\treporter: [\n\t\t['list'],\n\t\t['html', { outputFolder: 'playwright-report' }],\n\t],\n\ttimeout: 60_000,\n\texpect: {\n\t\ttimeout: 15_000,\n\t},\n\tuse: {\n\t\tbaseURL: FRONTEND_URL,\n\t\ttrace: 'retain-on-failure',\n\t\tscreenshot: 'only-on-failure',\n\t\tvideo: 'retain-on-failure',\n\t},\n\tprojects: [\n\t\t{\n\t\t\tname: 'chromium',\n\t\t\tuse: {\n\t\t\t\t...devices['Desktop Chrome'],\n\t\t\t\tviewport: { width: 1440, height: 900 },\n\t\t\t},\n\t\t},\n\t],\n\t// Global setup — runs once per worker\n\tglobalSetup: './e2e/fixtures/global-setup.js',\n\t// Expose env vars to tests\n\tglobalTeardown: undefined,\n\t// Share backend URL via env\n\t// Each test file can access process.env.BACKEND_URL\n});\n\nexport { BACKEND_URL, FRONTEND_URL, AUTH_USERNAME, AUTH_PASSWORD };\n// #endregion PlaywrightConfig\n"
+ "body": "// #region PlaywrightConfig [C:3] [TYPE Config] [SEMANTICS e2e, playwright, test, config]\n// @BRIEF Playwright E2E test configuration for ss-tools frontend.\n// @RELATION DEPENDS_ON -> [EXT:frontend:EnvConfig]]\n// @INVARIANT All E2E tests run against a fully deployed stack (DB + backend + frontend).\n// @UX_STATE ConfigLoaded -> Browser contexts are created with predefined env settings.\n\nimport { defineConfig, devices } from '@playwright/test';\n\nconst BACKEND_URL = process.env.BACKEND_URL || 'http://127.0.0.1:8101';\nconst FRONTEND_URL = process.env.FRONTEND_URL || 'http://127.0.0.1:8102';\nconst AUTH_USERNAME = process.env.E2E_USERNAME || 'admin';\nconst AUTH_PASSWORD = process.env.E2E_PASSWORD || 'admin123';\n\nexport default defineConfig({\n\ttestDir: './e2e/tests',\n\ttestMatch: '**/*.e2e.js',\n\tfullyParallel: false,\n\tretries: process.env.CI ? 1 : 0,\n\tworkers: 1, // sequential tests — settings mutate global state\n\treporter: [\n\t\t['list'],\n\t\t['html', { outputFolder: 'playwright-report' }],\n\t],\n\ttimeout: 60_000,\n\texpect: {\n\t\ttimeout: 15_000,\n\t},\n\tuse: {\n\t\tbaseURL: FRONTEND_URL,\n\t\ttrace: 'retain-on-failure',\n\t\tscreenshot: 'only-on-failure',\n\t\tvideo: 'retain-on-failure',\n\t},\n\tprojects: [\n\t\t{\n\t\t\tname: 'chromium',\n\t\t\tuse: {\n\t\t\t\t...devices['Desktop Chrome'],\n\t\t\t\tviewport: { width: 1440, height: 900 },\n\t\t\t},\n\t\t},\n\t],\n\t// Global setup — runs once per worker\n\tglobalSetup: './e2e/fixtures/global-setup.js',\n\t// Expose env vars to tests\n\tglobalTeardown: undefined,\n\t// Share backend URL via env\n\t// Each test file can access process.env.BACKEND_URL\n});\n\nexport { BACKEND_URL, FRONTEND_URL, AUTH_USERNAME, AUTH_PASSWORD };\n// #endregion PlaywrightConfig\n"
},
{
"contract_id": "handleValidate:Function",
@@ -64042,8 +59220,8 @@
{
"source_id": "PasswordPrompt",
"relation_type": "USES",
- "target_id": "EXT:path:frontend/src/lib/api.js (inferred)",
- "target_ref": "[EXT:path:frontend/src/lib/api.js (inferred)]"
+ "target_id": "ApiModule",
+ "target_ref": "[ApiModule]"
},
{
"source_id": "PasswordPrompt",
@@ -64061,7 +59239,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n{#if show}\n \n
\n \n
\n\n
\n\n
\n
\n
\n
\n
\n
\n Database Password Required\n \n
\n
\n The migration process requires passwords for\n the following databases to proceed.\n
\n\n {#if errorMessage}\n
\n Error: {errorMessage}\n
\n {/if}\n\n
\n
\n
\n
\n
\n
\n \n {submitting ? \"Resuming...\" : \"Resume Migration\"}\n \n \n Cancel\n \n
\n
\n
\n
\n{/if}\n\n"
+ "body": "\n\n\n\n\n\n{#if show}\n \n
\n \n
\n\n
\n\n
\n
\n
\n
\n
\n
\n Database Password Required\n \n
\n
\n The migration process requires passwords for\n the following databases to proceed.\n
\n\n {#if errorMessage}\n
\n Error: {errorMessage}\n
\n {/if}\n\n
\n
\n
\n
\n
\n
\n \n {submitting ? \"Resuming...\" : \"Resume Migration\"}\n \n \n Cancel\n \n
\n
\n
\n
\n{/if}\n\n"
},
{
"contract_id": "handleSubmit:Function",
@@ -64510,14 +59688,14 @@
{
"source_id": "TaskHistory",
"relation_type": "USES",
- "target_id": "EXT:path:frontend/src/lib/api.js (inferred)",
- "target_ref": "[EXT:path:frontend/src/lib/api.js (inferred)]"
+ "target_id": "ApiModule",
+ "target_ref": "[ApiModule]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n
\n
\n {$t.tasks?.recent }\n \n
\n
\n
\n {$t.tasks?.clear_tasks }\n \n \n \n
\n
\n
\n clearTasks()} class=\"block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100\">{$t.tasks?.clear_non_running } \n clearTasks('FAILED')} class=\"block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100\">{$t.tasks?.clear_failed } \n clearTasks('AWAITING_INPUT')} class=\"block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100\">{$t.tasks?.clear_awaiting_input } \n
\n
\n
\n
\n {$t.common?.refresh }\n \n
\n
\n \n {#if loading && tasks.length === 0}\n
{$t.tasks?.loading }
\n {:else if error}\n
{error}
\n {:else if tasks.length === 0}\n
{$t.tasks?.no_tasks }
\n {:else}\n
\n {#each tasks as task}\n \n selectTask(task)}\n >\n \n
\n
\n {task.plugin_id}\n ({task.id.slice(0, 8)}) \n
\n
\n
\n
\n
\n
\n {#if task.params.from_env && task.params.to_env}\n {task.params.from_env} → {task.params.to_env}\n {:else}\n {$t.tasks?.parameters }: {Object.keys(task.params).length} {$t.tasks?.keys }\n {/if}\n
\n
\n
\n
\n {$t.tasks?.started_label }: {new Date(task.started_at || task.created_at || Date.now()).toLocaleString()}\n
\n
\n
\n
\n \n \n {/each}\n \n {/if}\n
\n\n"
+ "body": "\n\n\n\n\n\n\n
\n
\n {$t.tasks?.recent }\n \n
\n
\n
\n {$t.tasks?.clear_tasks }\n \n \n \n
\n
\n
\n clearTasks()} class=\"block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100\">{$t.tasks?.clear_non_running } \n clearTasks('FAILED')} class=\"block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100\">{$t.tasks?.clear_failed } \n clearTasks('AWAITING_INPUT')} class=\"block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100\">{$t.tasks?.clear_awaiting_input } \n
\n
\n
\n
\n {$t.common?.refresh }\n \n
\n
\n \n {#if loading && tasks.length === 0}\n
{$t.tasks?.loading }
\n {:else if error}\n
{error}
\n {:else if tasks.length === 0}\n
{$t.tasks?.no_tasks }
\n {:else}\n
\n {#each tasks as task}\n \n selectTask(task)}\n >\n \n
\n
\n {task.plugin_id}\n ({task.id.slice(0, 8)}) \n
\n
\n
\n
\n
\n
\n {#if task.params.from_env && task.params.to_env}\n {task.params.from_env} → {task.params.to_env}\n {:else}\n {$t.tasks?.parameters }: {Object.keys(task.params).length} {$t.tasks?.keys }\n {/if}\n
\n
\n
\n
\n {$t.tasks?.started_label }: {new Date(task.started_at || task.created_at || Date.now()).toLocaleString()}\n
\n
\n
\n
\n \n \n {/each}\n \n {/if}\n
\n\n"
},
{
"contract_id": "getStatusColor:Function",
@@ -65474,14 +60652,14 @@
{
"source_id": "DocPreview",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:backend/src/plugins/llm_analysis/plugin.py",
- "target_ref": "[EXT:path:backend/src/plugins/llm_analysis/plugin.py]"
+ "target_id": "LLMAnalysisPlugin",
+ "target_ref": "[LLMAnalysisPlugin]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n{#if previewDoc}\n \n
\n
{$t.llm.doc_preview_title} \n \n
\n
{$t.llm.dataset_desc} \n
{previewDoc.description || 'No description generated.'}
\n\n
{$t.llm.column_doc} \n
\n \n \n Column \n Description \n \n \n \n {#each Object.entries(previewDoc.columns || {}) as [name, desc]}\n \n {name} \n {desc} \n \n {/each}\n \n
\n
\n\n
\n \n {$t.llm.cancel}\n \n \n {isSaving ? $t.llm.applying : $t.llm.apply_doc}\n \n
\n
\n
\n{/if}\n\n\n"
+ "body": "\n\n\n\n\n\n\n{#if previewDoc}\n \n
\n
{$t.llm.doc_preview_title} \n \n
\n
{$t.llm.dataset_desc} \n
{previewDoc.description || 'No description generated.'}
\n\n
{$t.llm.column_doc} \n
\n \n \n Column \n Description \n \n \n \n {#each Object.entries(previewDoc.columns || {}) as [name, desc]}\n \n {name} \n {desc} \n \n {/each}\n \n
\n
\n\n
\n \n {$t.llm.cancel}\n \n \n {isSaving ? $t.llm.applying : $t.llm.apply_doc}\n \n
\n
\n
\n{/if}\n\n\n"
},
{
"contract_id": "ProviderConfig",
@@ -65903,14 +61081,14 @@
{
"source_id": "MapperTool",
"relation_type": "USES",
- "target_id": "EXT:path:frontend/src/services/toolsService.js",
- "target_ref": "[EXT:path:frontend/src/services/toolsService.js]"
+ "target_id": "ToolsService",
+ "target_ref": "[ToolsService]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n\n
\n \n
\n
\n ({ value: e.id, label: e.name }))\n ]}\n />\n
\n
\n \n
\n
\n\n
\n {$t.mapper.source} \n \n \n \n {$t.mapper.source_sqllab} \n \n \n \n {$t.mapper.source_excel} \n \n
\n \n\n {#if source === 'sqllab'}\n
\n {:else}\n
\n \n
\n {/if}\n\n
\n \n {#if isGeneratingDocs}\n ↻ {$t.mapper?.generating}\n {:else}\n ✨ {$t.datasets?.generate_docs}\n {/if}\n \n \n {isRunning ? $t.mapper.starting : $t.mapper.run}\n \n
\n
\n \n\n
generatedDoc = null}\n onSave={handleApplyDoc}\n />\n \n\n\n"
+ "body": "\n\n\n\n\n\n\n\n
\n \n
\n
\n ({ value: e.id, label: e.name }))\n ]}\n />\n
\n
\n \n
\n
\n\n
\n {$t.mapper.source} \n \n \n \n {$t.mapper.source_sqllab} \n \n \n \n {$t.mapper.source_excel} \n \n
\n \n\n {#if source === 'sqllab'}\n
\n {:else}\n
\n \n
\n {/if}\n\n
\n \n {#if isGeneratingDocs}\n ↻ {$t.mapper?.generating}\n {:else}\n ✨ {$t.datasets?.generate_docs}\n {/if}\n \n \n {isRunning ? $t.mapper.starting : $t.mapper.run}\n \n
\n
\n \n\n
generatedDoc = null}\n onSave={handleApplyDoc}\n />\n \n\n\n"
},
{
"contract_id": "fetchData:Function",
@@ -67490,14 +62668,14 @@
{
"source_id": "PermissionsTest",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:internal:Permissions",
- "target_ref": "[EXT:internal:Permissions]"
+ "target_id": "PermissionsModule",
+ "target_ref": "[PermissionsModule]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region PermissionsTest [C:3] [TYPE Module] [SEMANTICS auth, rbac, permission, test, guard]\n// @BRIEF Verifies frontend RBAC permission parsing and access checks.\n// @RELATION DEPENDS_ON -> [EXT:internal:Permissions]\n\n// #region PermissionsTest:Module [TYPE Function]\n// @SEMANTICS: tests, auth, permissions, rbac\n// @PURPOSE: Verifies frontend RBAC permission parsing and access checks.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:internal:Permissions]\n\nimport { describe, it, expect } from \"vitest\";\nimport {\n normalizePermissionRequirement,\n isAdminUser,\n hasPermission,\n} from \"../permissions.js\";\n\ndescribe(\"auth.permissions\", () => {\n it(\"normalizes resource-only requirement with default READ action\", () => {\n expect(normalizePermissionRequirement(\"admin:settings\")).toEqual({\n resource: \"admin:settings\",\n action: \"READ\",\n });\n });\n\n it(\"normalizes explicit resource:action requirement\", () => {\n expect(normalizePermissionRequirement(\"admin:settings:write\")).toEqual({\n resource: \"admin:settings\",\n action: \"WRITE\",\n });\n });\n\n it(\"detects admin role case-insensitively\", () => {\n const user = {\n roles: [{ name: \"ADMIN\" }],\n };\n expect(isAdminUser(user)).toBe(true);\n });\n\n it(\"denies when user is absent and permission is required\", () => {\n expect(hasPermission(null, \"tasks\", \"READ\")).toBe(false);\n });\n\n it(\"grants when permission object matches resource and action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"READ\")).toBe(true);\n });\n\n it(\"grants when requirement is provided as resource:action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"admin:settings\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"admin:settings:READ\")).toBe(true);\n });\n\n it(\"grants when string permission entry matches\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [\"plugin:migration:READ\"],\n },\n ],\n };\n\n expect(hasPermission(user, \"plugin:migration\", \"READ\")).toBe(true);\n });\n\n it(\"denies when action does not match\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"WRITE\")).toBe(false);\n });\n\n it(\"always grants for admin role regardless of explicit permissions\", () => {\n const adminUser = {\n roles: [{ name: \"Admin\", permissions: [] }],\n };\n\n expect(hasPermission(adminUser, \"admin:users\", \"READ\")).toBe(true);\n expect(hasPermission(adminUser, \"plugin:migration\", \"EXECUTE\")).toBe(true);\n });\n});\n\n// #endregion PermissionsTest:Module\n// #endregion PermissionsTest\n"
+ "body": "// #region PermissionsTest [C:3] [TYPE Module] [SEMANTICS auth, rbac, permission, test, guard]\n// @BRIEF Verifies frontend RBAC permission parsing and access checks.\n// @RELATION DEPENDS_ON -> [PermissionsModule]\n\n// #region PermissionsTest:Module [TYPE Function]\n// @SEMANTICS: tests, auth, permissions, rbac\n// @PURPOSE: Verifies frontend RBAC permission parsing and access checks.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [PermissionsModule]\n\nimport { describe, it, expect } from \"vitest\";\nimport {\n normalizePermissionRequirement,\n isAdminUser,\n hasPermission,\n} from \"../permissions.js\";\n\ndescribe(\"auth.permissions\", () => {\n it(\"normalizes resource-only requirement with default READ action\", () => {\n expect(normalizePermissionRequirement(\"admin:settings\")).toEqual({\n resource: \"admin:settings\",\n action: \"READ\",\n });\n });\n\n it(\"normalizes explicit resource:action requirement\", () => {\n expect(normalizePermissionRequirement(\"admin:settings:write\")).toEqual({\n resource: \"admin:settings\",\n action: \"WRITE\",\n });\n });\n\n it(\"detects admin role case-insensitively\", () => {\n const user = {\n roles: [{ name: \"ADMIN\" }],\n };\n expect(isAdminUser(user)).toBe(true);\n });\n\n it(\"denies when user is absent and permission is required\", () => {\n expect(hasPermission(null, \"tasks\", \"READ\")).toBe(false);\n });\n\n it(\"grants when permission object matches resource and action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"READ\")).toBe(true);\n });\n\n it(\"grants when requirement is provided as resource:action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"admin:settings\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"admin:settings:READ\")).toBe(true);\n });\n\n it(\"grants when string permission entry matches\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [\"plugin:migration:READ\"],\n },\n ],\n };\n\n expect(hasPermission(user, \"plugin:migration\", \"READ\")).toBe(true);\n });\n\n it(\"denies when action does not match\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"WRITE\")).toBe(false);\n });\n\n it(\"always grants for admin role regardless of explicit permissions\", () => {\n const adminUser = {\n roles: [{ name: \"Admin\", permissions: [] }],\n };\n\n expect(hasPermission(adminUser, \"admin:users\", \"READ\")).toBe(true);\n expect(hasPermission(adminUser, \"plugin:migration\", \"EXECUTE\")).toBe(true);\n });\n});\n\n// #endregion PermissionsTest:Module\n// #endregion PermissionsTest\n"
},
{
"contract_id": "PermissionsTest:Module",
@@ -67521,14 +62699,14 @@
{
"source_id": "PermissionsTest:Module",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:internal:Permissions",
- "target_ref": "[EXT:internal:Permissions]"
+ "target_id": "PermissionsModule",
+ "target_ref": "[PermissionsModule]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region PermissionsTest:Module [TYPE Function]\n// @SEMANTICS: tests, auth, permissions, rbac\n// @PURPOSE: Verifies frontend RBAC permission parsing and access checks.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:internal:Permissions]\n\nimport { describe, it, expect } from \"vitest\";\nimport {\n normalizePermissionRequirement,\n isAdminUser,\n hasPermission,\n} from \"../permissions.js\";\n\ndescribe(\"auth.permissions\", () => {\n it(\"normalizes resource-only requirement with default READ action\", () => {\n expect(normalizePermissionRequirement(\"admin:settings\")).toEqual({\n resource: \"admin:settings\",\n action: \"READ\",\n });\n });\n\n it(\"normalizes explicit resource:action requirement\", () => {\n expect(normalizePermissionRequirement(\"admin:settings:write\")).toEqual({\n resource: \"admin:settings\",\n action: \"WRITE\",\n });\n });\n\n it(\"detects admin role case-insensitively\", () => {\n const user = {\n roles: [{ name: \"ADMIN\" }],\n };\n expect(isAdminUser(user)).toBe(true);\n });\n\n it(\"denies when user is absent and permission is required\", () => {\n expect(hasPermission(null, \"tasks\", \"READ\")).toBe(false);\n });\n\n it(\"grants when permission object matches resource and action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"READ\")).toBe(true);\n });\n\n it(\"grants when requirement is provided as resource:action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"admin:settings\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"admin:settings:READ\")).toBe(true);\n });\n\n it(\"grants when string permission entry matches\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [\"plugin:migration:READ\"],\n },\n ],\n };\n\n expect(hasPermission(user, \"plugin:migration\", \"READ\")).toBe(true);\n });\n\n it(\"denies when action does not match\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"WRITE\")).toBe(false);\n });\n\n it(\"always grants for admin role regardless of explicit permissions\", () => {\n const adminUser = {\n roles: [{ name: \"Admin\", permissions: [] }],\n };\n\n expect(hasPermission(adminUser, \"admin:users\", \"READ\")).toBe(true);\n expect(hasPermission(adminUser, \"plugin:migration\", \"EXECUTE\")).toBe(true);\n });\n});\n\n// #endregion PermissionsTest:Module\n"
+ "body": "// #region PermissionsTest:Module [TYPE Function]\n// @SEMANTICS: tests, auth, permissions, rbac\n// @PURPOSE: Verifies frontend RBAC permission parsing and access checks.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [PermissionsModule]\n\nimport { describe, it, expect } from \"vitest\";\nimport {\n normalizePermissionRequirement,\n isAdminUser,\n hasPermission,\n} from \"../permissions.js\";\n\ndescribe(\"auth.permissions\", () => {\n it(\"normalizes resource-only requirement with default READ action\", () => {\n expect(normalizePermissionRequirement(\"admin:settings\")).toEqual({\n resource: \"admin:settings\",\n action: \"READ\",\n });\n });\n\n it(\"normalizes explicit resource:action requirement\", () => {\n expect(normalizePermissionRequirement(\"admin:settings:write\")).toEqual({\n resource: \"admin:settings\",\n action: \"WRITE\",\n });\n });\n\n it(\"detects admin role case-insensitively\", () => {\n const user = {\n roles: [{ name: \"ADMIN\" }],\n };\n expect(isAdminUser(user)).toBe(true);\n });\n\n it(\"denies when user is absent and permission is required\", () => {\n expect(hasPermission(null, \"tasks\", \"READ\")).toBe(false);\n });\n\n it(\"grants when permission object matches resource and action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"READ\")).toBe(true);\n });\n\n it(\"grants when requirement is provided as resource:action\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"admin:settings\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"admin:settings:READ\")).toBe(true);\n });\n\n it(\"grants when string permission entry matches\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [\"plugin:migration:READ\"],\n },\n ],\n };\n\n expect(hasPermission(user, \"plugin:migration\", \"READ\")).toBe(true);\n });\n\n it(\"denies when action does not match\", () => {\n const user = {\n roles: [\n {\n name: \"Operator\",\n permissions: [{ resource: \"tasks\", action: \"READ\" }],\n },\n ],\n };\n\n expect(hasPermission(user, \"tasks\", \"WRITE\")).toBe(false);\n });\n\n it(\"always grants for admin role regardless of explicit permissions\", () => {\n const adminUser = {\n roles: [{ name: \"Admin\", permissions: [] }],\n };\n\n expect(hasPermission(adminUser, \"admin:users\", \"READ\")).toBe(true);\n expect(hasPermission(adminUser, \"plugin:migration\", \"EXECUTE\")).toBe(true);\n });\n});\n\n// #endregion PermissionsTest:Module\n"
},
{
"contract_id": "PermissionsModule",
@@ -68528,8 +63706,8 @@
{
"source_id": "ScheduleAtAGlance",
"relation_type": "CALLS",
- "target_id": "[EXT:method:ValidationApi.fetchTasks]",
- "target_ref": "[[EXT:method:ValidationApi.fetchTasks]]"
+ "target_id": "EXT:method:ValidationApi.fetchTasks]",
+ "target_ref": "[EXT:method:ValidationApi.fetchTasks]]"
},
{
"source_id": "ScheduleAtAGlance",
@@ -68547,7 +63725,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n
\n
\n
\n \n \n
\n {$t.health?.schedule_title || 'Schedule'}\n \n
\n\n {#if !loading && !error && scheduledTasks.length > 0}\n
\n \n {$t.health?.schedule_active_count?.replace('{count}', String(scheduledTasks.length)) || `${scheduledTasks.length} active`}\n \n · \n \n {$t.health?.schedule_dashboard_count?.replace('{count}', String(totalDashboards)) || `${totalDashboards} dashboards`}\n \n
\n {/if}\n
\n\n \n {#if loading}\n
\n
\n {#each Array(7) as _, i (i)}\n
\n {/each}\n
\n
\n
\n\n \n {:else if error}\n
\n
\n
\n \n \n
{error} \n
\n {$t.common?.retry || 'Retry'}\n \n
\n
\n\n \n {:else if scheduledTasks.length === 0}\n
\n
\n
\n {$t.health?.schedule_empty || 'No active validation schedules.'}\n
\n
\n {$t.health?.schedule_empty_desc || 'Create a validation task with a schedule to see it here.'}\n
\n
\n\n \n {:else}\n
\n
\n \n
\n
\n {#each DAY_SHORT as dayLabel, idx (idx)}\n {@const active = isDayActive(idx)}\n {@const dayTasks = getTasksForDay(idx)}\n
t.id === hoveredTaskId) ? 'ring-2 ring-blue-300' : 'opacity-60') : ''}\"\n title={active ? `${dayTasks.length} task(s) on ${DAY_SHORT[idx]}` : ''}\n >\n \n {$t.validation?.[`days_${dayLabel}`] || dayLabel.toUpperCase()}\n \n {#if active}\n {#each dayTasks.slice(0, 2) as task (task.id)}\n {@const tc = getTaskColor(task)}\n \n {/each}\n {#if dayTasks.length > 2}\n +{dayTasks.length - 2} \n {/if}\n {/if}\n
\n {/each}\n
\n\n \n
\n
\n \n \n {#if scheduledTasks.length === 1}\n
{formatTimeRange(scheduledTasks[0].window_start, scheduledTasks[0].window_end)} \n {:else}\n
{$t.health?.schedule_multi_time || 'Multiple windows'} \n {/if}\n
· \n
{appTimezone} \n
\n
\n\n \n
\n
\n {#each scheduledTasks as task (task.id)}\n {@const status = getTaskStatus(task.id)}\n {@const tc = status ? getStatusStyle(status) : null}\n
handleTaskClick(task.id)}\n onmouseenter={() => (hoveredTaskId = task.id)}\n onmouseleave={() => (hoveredTaskId = null)}\n class=\"w-full text-left flex items-center gap-3 px-3 py-2 rounded-lg border border-transparent hover:border-gray-200 hover:bg-gray-50 transition-all cursor-pointer group\"\n >\n \n \n\n \n \n
\n {task.name} \n {#if task.environment_id}\n \n {task.environment_id}\n \n {/if}\n
\n
\n \n \n {#each DAY_SHORT as dayLabel, idx (idx)}\n {#if taskRunsOnDay(task, idx)}\n \n {$t.validation?.[`days_${dayLabel}`] || dayLabel.slice(0, 2).toUpperCase()}\n \n {:else}\n \n {dayLabel.slice(0, 1).toUpperCase()}\n \n {/if}\n {/each}\n \n · \n {formatTimeRange(task.window_start, task.window_end)} \n · \n \n {Array.isArray(task.dashboard_ids) ? task.dashboard_ids.length : 0} {$t.health?.schedule_dashboards || 'dashboards'}\n \n
\n
\n\n \n \n \n \n \n {/each}\n
\n\n \n {#if nextUpcoming}\n
\n
\n
\n \n \n
{$t.health?.schedule_next || 'Next'}: \n
{nextUpcoming.task.name} \n
· \n
\n {formatNextDay(nextUpcoming.dayIdx)} {nextUpcoming.timeStr?.slice(0, 5)} {appTimezone}\n \n
\n
\n {/if}\n
\n
\n
\n {/if}\n
\n\n"
+ "body": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n
\n
\n
\n \n \n
\n {$t.health?.schedule_title || 'Schedule'}\n \n
\n\n {#if !loading && !error && scheduledTasks.length > 0}\n
\n \n {$t.health?.schedule_active_count?.replace('{count}', String(scheduledTasks.length)) || `${scheduledTasks.length} active`}\n \n · \n \n {$t.health?.schedule_dashboard_count?.replace('{count}', String(totalDashboards)) || `${totalDashboards} dashboards`}\n \n
\n {/if}\n
\n\n \n {#if loading}\n
\n
\n {#each Array(7) as _, i (i)}\n
\n {/each}\n
\n
\n
\n\n \n {:else if error}\n
\n
\n
\n \n \n
{error} \n
\n {$t.common?.retry || 'Retry'}\n \n
\n
\n\n \n {:else if scheduledTasks.length === 0}\n
\n
\n
\n {$t.health?.schedule_empty || 'No active validation schedules.'}\n
\n
\n {$t.health?.schedule_empty_desc || 'Create a validation task with a schedule to see it here.'}\n
\n
\n\n \n {:else}\n
\n
\n \n
\n
\n {#each DAY_SHORT as dayLabel, idx (idx)}\n {@const active = isDayActive(idx)}\n {@const dayTasks = getTasksForDay(idx)}\n
t.id === hoveredTaskId) ? 'ring-2 ring-blue-300' : 'opacity-60') : ''}\"\n title={active ? `${dayTasks.length} task(s) on ${DAY_SHORT[idx]}` : ''}\n >\n \n {$t.validation?.[`days_${dayLabel}`] || dayLabel.toUpperCase()}\n \n {#if active}\n {#each dayTasks.slice(0, 2) as task (task.id)}\n {@const tc = getTaskColor(task)}\n \n {/each}\n {#if dayTasks.length > 2}\n +{dayTasks.length - 2} \n {/if}\n {/if}\n
\n {/each}\n
\n\n \n
\n
\n \n \n {#if scheduledTasks.length === 1}\n
{formatTimeRange(scheduledTasks[0].window_start, scheduledTasks[0].window_end)} \n {:else}\n
{$t.health?.schedule_multi_time || 'Multiple windows'} \n {/if}\n
· \n
{appTimezone} \n
\n
\n\n \n
\n
\n {#each scheduledTasks as task (task.id)}\n {@const status = getTaskStatus(task.id)}\n {@const tc = status ? getStatusStyle(status) : null}\n
handleTaskClick(task.id)}\n onmouseenter={() => (hoveredTaskId = task.id)}\n onmouseleave={() => (hoveredTaskId = null)}\n class=\"w-full text-left flex items-center gap-3 px-3 py-2 rounded-lg border border-transparent hover:border-gray-200 hover:bg-gray-50 transition-all cursor-pointer group\"\n >\n \n \n\n \n \n
\n {task.name} \n {#if task.environment_id}\n \n {task.environment_id}\n \n {/if}\n
\n
\n \n \n {#each DAY_SHORT as dayLabel, idx (idx)}\n {#if taskRunsOnDay(task, idx)}\n \n {$t.validation?.[`days_${dayLabel}`] || dayLabel.slice(0, 2).toUpperCase()}\n \n {:else}\n \n {dayLabel.slice(0, 1).toUpperCase()}\n \n {/if}\n {/each}\n \n · \n {formatTimeRange(task.window_start, task.window_end)} \n · \n \n {Array.isArray(task.dashboard_ids) ? task.dashboard_ids.length : 0} {$t.health?.schedule_dashboards || 'dashboards'}\n \n
\n
\n\n \n \n \n \n \n {/each}\n
\n\n \n {#if nextUpcoming}\n
\n
\n
\n \n \n
{$t.health?.schedule_next || 'Next'}: \n
{nextUpcoming.task.name} \n
· \n
\n {formatNextDay(nextUpcoming.dayIdx)} {nextUpcoming.timeStr?.slice(0, 5)} {appTimezone}\n \n
\n
\n {/if}\n
\n
\n
\n {/if}\n
\n\n"
},
{
"contract_id": "Sidebar",
@@ -68824,12 +64002,48 @@
"tier_source": "AutoCalculated",
"body": "// #region TopNavbarStoreTest:Module [TYPE Function]\n// @UX_STATE: Loading -> Default\n// @PURPOSE: Unit tests for TopNavbar.svelte component\n// @LAYER UI\n// @RELATION DEPENDS_ON -> [EXT:frontend:TopNavbar]\n\nimport { describe, it, expect, beforeEach, vi } from 'vitest';\n\n// Mock dependencies\nvi.mock('$app/environment', () => ({\n browser: true\n}));\n\nvi.mock('$app/stores', () => ({\n page: {\n subscribe: vi.fn((callback) => {\n callback({ url: { pathname: '/dashboards' } });\n return vi.fn();\n })\n }\n}));\n\ndescribe('TopNavbar Component Store Tests', () => {\n beforeEach(() => {\n vi.resetModules();\n });\n\n describe('Sidebar Store Integration', () => {\n it('should read isExpanded from sidebarStore', async () => {\n const { sidebarStore } = await import('$lib/stores/sidebar.js');\n \n let state = null;\n const unsubscribe = sidebarStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.isExpanded).toBe(true);\n });\n\n it('should toggle sidebar via toggleMobileSidebar', async () => {\n const { sidebarStore, toggleMobileSidebar } = await import('$lib/stores/sidebar.js');\n \n let state = null;\n const unsub1 = sidebarStore.subscribe(s => { state = s; });\n unsub1();\n expect(state.isMobileOpen).toBe(false);\n \n toggleMobileSidebar();\n \n const unsub2 = sidebarStore.subscribe(s => { state = s; });\n unsub2();\n expect(state.isMobileOpen).toBe(true);\n });\n });\n\n describe('Activity Store Integration', () => {\n it('should have zero activeCount initially', async () => {\n const { activityStore } = await import('$lib/stores/activity.js');\n \n let state = null;\n const unsubscribe = activityStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.activeCount).toBe(0);\n });\n\n it('should count RUNNING tasks as active', async () => {\n const { updateResourceTask } = await import('$lib/stores/taskDrawer.js');\n const { activityStore } = await import('$lib/stores/activity.js');\n \n // Add a running task\n updateResourceTask('dashboard-1', 'task-1', 'RUNNING');\n \n let state = null;\n const unsubscribe = activityStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.activeCount).toBe(1);\n });\n\n it('should not count SUCCESS tasks as active', async () => {\n const { updateResourceTask } = await import('$lib/stores/taskDrawer.js');\n const { activityStore } = await import('$lib/stores/activity.js');\n \n // Add a success task\n updateResourceTask('dashboard-1', 'task-1', 'SUCCESS');\n \n let state = null;\n const unsubscribe = activityStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.activeCount).toBe(0);\n });\n\n it('should not count WAITING_INPUT as active', async () => {\n const { updateResourceTask } = await import('$lib/stores/taskDrawer.js');\n const { activityStore } = await import('$lib/stores/activity.js');\n \n // Add a waiting input task - should NOT be counted as active per contract\n // Only RUNNING tasks count as active\n updateResourceTask('dashboard-1', 'task-1', 'WAITING_INPUT');\n \n let state = null;\n const unsubscribe = activityStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.activeCount).toBe(0);\n });\n });\n\n describe('Task Drawer Integration', () => {\n it('should open drawer for specific task', async () => {\n const { taskDrawerStore, openDrawerForTask } = await import('$lib/stores/taskDrawer.js');\n \n openDrawerForTask('task-123');\n \n let state = null;\n const unsubscribe = taskDrawerStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.isOpen).toBe(true);\n expect(state.activeTaskId).toBe('task-123');\n });\n\n it('should open drawer in list mode', async () => {\n const { taskDrawerStore, openDrawer } = await import('$lib/stores/taskDrawer.js');\n \n openDrawer();\n \n let state = null;\n const unsubscribe = taskDrawerStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.isOpen).toBe(true);\n expect(state.activeTaskId).toBeNull();\n });\n\n it('should close drawer', async () => {\n const { taskDrawerStore, openDrawerForTask, closeDrawer } = await import('$lib/stores/taskDrawer.js');\n \n // First open drawer\n openDrawerForTask('task-123');\n \n let state = null;\n const unsub1 = taskDrawerStore.subscribe(s => { state = s; });\n unsub1();\n expect(state.isOpen).toBe(true);\n \n closeDrawer();\n \n const unsub2 = taskDrawerStore.subscribe(s => { state = s; });\n unsub2();\n expect(state.isOpen).toBe(false);\n });\n });\n\n describe('UX States', () => {\n it('should support activity badge with count > 0', async () => {\n const { updateResourceTask } = await import('$lib/stores/taskDrawer.js');\n const { activityStore } = await import('$lib/stores/activity.js');\n \n updateResourceTask('dashboard-1', 'task-1', 'RUNNING');\n updateResourceTask('dashboard-2', 'task-2', 'RUNNING');\n \n let state = null;\n const unsubscribe = activityStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.activeCount).toBe(2);\n expect(state.activeCount).toBeGreaterThan(0);\n });\n\n it('should show 9+ for counts exceeding 9', async () => {\n const { updateResourceTask } = await import('$lib/stores/taskDrawer.js');\n const { activityStore } = await import('$lib/stores/activity.js');\n \n // Add 10 running tasks\n for (let i = 0; i < 10; i++) {\n updateResourceTask(`resource-${i}`, `task-${i}`, 'RUNNING');\n }\n \n let state = null;\n const unsubscribe = activityStore.subscribe(s => { state = s; });\n unsubscribe();\n \n expect(state.activeCount).toBe(10);\n });\n });\n});\n\n// #endregion TopNavbarStoreTest:Module\n"
},
+ {
+ "contract_id": "PageContracts",
+ "contract_type": "Interface",
+ "file_path": "frontend/src/lib/components/layout/sidebarNavigation.js",
+ "start_line": 1,
+ "end_line": 3,
+ "tier": "TIER_1",
+ "complexity": 2,
+ "metadata": {
+ "BRIEF": "Contract implemented by all Svelte route pages — defines page-level behavior and routing structure.",
+ "COMPLEXITY": 2
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "// #region PageContracts [C:2] [TYPE Interface]\n// @BRIEF Contract implemented by all Svelte route pages — defines page-level behavior and routing structure.\n// #endregion PageContracts\n"
+ },
+ {
+ "contract_id": "NavigationContracts",
+ "contract_type": "Interface",
+ "file_path": "frontend/src/lib/components/layout/sidebarNavigation.js",
+ "start_line": 5,
+ "end_line": 7,
+ "tier": "TIER_1",
+ "complexity": 2,
+ "metadata": {
+ "BRIEF": "Contract for navigation structure — sidebar sections, route categories, and menu item hierarchy.",
+ "COMPLEXITY": 2
+ },
+ "relations": [],
+ "schema_warnings": [],
+ "anchor_syntax": "region",
+ "tier_source": "AutoCalculated",
+ "body": "// #region NavigationContracts [C:2] [TYPE Interface] \n// @BRIEF Contract for navigation structure — sidebar sections, route categories, and menu item hierarchy.\n// #endregion NavigationContracts\n"
+ },
{
"contract_id": "SidebarNavigation:Module",
"contract_type": "Function",
"file_path": "frontend/src/lib/components/layout/sidebarNavigation.js",
- "start_line": 1,
- "end_line": 229,
+ "start_line": 9,
+ "end_line": 237,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -68848,8 +64062,8 @@
{
"source_id": "SidebarNavigation:Module",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:internal:Permissions",
- "target_ref": "[EXT:internal:Permissions]"
+ "target_id": "PermissionsModule",
+ "target_ref": "[PermissionsModule]"
},
{
"source_id": "SidebarNavigation:Module",
@@ -68861,14 +64075,14 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region SidebarNavigation:Module [TYPE Function]\n// @SEMANTICS: navigation, sidebar, rbac, menu, filtering\n// @PURPOSE: Build sidebar navigation sections and categories filtered by user permissions and feature flags.\n// @LAYER UI\n// @RELATION DEPENDS_ON -> [EXT:internal:Permissions]\n// @RELATION BINDS_TO -> [Sidebar]\n// @INVARIANT: Admin role can access all categories and subitems through permission utility.\n\nimport { hasPermission } from \"$lib/auth/permissions.js\";\n\n// #region isItemAllowed:Function [TYPE Function]\n// @PURPOSE: Check whether a single menu node can be shown for a given user.\n// @PRE: item can contain optional requiredPermission/requiredAction.\n// @POST: Returns true when no permission is required or permission check passes.\nfunction isItemAllowed(user, item) {\n if (!item?.requiredPermission) return true;\n return hasPermission(\n user,\n item.requiredPermission,\n item.requiredAction || \"READ\",\n );\n}\n// #endregion isItemAllowed:Function\n\n// #region isFeatureEnabled:Function [TYPE Function]\nfunction isFeatureEnabled(item, features) {\n if (!item?.requiredFeature) return true;\n return features[item.requiredFeature] !== false;\n}\n// #endregion isFeatureEnabled:Function\n\n// #region buildSidebarSections:Function [TYPE Function]\n// @PURPOSE: Build translated sidebar sections with categories, filtered by RBAC permissions and feature flags.\n// @PRE: i18nState provides nav labels; user can be null; features default to {} (all enabled).\n// @POST: Returns only sections/categories/subitems available for provided user and enabled features.\nexport function buildSidebarSections(i18nState, user, features = {}) {\n const nav = i18nState?.nav || {};\n\n // ── Section 1: Resources ─────────────────────────────────\n const resources = {\n id: \"resources\",\n label: nav.section_resources,\n categories: [\n {\n id: \"dashboards\",\n label: nav.dashboards,\n icon: \"dashboard\",\n tone: \"from-sky-100 to-sky-200 text-sky-700 ring-sky-200\",\n path: \"/dashboards\",\n requiredPermission: \"plugin:migration\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.overview, path: \"/dashboards\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n { label: nav.health_center, path: \"/dashboards/health\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\", requiredFeature: \"health_monitor\" },\n ],\n },\n {\n id: \"datasets\",\n label: nav.datasets,\n icon: \"database\",\n tone: \"from-emerald-100 to-emerald-200 text-emerald-700 ring-emerald-200\",\n path: \"/datasets\",\n requiredPermission: \"plugin:migration\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.all_datasets, path: \"/datasets\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n { label: nav.dataset_review_workspace, path: \"/datasets/review\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\", requiredFeature: \"dataset_review\" },\n ],\n },\n {\n id: \"migration\",\n label: nav.migration,\n icon: \"layers\",\n tone: \"from-orange-100 to-orange-200 text-orange-700 ring-orange-200\",\n path: \"/migration\",\n requiredPermission: \"plugin:migration\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.migration_overview || \"Overview\", path: \"/migration\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n { label: nav.migration_mappings || \"Mappings\", path: \"/migration/mappings\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n ],\n },\n ],\n };\n\n // ── Section 2: Operations ────────────────────────────────\n const operations = {\n id: \"operations\",\n label: nav.section_operations,\n categories: [\n {\n id: \"git\",\n label: nav.git,\n icon: \"activity\",\n tone: \"from-purple-100 to-purple-200 text-purple-700 ring-purple-200\",\n path: \"/git\",\n subItems: [\n { label: nav.git_repo_status || \"Repository Status\", path: \"/git\" },\n ],\n },\n {\n id: \"translation\",\n label: nav.translation,\n icon: \"translate\",\n tone: \"from-cyan-100 to-teal-100 text-teal-700 ring-teal-200\",\n path: \"/translate\",\n requiredPermission: \"translate.job\",\n requiredAction: \"VIEW\",\n subItems: [\n { label: nav.translation_jobs, path: \"/translate\", requiredPermission: \"translate.job\", requiredAction: \"VIEW\" },\n { label: nav.translation_dictionaries, path: \"/translate/dictionaries\", requiredPermission: \"translate.dictionary\", requiredAction: \"VIEW\" },\n { label: nav.translation_history, path: \"/translate/history\", requiredPermission: \"translate.job\", requiredAction: \"VIEW\" },\n ],\n },\n {\n id: \"validation\",\n label: nav.validation,\n icon: \"activity\",\n tone: \"from-amber-100 to-yellow-100 text-amber-700 ring-amber-200\",\n path: \"/validation\",\n requiredPermission: \"validation.task\",\n requiredAction: \"VIEW\",\n subItems: [\n { label: nav.validation_tasks, path: \"/validation\", requiredPermission: \"validation.task\", requiredAction: \"VIEW\" },\n { label: nav.validation_history, path: \"/validation/history\", requiredPermission: \"validation.run\", requiredAction: \"VIEW\" },\n ],\n },\n {\n id: \"reports\",\n label: nav.reports,\n icon: \"reports\",\n tone: \"from-violet-100 to-fuchsia-100 text-violet-700 ring-violet-200\",\n path: \"/reports\",\n requiredPermission: \"tasks\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.all_reports || \"All Reports\", path: \"/reports\", requiredPermission: \"tasks\", requiredAction: \"READ\" },\n ],\n },\n ],\n };\n\n // ── Section 3: System ────────────────────────────────────\n const system = {\n id: \"system\",\n label: nav.section_system,\n categories: [\n {\n id: \"tools\",\n label: nav.tools,\n icon: \"list\",\n tone: \"from-slate-100 to-slate-200 text-slate-700 ring-slate-200\",\n path: \"/tools/mapper\",\n subItems: [\n { label: nav.tools_mapper, path: \"/tools/mapper\" },\n { label: nav.tools_debug, path: \"/tools/debug\" },\n { label: nav.tools_storage, path: \"/tools/storage\" },\n { label: nav.tools_backups, path: \"/tools/backups\" },\n ],\n },\n {\n id: \"storage\",\n label: nav.storage,\n icon: \"storage\",\n tone: \"from-amber-100 to-amber-200 text-amber-800 ring-amber-200\",\n path: \"/storage\",\n requiredPermission: \"plugin:storage\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.repositories, path: \"/storage/repos\", requiredPermission: \"plugin:storage\", requiredAction: \"READ\" },\n ],\n },\n {\n id: \"admin\",\n label: nav.admin,\n icon: \"admin\",\n tone: \"from-rose-100 to-rose-200 text-rose-700 ring-rose-200\",\n path: \"/admin/users\",\n subItems: [\n { label: nav.admin_users, path: \"/admin/users\", requiredPermission: \"admin:users\", requiredAction: \"READ\" },\n { label: nav.admin_roles, path: \"/admin/roles\", requiredPermission: \"admin:roles\", requiredAction: \"READ\" },\n { label: nav.admin_settings, path: \"/admin/settings\", requiredPermission: \"admin:settings\", requiredAction: \"READ\" },\n { label: nav.admin_llm, path: \"/admin/settings/llm\", requiredPermission: \"admin:settings\", requiredAction: \"READ\" },\n ],\n },\n {\n id: \"maintenance\",\n label: nav.maintenance || \"Maintenance\",\n icon: \"activity\",\n tone: \"from-orange-100 to-orange-200 text-orange-700 ring-orange-200\",\n path: \"/maintenance\",\n requiredPermission: \"maintenance:write\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.maintenance || \"Maintenance\", path: \"/maintenance\", requiredPermission: \"maintenance:write\", requiredAction: \"READ\" },\n ],\n },\n ],\n };\n\n const allSections = [resources, operations, system];\n\n // Filter by permissions and features\n return allSections\n .map((section) => ({\n ...section,\n categories: section.categories\n .map((category) => {\n const visibleSubItems = (category.subItems || []).filter(\n (sub) => isItemAllowed(user, sub) && isFeatureEnabled(sub, features),\n );\n return { ...category, subItems: visibleSubItems };\n })\n .filter((category) => {\n if (!isItemAllowed(user, category)) return false;\n return Array.isArray(category.subItems) && category.subItems.length > 0;\n }),\n }))\n .filter((section) => section.categories.length > 0);\n}\n// #endregion buildSidebarSections:Function\n\n// ── Legacy adapter for backward compatibility ──────────────\n// @DEPRECATED Use buildSidebarSections instead. Returns flat category list for old consumers.\nexport function buildSidebarCategories(i18nState, user, features = {}) {\n const sections = buildSidebarSections(i18nState, user, features);\n return sections.flatMap((s) => s.categories);\n}\n// #endregion SidebarNavigation:Module\n"
+ "body": "// #region SidebarNavigation:Module [TYPE Function]\n// @SEMANTICS: navigation, sidebar, rbac, menu, filtering\n// @PURPOSE: Build sidebar navigation sections and categories filtered by user permissions and feature flags.\n// @LAYER UI\n// @RELATION DEPENDS_ON -> [PermissionsModule]\n// @RELATION BINDS_TO -> [Sidebar]\n// @INVARIANT: Admin role can access all categories and subitems through permission utility.\n\nimport { hasPermission } from \"$lib/auth/permissions.js\";\n\n// #region isItemAllowed:Function [TYPE Function]\n// @PURPOSE: Check whether a single menu node can be shown for a given user.\n// @PRE: item can contain optional requiredPermission/requiredAction.\n// @POST: Returns true when no permission is required or permission check passes.\nfunction isItemAllowed(user, item) {\n if (!item?.requiredPermission) return true;\n return hasPermission(\n user,\n item.requiredPermission,\n item.requiredAction || \"READ\",\n );\n}\n// #endregion isItemAllowed:Function\n\n// #region isFeatureEnabled:Function [TYPE Function]\nfunction isFeatureEnabled(item, features) {\n if (!item?.requiredFeature) return true;\n return features[item.requiredFeature] !== false;\n}\n// #endregion isFeatureEnabled:Function\n\n// #region buildSidebarSections:Function [TYPE Function]\n// @PURPOSE: Build translated sidebar sections with categories, filtered by RBAC permissions and feature flags.\n// @PRE: i18nState provides nav labels; user can be null; features default to {} (all enabled).\n// @POST: Returns only sections/categories/subitems available for provided user and enabled features.\nexport function buildSidebarSections(i18nState, user, features = {}) {\n const nav = i18nState?.nav || {};\n\n // ── Section 1: Resources ─────────────────────────────────\n const resources = {\n id: \"resources\",\n label: nav.section_resources,\n categories: [\n {\n id: \"dashboards\",\n label: nav.dashboards,\n icon: \"dashboard\",\n tone: \"from-sky-100 to-sky-200 text-sky-700 ring-sky-200\",\n path: \"/dashboards\",\n requiredPermission: \"plugin:migration\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.overview, path: \"/dashboards\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n { label: nav.health_center, path: \"/dashboards/health\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\", requiredFeature: \"health_monitor\" },\n ],\n },\n {\n id: \"datasets\",\n label: nav.datasets,\n icon: \"database\",\n tone: \"from-emerald-100 to-emerald-200 text-emerald-700 ring-emerald-200\",\n path: \"/datasets\",\n requiredPermission: \"plugin:migration\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.all_datasets, path: \"/datasets\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n { label: nav.dataset_review_workspace, path: \"/datasets/review\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\", requiredFeature: \"dataset_review\" },\n ],\n },\n {\n id: \"migration\",\n label: nav.migration,\n icon: \"layers\",\n tone: \"from-orange-100 to-orange-200 text-orange-700 ring-orange-200\",\n path: \"/migration\",\n requiredPermission: \"plugin:migration\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.migration_overview || \"Overview\", path: \"/migration\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n { label: nav.migration_mappings || \"Mappings\", path: \"/migration/mappings\", requiredPermission: \"plugin:migration\", requiredAction: \"READ\" },\n ],\n },\n ],\n };\n\n // ── Section 2: Operations ────────────────────────────────\n const operations = {\n id: \"operations\",\n label: nav.section_operations,\n categories: [\n {\n id: \"git\",\n label: nav.git,\n icon: \"activity\",\n tone: \"from-purple-100 to-purple-200 text-purple-700 ring-purple-200\",\n path: \"/git\",\n subItems: [\n { label: nav.git_repo_status || \"Repository Status\", path: \"/git\" },\n ],\n },\n {\n id: \"translation\",\n label: nav.translation,\n icon: \"translate\",\n tone: \"from-cyan-100 to-teal-100 text-teal-700 ring-teal-200\",\n path: \"/translate\",\n requiredPermission: \"translate.job\",\n requiredAction: \"VIEW\",\n subItems: [\n { label: nav.translation_jobs, path: \"/translate\", requiredPermission: \"translate.job\", requiredAction: \"VIEW\" },\n { label: nav.translation_dictionaries, path: \"/translate/dictionaries\", requiredPermission: \"translate.dictionary\", requiredAction: \"VIEW\" },\n { label: nav.translation_history, path: \"/translate/history\", requiredPermission: \"translate.job\", requiredAction: \"VIEW\" },\n ],\n },\n {\n id: \"validation\",\n label: nav.validation,\n icon: \"activity\",\n tone: \"from-amber-100 to-yellow-100 text-amber-700 ring-amber-200\",\n path: \"/validation\",\n requiredPermission: \"validation.task\",\n requiredAction: \"VIEW\",\n subItems: [\n { label: nav.validation_tasks, path: \"/validation\", requiredPermission: \"validation.task\", requiredAction: \"VIEW\" },\n { label: nav.validation_history, path: \"/validation/history\", requiredPermission: \"validation.run\", requiredAction: \"VIEW\" },\n ],\n },\n {\n id: \"reports\",\n label: nav.reports,\n icon: \"reports\",\n tone: \"from-violet-100 to-fuchsia-100 text-violet-700 ring-violet-200\",\n path: \"/reports\",\n requiredPermission: \"tasks\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.all_reports || \"All Reports\", path: \"/reports\", requiredPermission: \"tasks\", requiredAction: \"READ\" },\n ],\n },\n ],\n };\n\n // ── Section 3: System ────────────────────────────────────\n const system = {\n id: \"system\",\n label: nav.section_system,\n categories: [\n {\n id: \"tools\",\n label: nav.tools,\n icon: \"list\",\n tone: \"from-slate-100 to-slate-200 text-slate-700 ring-slate-200\",\n path: \"/tools/mapper\",\n subItems: [\n { label: nav.tools_mapper, path: \"/tools/mapper\" },\n { label: nav.tools_debug, path: \"/tools/debug\" },\n { label: nav.tools_storage, path: \"/tools/storage\" },\n { label: nav.tools_backups, path: \"/tools/backups\" },\n ],\n },\n {\n id: \"storage\",\n label: nav.storage,\n icon: \"storage\",\n tone: \"from-amber-100 to-amber-200 text-amber-800 ring-amber-200\",\n path: \"/storage\",\n requiredPermission: \"plugin:storage\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.repositories, path: \"/storage/repos\", requiredPermission: \"plugin:storage\", requiredAction: \"READ\" },\n ],\n },\n {\n id: \"admin\",\n label: nav.admin,\n icon: \"admin\",\n tone: \"from-rose-100 to-rose-200 text-rose-700 ring-rose-200\",\n path: \"/admin/users\",\n subItems: [\n { label: nav.admin_users, path: \"/admin/users\", requiredPermission: \"admin:users\", requiredAction: \"READ\" },\n { label: nav.admin_roles, path: \"/admin/roles\", requiredPermission: \"admin:roles\", requiredAction: \"READ\" },\n { label: nav.admin_settings, path: \"/admin/settings\", requiredPermission: \"admin:settings\", requiredAction: \"READ\" },\n { label: nav.admin_llm, path: \"/admin/settings/llm\", requiredPermission: \"admin:settings\", requiredAction: \"READ\" },\n ],\n },\n {\n id: \"maintenance\",\n label: nav.maintenance || \"Maintenance\",\n icon: \"activity\",\n tone: \"from-orange-100 to-orange-200 text-orange-700 ring-orange-200\",\n path: \"/maintenance\",\n requiredPermission: \"maintenance:write\",\n requiredAction: \"READ\",\n subItems: [\n { label: nav.maintenance || \"Maintenance\", path: \"/maintenance\", requiredPermission: \"maintenance:write\", requiredAction: \"READ\" },\n ],\n },\n ],\n };\n\n const allSections = [resources, operations, system];\n\n // Filter by permissions and features\n return allSections\n .map((section) => ({\n ...section,\n categories: section.categories\n .map((category) => {\n const visibleSubItems = (category.subItems || []).filter(\n (sub) => isItemAllowed(user, sub) && isFeatureEnabled(sub, features),\n );\n return { ...category, subItems: visibleSubItems };\n })\n .filter((category) => {\n if (!isItemAllowed(user, category)) return false;\n return Array.isArray(category.subItems) && category.subItems.length > 0;\n }),\n }))\n .filter((section) => section.categories.length > 0);\n}\n// #endregion buildSidebarSections:Function\n\n// ── Legacy adapter for backward compatibility ──────────────\n// @DEPRECATED Use buildSidebarSections instead. Returns flat category list for old consumers.\nexport function buildSidebarCategories(i18nState, user, features = {}) {\n const sections = buildSidebarSections(i18nState, user, features);\n return sections.flatMap((s) => s.categories);\n}\n// #endregion SidebarNavigation:Module\n"
},
{
"contract_id": "isItemAllowed:Function",
"contract_type": "Function",
"file_path": "frontend/src/lib/components/layout/sidebarNavigation.js",
- "start_line": 11,
- "end_line": 23,
+ "start_line": 19,
+ "end_line": 31,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -68886,8 +64100,8 @@
"contract_id": "isFeatureEnabled:Function",
"contract_type": "Function",
"file_path": "frontend/src/lib/components/layout/sidebarNavigation.js",
- "start_line": 25,
- "end_line": 30,
+ "start_line": 33,
+ "end_line": 38,
"tier": "TIER_1",
"complexity": 1,
"metadata": {},
@@ -68901,8 +64115,8 @@
"contract_id": "buildSidebarSections:Function",
"contract_type": "Function",
"file_path": "frontend/src/lib/components/layout/sidebarNavigation.js",
- "start_line": 32,
- "end_line": 221,
+ "start_line": 40,
+ "end_line": 229,
"tier": "TIER_1",
"complexity": 1,
"metadata": {
@@ -69049,14 +64263,14 @@
{
"source_id": "[EXT:frontend:ReportTypeProfiles]Test:Module",
"relation_type": "DEPENDS_ON",
- "target_id": "[EXT:frontend:ReportTypeProfiles]",
- "target_ref": "[[EXT:frontend:ReportTypeProfiles]]"
+ "target_id": "EXT:frontend:ReportTypeProfiles]",
+ "target_ref": "[EXT:frontend:ReportTypeProfiles]]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region [EXT:frontend:ReportTypeProfiles]Test:Module [TYPE Function]\n// @SEMANTICS: tests, reports, type-profiles, fallback\n// @PURPOSE: Validate report type profile mapping and unknown fallback behavior.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [[EXT:frontend:ReportTypeProfiles]]\n// @INVARIANT: Unknown task_type always resolves to the fallback profile.\n\nimport { describe, it, expect } from 'vitest';\nimport { getReportTypeProfile, REPORT_TYPE_PROFILES } from '../reportTypeProfiles.js';\n\ndescribe('report type profiles', () => {\n it('returns dedicated profiles for known task types', () => {\n expect(getReportTypeProfile('llm_verification').key).toBe('llm_verification');\n expect(getReportTypeProfile('backup').key).toBe('backup');\n expect(getReportTypeProfile('migration').key).toBe('migration');\n expect(getReportTypeProfile('documentation').key).toBe('documentation');\n });\n\n it('returns fallback profile for unknown task type', () => {\n const profile = getReportTypeProfile('something_new');\n expect(profile.key).toBe('unknown');\n expect(profile.fallback).toBe(true);\n });\n\n it('contains exactly one fallback profile in registry', () => {\n const fallbackCount = Object.values(REPORT_TYPE_PROFILES).filter((p) => p.fallback === true).length;\n expect(fallbackCount).toBe(1);\n });\n});\n\n// #endregion [EXT:frontend:ReportTypeProfiles]Test:Module\n"
+ "body": "// #region [EXT:frontend:ReportTypeProfiles]Test:Module [TYPE Function]\n// @SEMANTICS: tests, reports, type-profiles, fallback\n// @PURPOSE: Validate report type profile mapping and unknown fallback behavior.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:frontend:ReportTypeProfiles]]\n// @INVARIANT: Unknown task_type always resolves to the fallback profile.\n\nimport { describe, it, expect } from 'vitest';\nimport { getReportTypeProfile, REPORT_TYPE_PROFILES } from '../reportTypeProfiles.js';\n\ndescribe('report type profiles', () => {\n it('returns dedicated profiles for known task types', () => {\n expect(getReportTypeProfile('llm_verification').key).toBe('llm_verification');\n expect(getReportTypeProfile('backup').key).toBe('backup');\n expect(getReportTypeProfile('migration').key).toBe('migration');\n expect(getReportTypeProfile('documentation').key).toBe('documentation');\n });\n\n it('returns fallback profile for unknown task type', () => {\n const profile = getReportTypeProfile('something_new');\n expect(profile.key).toBe('unknown');\n expect(profile.fallback).toBe(true);\n });\n\n it('contains exactly one fallback profile in registry', () => {\n const fallbackCount = Object.values(REPORT_TYPE_PROFILES).filter((p) => p.fallback === true).length;\n expect(fallbackCount).toBe(1);\n });\n});\n\n// #endregion [EXT:frontend:ReportTypeProfiles]Test:Module\n"
},
{
"contract_id": "ReportsFilterPerformanceTest:Module",
@@ -70355,7 +65569,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region [EXT:frontend:AssistantChatTest]s [C:3] [TYPE Module] [SEMANTICS assistant, chat, store, test, session]\n// @BRIEF Unit tests for assistant chat store validating open/close/toggle, conversation binding, session context, and seed message state transitions.\n// @RELATION DEPENDS_ON -> [AssistantChatStore]\n\n// #region [EXT:frontend:AssistantChatTest]:Module [TYPE Function]\n// @SEMANTICS: test, store, assistant, toggle, conversation\n// @PURPOSE: Validate assistant chat store visibility and conversation binding transitions.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:frontend:assistantChat]\n// @INVARIANT: Each test starts from default closed state.\n\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { get } from 'svelte/store';\nimport {\n assistantChatStore,\n toggleAssistantChat,\n openAssistantChat,\n closeAssistantChat,\n setAssistantConversationId,\n openAssistantChatWithContext,\n setAssistantDatasetReviewSessionId,\n setAssistantFocusTarget,\n} from '../assistantChat.js';\n\n// #region assistantChatStore_tests:Function [TYPE Function]\n// @RELATION BINDS_TO -> [[EXT:frontend:AssistantChatTest]]\n// @PURPOSE: Group store unit scenarios for assistant panel behavior.\n// @PRE: Store can be reset to baseline state in beforeEach hook.\n// @POST: Open/close/toggle/conversation transitions are validated.\ndescribe('assistantChatStore', () => {\n beforeEach(() => {\n assistantChatStore.set({\n isOpen: false,\n conversationId: null,\n datasetReviewSessionId: null,\n seedMessage: '',\n focusTarget: null,\n });\n });\n\n it('should open assistant panel', () => {\n openAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n });\n\n it('should close assistant panel', () => {\n openAssistantChat();\n closeAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(false);\n });\n\n it('should toggle assistant panel state', () => {\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(true);\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(false);\n });\n\n it('should set conversation id', () => {\n setAssistantConversationId('conv-123');\n const state = get(assistantChatStore);\n expect(state.conversationId).toBe('conv-123');\n });\n\n it('should open assistant panel with dataset review context', () => {\n openAssistantChatWithContext({\n datasetReviewSessionId: 'session-42',\n seedMessage: 'Explain mapping warning',\n focusTarget: { target: 'mapping:m-1', source: 'test' },\n });\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n expect(state.datasetReviewSessionId).toBe('session-42');\n expect(state.seedMessage).toBe('Explain mapping warning');\n expect(state.focusTarget).toEqual({ target: 'mapping:m-1', source: 'test' });\n });\n\n it('should update dataset review session id and focus target independently', () => {\n setAssistantDatasetReviewSessionId('session-99');\n setAssistantFocusTarget({ target: 'finding:f-1', source: 'test' });\n const state = get(assistantChatStore);\n expect(state.datasetReviewSessionId).toBe('session-99');\n expect(state.focusTarget).toEqual({ target: 'finding:f-1', source: 'test' });\n });\n});\n// #endregion assistantChatStore_tests:Function\n// #endregion [EXT:frontend:AssistantChatTest]:Module\n// #endregion [EXT:frontend:AssistantChatTest]s\n"
+ "body": "// #region [EXT:frontend:AssistantChatTest]s [C:3] [TYPE Module] [SEMANTICS assistant, chat, store, test, session]\n// @BRIEF Unit tests for assistant chat store validating open/close/toggle, conversation binding, session context, and seed message state transitions.\n// @RELATION DEPENDS_ON -> [AssistantChatStore]\n\n// #region [EXT:frontend:AssistantChatTest]:Module [TYPE Function]\n// @SEMANTICS: test, store, assistant, toggle, conversation\n// @PURPOSE: Validate assistant chat store visibility and conversation binding transitions.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:frontend:assistantChat]\n// @INVARIANT: Each test starts from default closed state.\n\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { get } from 'svelte/store';\nimport {\n assistantChatStore,\n toggleAssistantChat,\n openAssistantChat,\n closeAssistantChat,\n setAssistantConversationId,\n openAssistantChatWithContext,\n setAssistantDatasetReviewSessionId,\n setAssistantFocusTarget,\n} from '../assistantChat.js';\n\n// #region assistantChatStore_tests:Function [TYPE Function]\n// @RELATION BINDS_TO -> [EXT:frontend:AssistantChatTest]]\n// @PURPOSE: Group store unit scenarios for assistant panel behavior.\n// @PRE: Store can be reset to baseline state in beforeEach hook.\n// @POST: Open/close/toggle/conversation transitions are validated.\ndescribe('assistantChatStore', () => {\n beforeEach(() => {\n assistantChatStore.set({\n isOpen: false,\n conversationId: null,\n datasetReviewSessionId: null,\n seedMessage: '',\n focusTarget: null,\n });\n });\n\n it('should open assistant panel', () => {\n openAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n });\n\n it('should close assistant panel', () => {\n openAssistantChat();\n closeAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(false);\n });\n\n it('should toggle assistant panel state', () => {\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(true);\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(false);\n });\n\n it('should set conversation id', () => {\n setAssistantConversationId('conv-123');\n const state = get(assistantChatStore);\n expect(state.conversationId).toBe('conv-123');\n });\n\n it('should open assistant panel with dataset review context', () => {\n openAssistantChatWithContext({\n datasetReviewSessionId: 'session-42',\n seedMessage: 'Explain mapping warning',\n focusTarget: { target: 'mapping:m-1', source: 'test' },\n });\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n expect(state.datasetReviewSessionId).toBe('session-42');\n expect(state.seedMessage).toBe('Explain mapping warning');\n expect(state.focusTarget).toEqual({ target: 'mapping:m-1', source: 'test' });\n });\n\n it('should update dataset review session id and focus target independently', () => {\n setAssistantDatasetReviewSessionId('session-99');\n setAssistantFocusTarget({ target: 'finding:f-1', source: 'test' });\n const state = get(assistantChatStore);\n expect(state.datasetReviewSessionId).toBe('session-99');\n expect(state.focusTarget).toEqual({ target: 'finding:f-1', source: 'test' });\n });\n});\n// #endregion assistantChatStore_tests:Function\n// #endregion [EXT:frontend:AssistantChatTest]:Module\n// #endregion [EXT:frontend:AssistantChatTest]s\n"
},
{
"contract_id": "[EXT:frontend:AssistantChatTest]:Module",
@@ -70388,7 +65602,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region [EXT:frontend:AssistantChatTest]:Module [TYPE Function]\n// @SEMANTICS: test, store, assistant, toggle, conversation\n// @PURPOSE: Validate assistant chat store visibility and conversation binding transitions.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:frontend:assistantChat]\n// @INVARIANT: Each test starts from default closed state.\n\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { get } from 'svelte/store';\nimport {\n assistantChatStore,\n toggleAssistantChat,\n openAssistantChat,\n closeAssistantChat,\n setAssistantConversationId,\n openAssistantChatWithContext,\n setAssistantDatasetReviewSessionId,\n setAssistantFocusTarget,\n} from '../assistantChat.js';\n\n// #region assistantChatStore_tests:Function [TYPE Function]\n// @RELATION BINDS_TO -> [[EXT:frontend:AssistantChatTest]]\n// @PURPOSE: Group store unit scenarios for assistant panel behavior.\n// @PRE: Store can be reset to baseline state in beforeEach hook.\n// @POST: Open/close/toggle/conversation transitions are validated.\ndescribe('assistantChatStore', () => {\n beforeEach(() => {\n assistantChatStore.set({\n isOpen: false,\n conversationId: null,\n datasetReviewSessionId: null,\n seedMessage: '',\n focusTarget: null,\n });\n });\n\n it('should open assistant panel', () => {\n openAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n });\n\n it('should close assistant panel', () => {\n openAssistantChat();\n closeAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(false);\n });\n\n it('should toggle assistant panel state', () => {\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(true);\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(false);\n });\n\n it('should set conversation id', () => {\n setAssistantConversationId('conv-123');\n const state = get(assistantChatStore);\n expect(state.conversationId).toBe('conv-123');\n });\n\n it('should open assistant panel with dataset review context', () => {\n openAssistantChatWithContext({\n datasetReviewSessionId: 'session-42',\n seedMessage: 'Explain mapping warning',\n focusTarget: { target: 'mapping:m-1', source: 'test' },\n });\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n expect(state.datasetReviewSessionId).toBe('session-42');\n expect(state.seedMessage).toBe('Explain mapping warning');\n expect(state.focusTarget).toEqual({ target: 'mapping:m-1', source: 'test' });\n });\n\n it('should update dataset review session id and focus target independently', () => {\n setAssistantDatasetReviewSessionId('session-99');\n setAssistantFocusTarget({ target: 'finding:f-1', source: 'test' });\n const state = get(assistantChatStore);\n expect(state.datasetReviewSessionId).toBe('session-99');\n expect(state.focusTarget).toEqual({ target: 'finding:f-1', source: 'test' });\n });\n});\n// #endregion assistantChatStore_tests:Function\n// #endregion [EXT:frontend:AssistantChatTest]:Module\n"
+ "body": "// #region [EXT:frontend:AssistantChatTest]:Module [TYPE Function]\n// @SEMANTICS: test, store, assistant, toggle, conversation\n// @PURPOSE: Validate assistant chat store visibility and conversation binding transitions.\n// @LAYER UI (Tests)\n// @RELATION DEPENDS_ON -> [EXT:frontend:assistantChat]\n// @INVARIANT: Each test starts from default closed state.\n\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { get } from 'svelte/store';\nimport {\n assistantChatStore,\n toggleAssistantChat,\n openAssistantChat,\n closeAssistantChat,\n setAssistantConversationId,\n openAssistantChatWithContext,\n setAssistantDatasetReviewSessionId,\n setAssistantFocusTarget,\n} from '../assistantChat.js';\n\n// #region assistantChatStore_tests:Function [TYPE Function]\n// @RELATION BINDS_TO -> [EXT:frontend:AssistantChatTest]]\n// @PURPOSE: Group store unit scenarios for assistant panel behavior.\n// @PRE: Store can be reset to baseline state in beforeEach hook.\n// @POST: Open/close/toggle/conversation transitions are validated.\ndescribe('assistantChatStore', () => {\n beforeEach(() => {\n assistantChatStore.set({\n isOpen: false,\n conversationId: null,\n datasetReviewSessionId: null,\n seedMessage: '',\n focusTarget: null,\n });\n });\n\n it('should open assistant panel', () => {\n openAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n });\n\n it('should close assistant panel', () => {\n openAssistantChat();\n closeAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(false);\n });\n\n it('should toggle assistant panel state', () => {\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(true);\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(false);\n });\n\n it('should set conversation id', () => {\n setAssistantConversationId('conv-123');\n const state = get(assistantChatStore);\n expect(state.conversationId).toBe('conv-123');\n });\n\n it('should open assistant panel with dataset review context', () => {\n openAssistantChatWithContext({\n datasetReviewSessionId: 'session-42',\n seedMessage: 'Explain mapping warning',\n focusTarget: { target: 'mapping:m-1', source: 'test' },\n });\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n expect(state.datasetReviewSessionId).toBe('session-42');\n expect(state.seedMessage).toBe('Explain mapping warning');\n expect(state.focusTarget).toEqual({ target: 'mapping:m-1', source: 'test' });\n });\n\n it('should update dataset review session id and focus target independently', () => {\n setAssistantDatasetReviewSessionId('session-99');\n setAssistantFocusTarget({ target: 'finding:f-1', source: 'test' });\n const state = get(assistantChatStore);\n expect(state.datasetReviewSessionId).toBe('session-99');\n expect(state.focusTarget).toEqual({ target: 'finding:f-1', source: 'test' });\n });\n});\n// #endregion assistantChatStore_tests:Function\n// #endregion [EXT:frontend:AssistantChatTest]:Module\n"
},
{
"contract_id": "assistantChatStore_tests:Function",
@@ -70407,14 +65621,14 @@
{
"source_id": "assistantChatStore_tests:Function",
"relation_type": "BINDS_TO",
- "target_id": "[EXT:frontend:AssistantChatTest]",
- "target_ref": "[[EXT:frontend:AssistantChatTest]]"
+ "target_id": "EXT:frontend:AssistantChatTest]",
+ "target_ref": "[EXT:frontend:AssistantChatTest]]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region assistantChatStore_tests:Function [TYPE Function]\n// @RELATION BINDS_TO -> [[EXT:frontend:AssistantChatTest]]\n// @PURPOSE: Group store unit scenarios for assistant panel behavior.\n// @PRE: Store can be reset to baseline state in beforeEach hook.\n// @POST: Open/close/toggle/conversation transitions are validated.\ndescribe('assistantChatStore', () => {\n beforeEach(() => {\n assistantChatStore.set({\n isOpen: false,\n conversationId: null,\n datasetReviewSessionId: null,\n seedMessage: '',\n focusTarget: null,\n });\n });\n\n it('should open assistant panel', () => {\n openAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n });\n\n it('should close assistant panel', () => {\n openAssistantChat();\n closeAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(false);\n });\n\n it('should toggle assistant panel state', () => {\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(true);\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(false);\n });\n\n it('should set conversation id', () => {\n setAssistantConversationId('conv-123');\n const state = get(assistantChatStore);\n expect(state.conversationId).toBe('conv-123');\n });\n\n it('should open assistant panel with dataset review context', () => {\n openAssistantChatWithContext({\n datasetReviewSessionId: 'session-42',\n seedMessage: 'Explain mapping warning',\n focusTarget: { target: 'mapping:m-1', source: 'test' },\n });\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n expect(state.datasetReviewSessionId).toBe('session-42');\n expect(state.seedMessage).toBe('Explain mapping warning');\n expect(state.focusTarget).toEqual({ target: 'mapping:m-1', source: 'test' });\n });\n\n it('should update dataset review session id and focus target independently', () => {\n setAssistantDatasetReviewSessionId('session-99');\n setAssistantFocusTarget({ target: 'finding:f-1', source: 'test' });\n const state = get(assistantChatStore);\n expect(state.datasetReviewSessionId).toBe('session-99');\n expect(state.focusTarget).toEqual({ target: 'finding:f-1', source: 'test' });\n });\n});\n// #endregion assistantChatStore_tests:Function\n"
+ "body": "// #region assistantChatStore_tests:Function [TYPE Function]\n// @RELATION BINDS_TO -> [EXT:frontend:AssistantChatTest]]\n// @PURPOSE: Group store unit scenarios for assistant panel behavior.\n// @PRE: Store can be reset to baseline state in beforeEach hook.\n// @POST: Open/close/toggle/conversation transitions are validated.\ndescribe('assistantChatStore', () => {\n beforeEach(() => {\n assistantChatStore.set({\n isOpen: false,\n conversationId: null,\n datasetReviewSessionId: null,\n seedMessage: '',\n focusTarget: null,\n });\n });\n\n it('should open assistant panel', () => {\n openAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n });\n\n it('should close assistant panel', () => {\n openAssistantChat();\n closeAssistantChat();\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(false);\n });\n\n it('should toggle assistant panel state', () => {\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(true);\n toggleAssistantChat();\n expect(get(assistantChatStore).isOpen).toBe(false);\n });\n\n it('should set conversation id', () => {\n setAssistantConversationId('conv-123');\n const state = get(assistantChatStore);\n expect(state.conversationId).toBe('conv-123');\n });\n\n it('should open assistant panel with dataset review context', () => {\n openAssistantChatWithContext({\n datasetReviewSessionId: 'session-42',\n seedMessage: 'Explain mapping warning',\n focusTarget: { target: 'mapping:m-1', source: 'test' },\n });\n const state = get(assistantChatStore);\n expect(state.isOpen).toBe(true);\n expect(state.datasetReviewSessionId).toBe('session-42');\n expect(state.seedMessage).toBe('Explain mapping warning');\n expect(state.focusTarget).toEqual({ target: 'mapping:m-1', source: 'test' });\n });\n\n it('should update dataset review session id and focus target independently', () => {\n setAssistantDatasetReviewSessionId('session-99');\n setAssistantFocusTarget({ target: 'finding:f-1', source: 'test' });\n const state = get(assistantChatStore);\n expect(state.datasetReviewSessionId).toBe('session-99');\n expect(state.focusTarget).toEqual({ target: 'finding:f-1', source: 'test' });\n });\n});\n// #endregion assistantChatStore_tests:Function\n"
},
{
"contract_id": "MockEnvPublic",
@@ -74938,14 +70152,14 @@
{
"source_id": "MigrationMappingsPage",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:EnvSelector.svelte",
- "target_ref": "[EXT:path:EnvSelector.svelte]"
+ "target_id": "EnvSelector",
+ "target_ref": "[EnvSelector]"
},
{
"source_id": "MigrationMappingsPage",
"relation_type": "DEPENDS_ON",
- "target_id": "EXT:path:MappingTable.svelte",
- "target_ref": "[EXT:path:MappingTable.svelte]"
+ "target_id": "MappingTable",
+ "target_ref": "[MappingTable]"
},
{
"source_id": "MigrationMappingsPage",
@@ -74963,7 +70177,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n\n\n\n
\n\n {#if loading}\n
{$t.migration?.loading_envs }
\n {:else}\n
\n { sourceDatabases = []; mappings = []; suggestions = []; }}\n />\n { targetDatabases = []; mappings = []; suggestions = []; }}\n />\n
\n\n
\n \n {$t.migration?.fetch_dbs }\n \n
\n\n {#if error}\n
\n {error}\n
\n {/if}\n\n {#if success}\n
\n {success}\n
\n {/if}\n\n {#if sourceDatabases.length > 0}\n
\n {:else if !fetchingDbs && sourceEnvId && targetEnvId}\n
{$t.migration?.mapping_hint }
\n {/if}\n {/if}\n
\n\n\n\n"
+ "body": "\n\n\n\n\n\n\n\n\n\n
\n\n {#if loading}\n
{$t.migration?.loading_envs }
\n {:else}\n
\n { sourceDatabases = []; mappings = []; suggestions = []; }}\n />\n { targetDatabases = []; mappings = []; suggestions = []; }}\n />\n
\n\n
\n \n {$t.migration?.fetch_dbs }\n \n
\n\n {#if error}\n
\n {error}\n
\n {/if}\n\n {#if success}\n
\n {success}\n
\n {/if}\n\n {#if sourceDatabases.length > 0}\n
\n {:else if !fetchingDbs && sourceEnvId && targetEnvId}\n
{$t.migration?.mapping_hint }
\n {/if}\n {/if}\n
\n\n\n\n"
},
{
"contract_id": "MappingsPageScript:Block",
@@ -75175,14 +70389,14 @@
{
"source_id": "ProfileFixtures:Module",
"relation_type": "DEPENDS_ON",
- "target_id": "frontend/src/lib/i18n/index.ts [key",
- "target_ref": "frontend/src/lib/i18n/index.ts [key:profile.lookup_error]"
+ "target_id": "EXT:path:frontend_i18n_index_key",
+ "target_ref": "[EXT:path:frontend_i18n_index_key]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region ProfileFixtures:Module [TYPE Function]\n// @SEMANTICS: fixtures, profile, ui\n// @PURPOSE: Shared deterministic fixture inputs for profile page integration tests.\n// @INVARIANT: lookupFailedManualFallback.warning is a hardcoded English string; drift risk if i18n key profile.lookup_error changes without updating this fixture.\n// @RELATION BINDS_TO -> [EXT:frontend:ProfilePageBindAccountFlowTests]\n// @RELATION DEPENDS_ON -> [EXT:frontend:i18n.profile.lookup_error]\n// @RELATION DEPENDS_ON -> frontend/src/lib/i18n/index.ts [key:profile.lookup_error]\n\nexport const profileFixtures = {\n bindAccountHappyPath: {\n environmentId: \"dev\",\n candidate: \"j.doe\",\n showOnlyMyDashboards: true,\n },\n lookupFailedManualFallback: {\n environmentId: \"dev\",\n warning:\n \"Cannot load Superset accounts for this environment right now. You can enter username manually.\",\n manualUsername: \"john_doe\",\n },\n invalidUsername: {\n supersetUsername: \"John Doe\",\n showOnlyMyDashboards: true,\n },\n};\n\n// #endregion ProfileFixtures:Module\n"
+ "body": "// #region ProfileFixtures:Module [TYPE Function]\n// @SEMANTICS: fixtures, profile, ui\n// @PURPOSE: Shared deterministic fixture inputs for profile page integration tests.\n// @INVARIANT: lookupFailedManualFallback.warning is a hardcoded English string; drift risk if i18n key profile.lookup_error changes without updating this fixture.\n// @RELATION BINDS_TO -> [EXT:frontend:ProfilePageBindAccountFlowTests]\n// @RELATION DEPENDS_ON -> [EXT:frontend:i18n.profile.lookup_error]\n// @RELATION DEPENDS_ON -> [EXT:path:frontend_i18n_index_key]\n\nexport const profileFixtures = {\n bindAccountHappyPath: {\n environmentId: \"dev\",\n candidate: \"j.doe\",\n showOnlyMyDashboards: true,\n },\n lookupFailedManualFallback: {\n environmentId: \"dev\",\n warning:\n \"Cannot load Superset accounts for this environment right now. You can enter username manually.\",\n manualUsername: \"john_doe\",\n },\n invalidUsername: {\n supersetUsername: \"John Doe\",\n showOnlyMyDashboards: true,\n },\n};\n\n// #endregion ProfileFixtures:Module\n"
},
{
"contract_id": "ProfilePreferencesIntegrationTest",
@@ -75320,14 +70534,14 @@
{
"source_id": "ReportPageContractTest:Module",
"relation_type": "BINDS_TO",
- "target_id": "frontend/src/routes/reports/llm/[taskId]/+page.svelte",
- "target_ref": "frontend/src/routes/reports/llm/[taskId]/+page.svelte"
+ "target_id": "LlmReportPage",
+ "target_ref": "[LlmReportPage]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "// #region ReportPageContractTest:Module [TYPE Function]\n// @SEMANTICS: llm-report, svelte-effect, screenshot-loading, regression-test\n// @PURPOSE: Protect the LLM report page from self-triggering screenshot load effects.\n// @LAYER UI (Tests)\n// @RELATION BINDS_TO -> frontend/src/routes/reports/llm/[taskId]/+page.svelte\n\nimport { describe, it, expect } from \"vitest\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst PAGE_PATH = path.resolve(\n process.cwd(),\n \"src/routes/reports/llm/[taskId]/+page.svelte\",\n);\n\n// #region llm_report_screenshot_effect_contract:Function [TYPE Function]\n// @RELATION USES -> [EXT:frontend:App]\n// @PURPOSE: Ensure screenshot loading stays untracked from blob-url mutation state.\n// @PRE: Report page source exists.\n// @POST: Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.\ndescribe(\"LLM report screenshot effect contract\", () => {\n it(\"uses untrack around screenshot blob loading side effect\", () => {\n const source = fs.readFileSync(PAGE_PATH, \"utf-8\");\n\n expect(source).toContain('import { onDestroy, onMount, untrack } from \"svelte\";');\n expect(source).toContain(\"untrack(() => {\");\n expect(source).toContain(\"void loadScreenshotBlobUrls(paths);\");\n });\n});\n// #endregion llm_report_screenshot_effect_contract:Function\n// #endregion ReportPageContractTest:Module\n"
+ "body": "// #region ReportPageContractTest:Module [TYPE Function]\n// @SEMANTICS: llm-report, svelte-effect, screenshot-loading, regression-test\n// @PURPOSE: Protect the LLM report page from self-triggering screenshot load effects.\n// @LAYER UI (Tests)\n// @RELATION BINDS_TO -> [LlmReportPage]\n\nimport { describe, it, expect } from \"vitest\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst PAGE_PATH = path.resolve(\n process.cwd(),\n \"src/routes/reports/llm/[taskId]/+page.svelte\",\n);\n\n// #region llm_report_screenshot_effect_contract:Function [TYPE Function]\n// @RELATION USES -> [EXT:frontend:App]\n// @PURPOSE: Ensure screenshot loading stays untracked from blob-url mutation state.\n// @PRE: Report page source exists.\n// @POST: Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.\ndescribe(\"LLM report screenshot effect contract\", () => {\n it(\"uses untrack around screenshot blob loading side effect\", () => {\n const source = fs.readFileSync(PAGE_PATH, \"utf-8\");\n\n expect(source).toContain('import { onDestroy, onMount, untrack } from \"svelte\";');\n expect(source).toContain(\"untrack(() => {\");\n expect(source).toContain(\"void loadScreenshotBlobUrls(paths);\");\n });\n});\n// #endregion llm_report_screenshot_effect_contract:Function\n// #endregion ReportPageContractTest:Module\n"
},
{
"contract_id": "llm_report_screenshot_effect_contract:Function",
@@ -76044,26 +71258,26 @@
{
"source_id": "BackupsRedirectPage",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:PageContracts",
- "target_ref": "[EXT:internal:PageContracts]"
+ "target_id": "PageContracts",
+ "target_ref": "[PageContracts]"
},
{
"source_id": "BackupsRedirectPage",
"relation_type": "BINDS_TO",
- "target_id": "EXT:internal:NavigationContracts",
- "target_ref": "[EXT:internal:NavigationContracts]"
+ "target_id": "NavigationContracts",
+ "target_ref": "[NavigationContracts]"
},
{
"source_id": "BackupsRedirectPage",
"relation_type": "CALLS",
- "target_id": "/tools/storage",
- "target_ref": "/tools/storage"
+ "target_id": "ToolsStorage",
+ "target_ref": "[ToolsStorage]"
}
],
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n"
+ "body": "\n\n\n\n\n\n"
},
{
"contract_id": "fetchEnvironments:Function",
@@ -76152,14 +71366,14 @@
{
"source_id": "BackupsPage",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:PageContracts",
- "target_ref": "[EXT:internal:PageContracts]"
+ "target_id": "PageContracts",
+ "target_ref": "[PageContracts]"
},
{
"source_id": "BackupsPage",
"relation_type": "BINDS_TO",
- "target_id": "EXT:internal:NavigationContracts",
- "target_ref": "[EXT:internal:NavigationContracts]"
+ "target_id": "NavigationContracts",
+ "target_ref": "[NavigationContracts]"
},
{
"source_id": "BackupsPage",
@@ -76171,7 +71385,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n\n\n\n\n\n"
+ "body": "\n\n\n\n\n\n\n\n\n\n\n\n"
},
{
"contract_id": "DebugToolPage",
@@ -76203,14 +71417,14 @@
{
"source_id": "DebugToolPage",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:PageContracts",
- "target_ref": "[EXT:internal:PageContracts]"
+ "target_id": "PageContracts",
+ "target_ref": "[PageContracts]"
},
{
"source_id": "DebugToolPage",
"relation_type": "BINDS_TO",
- "target_id": "EXT:internal:NavigationContracts",
- "target_ref": "[EXT:internal:NavigationContracts]"
+ "target_id": "NavigationContracts",
+ "target_ref": "[NavigationContracts]"
},
{
"source_id": "DebugToolPage",
@@ -76228,7 +71442,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n\n"
+ "body": "\n\n\n\n\n\n\n\n"
},
{
"contract_id": "MapperToolPage",
@@ -76260,14 +71474,14 @@
{
"source_id": "MapperToolPage",
"relation_type": "IMPLEMENTS",
- "target_id": "EXT:internal:PageContracts",
- "target_ref": "[EXT:internal:PageContracts]"
+ "target_id": "PageContracts",
+ "target_ref": "[PageContracts]"
},
{
"source_id": "MapperToolPage",
"relation_type": "BINDS_TO",
- "target_id": "EXT:internal:NavigationContracts",
- "target_ref": "[EXT:internal:NavigationContracts]"
+ "target_id": "NavigationContracts",
+ "target_ref": "[NavigationContracts]"
},
{
"source_id": "MapperToolPage",
@@ -76285,7 +71499,7 @@
"schema_warnings": [],
"anchor_syntax": "region",
"tier_source": "AutoCalculated",
- "body": "\n\n\n\n\n\n\n\n"
+ "body": "\n\n\n\n\n\n\n\n"
},
{
"contract_id": "loadFiles:Function",
@@ -78309,6721 +73523,6720 @@
}
],
"file_hashes": {
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape_base.pyi": 5046405609030418900,
- "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/LICENSE": 2032205056284080825,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__init__.py": 5895297076117159245,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py": 10057637461647348368,
- "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.pyi": 11310761736182213265,
- "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_xport.py": 14080914637071212225,
- "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE": 12064892310002036996,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/config.py": 12280996227531856230,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_is_monotonic.py": 12769599198035357753,
- "venv/lib/python3.13/site-packages/yaml/resolver.py": 6669674521776449098,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90": 8079594129222364031,
- "venv/lib/python3.13/site-packages/pygments/lexers/algebra.py": 9651893228421050246,
- "venv/lib/python3.13/site-packages/rapidfuzz/utils.py": 5682627611354455144,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_arithmetic.py": 17427754419626622853,
- "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/INSTALLER": 17282701611721059870,
- "backend/src/models/__tests__/test_clean_release.py": 9937664704633848570,
- "backend/tests/test_logging_audit_fixes.py": 6972807998099938509,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_aarch64_gcc.h": 8140470539757491899,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/shared.py": 1162754506656505196,
- "venv/lib/python3.13/site-packages/pandas/core/computation/parsing.py": 3084943521520476999,
- "venv/lib/python3.13/site-packages/pydantic/main.py": 14086938579850319884,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/_py_collections.py": 16825222625411635946,
- "venv/lib/python3.13/site-packages/pygments/styles/arduino.py": 4578385147314541233,
- "frontend/build/_app/immutable/nodes/4.euBhzXnG.js": 8827989315454731607,
- "venv/lib/python3.13/site-packages/jeepney/bus.py": 5163075760432139100,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_where.py": 3272402211717453881,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked_shared.py": 8453174300922339015,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nlargest_nsmallest.py": 11049656379959696695,
- "frontend/src/routes/datasets/__tests__/inline_edit.test.js": 17712409018171053453,
- "venv/lib/python3.13/site-packages/jsonschema/exceptions.py": 15651767069704734674,
- "venv/lib/python3.13/site-packages/pyasn1/type/tagmap.py": 14075859042659927673,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/egg_link.py": 18211947508793805393,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_serialization.py": 2011519400081029270,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_errstate.py": 10788459171326750780,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_astype.py": 15384141282611151560,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/conftest.py": 3691712173202219606,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/scalars.py": 3468820466230647963,
- "venv/lib/python3.13/site-packages/sqlalchemy/event/__init__.py": 16182540084654095394,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connection.py": 8190661510572400096,
- "venv/lib/python3.13/site-packages/pip/__init__.py": 9449893869469432503,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_timedeltas.py": 4118671843063545221,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/__init__.py": 9106887608906281686,
- "venv/bin/pyrsa-verify": 6762739642629904442,
- "venv/lib/python3.13/site-packages/numpy/core/records.py": 12604652690721760437,
- "venv/lib/python3.13/site-packages/pyasn1/codec/native/__init__.py": 15728752901274520502,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_version.py": 10384171076976071398,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arraymethod.py": 14421188237635557797,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_pickle.py": 3419420815386925630,
- "venv/lib/python3.13/site-packages/rapidfuzz/_utils.py": 14374663810542207121,
- "venv/lib/python3.13/site-packages/numpy/version.py": 1497063540123613501,
- "frontend/src/components/EnvSelector.svelte": 6483243153689240649,
- "venv/lib/python3.13/site-packages/pip/_internal/vcs/subversion.py": 7423946096970870727,
- "frontend/build/_app/immutable/chunks/B02colNV.js": 11184422123417025804,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.pyi": 14233146512272397376,
- "venv/bin/pip3": 13861749540792881808,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/_core.py": 14812112544772987164,
- "venv/lib/python3.13/site-packages/numpy/ma/testutils.py": 9355402483340137461,
- "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/licenses/LICENSE": 12684353321716745791,
- "venv/lib/python3.13/site-packages/numpy/testing/overrides.py": 11819432487830192978,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_numpy.py": 222383250675686477,
- "venv/lib/python3.13/site-packages/pygments/lexers/ride.py": 14096748896451437594,
- "venv/lib/python3.13/site-packages/pandas/tests/io/conftest.py": 5864037534050136837,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_interval.py": 2613503970235591726,
- "frontend/playwright-report/index.html": 16542149899775356791,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_odswriter.py": 17220892094904423676,
- "venv/lib/python3.13/site-packages/apscheduler/__init__.py": 8652514118183227412,
- "venv/lib/python3.13/site-packages/pygments/lexers/wowtoc.py": 17527844575999013592,
- "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.pyi": 9282436354926617898,
- "venv/lib/python3.13/site-packages/keyring/compat/py312.py": 17581691618899404491,
- "venv/lib/python3.13/site-packages/gitdb/utils/encoding.py": 1668793658272579497,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/path_registry.py": 8410829659513707067,
- "frontend/src/lib/stores.js": 8225317698711142177,
- "frontend/build/_app/immutable/chunks/CC_MCBkD.js": 11709343780956289454,
- "backend/tests/services/clean_release/test_demo_mode_isolation.py": 1220295825861350705,
- "backend/alembic/versions/543d43d752b8_migrate_old_dictionary_entries_and_.py": 10988663686444687907,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_arithmetics.py": 16527169124402715210,
- "backend/tests/test_translate_scheduler_execution.py": 16687335504320865378,
- "venv/lib/python3.13/site-packages/starlette/_exception_handler.py": 9892172656847200124,
- "venv/lib/python3.13/site-packages/cryptography/x509/verification.py": 1079694784860492682,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/cache_key.py": 11118819065204404106,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_box_unbox.py": 7579587620530953711,
- "venv/lib/python3.13/site-packages/websockets/server.py": 16599051743322571790,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi": 10784666243744187693,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayprint.py": 13335063050941743734,
- "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_sorting.py": 10523740688498427929,
- "venv/lib/python3.13/site-packages/yaml/representer.py": 10550136298978225013,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_missing.py": 6224750552277937853,
- "venv/lib/python3.13/site-packages/PIL/FliImagePlugin.py": 13364963053197422923,
- "venv/lib/python3.13/site-packages/git/objects/blob.py": 8972374723153211283,
- "venv/lib/python3.13/site-packages/packaging/_tokenizer.py": 7442392076059866359,
- "frontend/src/routes/profile/+page.svelte": 13080303244628934788,
- "backend/src/core/migration/risk_assessor.py": 4161499861941446814,
- "venv/lib/python3.13/site-packages/ecdsa/test_rw_lock.py": 1572802971060634697,
- "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/licenses/LICENSE": 1126906383149772681,
- "backend/src/core/utils/superset_context_extractor/_pii.py": 15135596230141304567,
- "venv/lib/python3.13/site-packages/git/objects/submodule/root.py": 5322248117564025370,
- "backend/tests/services/clean_release/test_approval_service.py": 8273158625698254525,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_round.py": 8336918400205461173,
- "backend/src/models/dataset_review_pkg/_execution_models.py": 13278357366267031549,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_loc.py": 17839380711970027363,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_describe.py": 362374422228593281,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/deprecation.py": 7435269308988385470,
- "venv/lib/python3.13/site-packages/jsonschema/_legacy_keywords.py": 16481666133229715822,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_item_selection.py": 1027989019709029615,
- "venv/lib/python3.13/site-packages/pandas/core/apply.py": 17080038932032802984,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_shift.py": 9952689832827833247,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/strategies.py": 14007486769065345085,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayscalars.h": 16142050006935459679,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/properties.py": 5799883762127872919,
- "venv/lib/python3.13/site-packages/pandas/_libs/ops.pyi": 1192312467209548763,
- "venv/lib/python3.13/site-packages/jose/exceptions.py": 8562012933958941039,
- "venv/lib/python3.13/site-packages/PIL/__init__.py": 10393984345353752724,
- "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/RECORD": 17341460504914308184,
- "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/METADATA": 3044554568188160018,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/ecdsa/_compat.py": 13034064768731879065,
- "venv/lib/python3.13/site-packages/numpy/tests/test_scripts.py": 5790352482583964348,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/kind/foo.f90": 1367964042730902899,
- "venv/lib/python3.13/site-packages/pygments/lexers/apdlexer.py": 14222752852221009085,
- "venv/lib/python3.13/site-packages/pygments/lexers/supercollider.py": 15306357945850389082,
- "frontend/src/routes/datasets/ColumnsTable.svelte": 14113713230812728863,
- "venv/lib/python3.13/site-packages/_pytest/subtests.py": 14573790885130724739,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_promote.py": 16601872688404846307,
- "venv/lib/python3.13/site-packages/pydantic/functional_serializers.py": 15285359935059345032,
- "frontend/src/routes/login/+page.svelte": 2655837067927461296,
- "frontend/build/_app/immutable/nodes/18.X9qqmMrM.js": 10317790872480568902,
- "backend/src/plugins/git/__init__.py": 2144831474780401625,
- "venv/lib/python3.13/site-packages/attrs/validators.py": 10346563361083429998,
- "backend/tests/core/test_migration_engine.py": 11015960127863747154,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/jws.py": 7505219131537941130,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_numpy.py": 9825804096508014886,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reset_index.py": 14490875921264161445,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_compat.py": 4677414058216516380,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/install/editable_legacy.py": 8145740626773638218,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/accesstype.f90": 877982462186396830,
- "venv/lib/python3.13/site-packages/passlib/handlers/misc.py": 18255658377109333797,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_concat.py": 10207975532842927134,
- "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL": 5990830714395966792,
- "frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte": 2835359394064716026,
- "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.py": 1731362089136926666,
- "venv/lib/python3.13/site-packages/fastapi/cli.py": 13972351579061154035,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_ufunc.py": 3326502989311831856,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_index.py": 13517883160584591966,
- "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/METADATA": 3814104793342833872,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/RECORD": 12555714734722889695,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi": 16048852379621461316,
- "venv/lib/python3.13/site-packages/PIL/FpxImagePlugin.py": 18245056799205041866,
- "backend/src/services/reports/__tests__/test_type_profiles.py": 8045459741015920365,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/completion.py": 4435231315212798769,
- "venv/lib/python3.13/site-packages/attr/__init__.py": 14436902698244718082,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_map.py": 1115471561925426082,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/json/test_json.py": 12422315190455428620,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_read.py": 8825002468745406134,
- "backend/git_repos/remote/test-repo.git/HEAD": 12394318939628232491,
- "venv/lib/python3.13/site-packages/starlette/staticfiles.py": 11256974306202558529,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_indexing.py": 16264430536704066847,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_dialect.py": 4700488504252803159,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape.pyi": 2188930129299348535,
- "venv/bin/activate": 14735074000123383125,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_convert.py": 13349243029437881949,
- "venv/lib/python3.13/site-packages/fastapi/openapi/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/git/util.py": 7424113599506269603,
- "backend/tests/core/test_git_service_gitea_pr.py": 18003501172717000629,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_xlsxwriter.py": 16873939324418752965,
- "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/METADATA": 3474626408138844944,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_compat.py": 6032546839876195115,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_getlimits.py": 118041882543413669,
- "backend/src/api/routes/dashboards/_projection.py": 9178951020532547334,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_shape_base.py": 4117141349022217163,
- "scripts/gen_semantics.py": 11397714264377363083,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_file_buffer_url.py": 15377043158761455858,
- "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/WHEEL": 16097436423493754389,
- "backend/tests/test_auth.py": 18059959539697963472,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/signals.py": 10390443713463805090,
- "venv/lib/python3.13/site-packages/numpy/lib/_iotools.py": 10522826373041592861,
- "venv/lib/python3.13/site-packages/sqlalchemy/py.typed": 15130871412783076140,
- "frontend/src/components/tasks/LogFilterBar.svelte": 1342324464094667837,
- "venv/lib/python3.13/site-packages/numpy/linalg/__init__.pyi": 18409133021422984774,
- "venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py": 932468678264370661,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_frozen.py": 3484963987053884566,
- "frontend/build/_app/immutable/nodes/9.C5HoT9pt.js": 3952586507302745635,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/array.py": 12658302948819867972,
- "venv/lib/python3.13/site-packages/pandas/_libs/_cyutility.cpython-313-x86_64-linux-gnu.so": 3372660143512868174,
- "backend/src/plugins/translate/dictionary_crud.py": 17858252266960667195,
- "backend/src/services/reports/report_service.py": 9387534669439738529,
- "venv/lib/python3.13/site-packages/urllib3/util/ssltransport.py": 1175688460659745788,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_multiindex.py": 13723677252432338937,
- "venv/lib/python3.13/site-packages/PIL/_imagingcms.cpython-313-x86_64-linux-gnu.so": 15198265718775753589,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/char.pyi": 1639810799219814643,
- "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/keyring/compat/properties.py": 1562771115138037410,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_linux.h": 4071314837793906998,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_pairwise.py": 2673370322448160842,
- "venv/lib/python3.13/site-packages/fastapi/websockets.py": 9910052969532075719,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata.py": 2021612995853910808,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py": 5946672289916692272,
- "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.pyi": 1521384724035973688,
- "venv/lib/python3.13/site-packages/jose/jwk.py": 2781217726458801910,
- "venv/lib/python3.13/site-packages/cryptography/x509/general_name.py": 4481582226129488535,
- "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_transpose.py": 17983160984979323393,
- "venv/lib/python3.13/site-packages/git/index/__init__.py": 7874728461616959441,
- "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/WHEEL": 7454950858448014158,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/value_attrspec/gh21665.f90": 11945588837236968550,
- "venv/lib/python3.13/site-packages/httpcore/_backends/sync.py": 576247220834179928,
- "venv/lib/python3.13/site-packages/itsdangerous/__init__.py": 6969210114978365656,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/__init__.py": 5060190599837877599,
- "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_timedelta.py": 364160935264757405,
- "venv/lib/python3.13/site-packages/PIL/ImageTransform.py": 7825940907094338808,
- "venv/lib/python3.13/site-packages/git/repo/__init__.py": 6173604284490891047,
- "venv/lib/python3.13/site-packages/numpy/matlib.py": 112839038090033740,
- "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/fift.py": 7537570342576781911,
- "frontend/src/routes/+page.ts": 11160596731849880920,
- "backend/src/api/routes/assistant/_history.py": 6387339416391099341,
- "backend/src/services/clean_release/__tests__/test_stages.py": 15550789367780507193,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/align.py": 6078666505647454830,
- "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_config/__init__.py": 3577026529387563519,
- "backend/src/models/task.py": 13936135007931808732,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/spinners.py": 7664056305019151182,
- "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth1_client.py": 3129955464287331242,
- "venv/bin/Activate.ps1": 1196103427939049710,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_neighborhood_iterator_imp.h": 10634781863364525895,
- "venv/lib/python3.13/site-packages/jaraco/classes/ancestry.py": 11742194518360056470,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.pyi": 16976386782787920450,
- "frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js": 7546622841909210622,
- "venv/lib/python3.13/site-packages/git/index/util.py": 5022401275553420722,
- "backend/src/core/utils/async_network.py": 7880952036357722891,
- "venv/lib/python3.13/site-packages/pandas/_version.py": 3480474785419232091,
- "venv/lib/python3.13/site-packages/rapidfuzz/process.pyi": 6959881293311340830,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.pyf": 1361426175133186231,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/__init__.py": 9482393721453335937,
- "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/httpx/_transports/base.py": 6498990531443644896,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/base.py": 13269563625127294513,
- "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_impl.py": 16610770935842519289,
- "frontend/src/lib/ui/index.ts": 6883965364006817450,
- "frontend/src/lib/components/layout/TopNavbar.svelte": 16154704878262712977,
- "backend/src/api/routes/maintenance/_routes.py": 1806945539081275218,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/inout.f90": 1521999519583206538,
- "venv/lib/python3.13/site-packages/pandas/util/_validators.py": 10201915528715968165,
- "venv/lib/python3.13/site-packages/pandas/tests/construction/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/METADATA": 10241403930811743893,
- "frontend/src/lib/stores/translationRun.js": 10005138082029605368,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_elffile.py": 5728213398707817049,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ufuncobject.h": 5112456258078662871,
- "venv/lib/python3.13/site-packages/pygments/lexers/markup.py": 10311057264960923433,
- "backend/src/plugins/translate/preview_executor.py": 11680052270975606699,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_quoted_character.py": 2316632434571797367,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_unittests.py": 18157503533859249155,
- "venv/lib/python3.13/site-packages/numpy/tests/test_reloading.py": 17532116685329953400,
- "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/INSTALLER": 17282701611721059870,
- "frontend/build/_app/env.js": 8815854342083926790,
- "venv/lib/python3.13/site-packages/pandas/_libs/arrays.pyi": 12629806207276576877,
- "venv/lib/python3.13/site-packages/more_itertools/recipes.pyi": 16788810745659802820,
- "venv/lib/python3.13/site-packages/httpx/_main.py": 1812303705973265093,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_half.py": 3121836756584726126,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/conftest.py": 25473177671450048,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/fromnumeric.pyi": 6708743411405679061,
- "venv/lib/python3.13/site-packages/attrs/setters.py": 5775359015245600592,
- "venv/lib/python3.13/site-packages/starlette/authentication.py": 10905269573809129547,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/__init__.py": 3247870839323520754,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/use_modules.f90": 3913612933340746297,
- "venv/lib/python3.13/site-packages/pandas/core/sample.py": 11913688303879867963,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_to_offset.py": 3929599794655343911,
- "venv/lib/python3.13/site-packages/attr/_version_info.pyi": 7141309436445210354,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_get_dummies.py": 14871264482622327003,
- "frontend/src/lib/components/assistant/AssistantChatPanel.svelte": 17490466635940795553,
- "frontend/src/components/git/ConflictResolver.svelte": 12314421232300049275,
- "backend/tests/scripts/test_clean_release_tui_v2.py": 5872535102885848729,
- "venv/lib/python3.13/site-packages/_pytest/assertion/util.py": 16957445183087315124,
- "backend/git_repos/remote/test-repo.git/objects/a1/3525f5f44e26d8fbec3226bd488d14793575a2": 3742572048019652365,
- "venv/lib/python3.13/site-packages/more_itertools/recipes.py": 5254043689078173976,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/parameters.py": 5104015814292812973,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isin.py": 8136794647591341784,
- "venv/lib/python3.13/site-packages/attr/setters.pyi": 6670509359139243236,
- "venv/lib/python3.13/site-packages/pygments/lexers/sql.py": 15566262873151658034,
- "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.cpython-313-x86_64-linux-gnu.so": 13917011878259810696,
- "venv/lib/python3.13/site-packages/httpx/_urlparse.py": 8270294590945652412,
- "venv/lib/python3.13/site-packages/pip/_internal/index/__init__.py": 14829074315307489628,
- "venv/lib/python3.13/site-packages/numpy/lib/user_array.py": 14003456655595459585,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/isocintrin/isoCtests.f90": 6208802899442270399,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/__init__.py": 2436195108273216959,
- "frontend/build/_app/immutable/entry/start.BNyxZqQe.js": 14066366168579688400,
- "frontend/build/_app/immutable/chunks/1jzJINoE.js": 5138497638450462989,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_defchararray.py": 15135904718007443306,
- "venv/lib/python3.13/site-packages/pygments/lexers/ml.py": 7510453371068494792,
- "venv/lib/python3.13/site-packages/itsdangerous/serializer.py": 14271229091461164933,
- "venv/lib/python3.13/site-packages/urllib3/_base_connection.py": 14495079097019980154,
- "venv/lib/python3.13/site-packages/pandas/io/clipboards.py": 5183212433608887727,
- "frontend/e2e/fixtures/global-setup.js": 16032945890934324203,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_masked_matrix.py": 1444179242134203344,
- "backend/test_auth.db": 18214842050920965999,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimes.py": 14331984919364185787,
- "scripts/build_offline_docker_bundle.sh": 1393881756263325163,
- "venv/lib/python3.13/site-packages/pygments/lexers/jsonnet.py": 1314044008440065525,
- "frontend/src/lib/components/reports/ReportsList.svelte": 17367781544989044334,
- "venv/lib/python3.13/site-packages/git/objects/submodule/base.py": 10140490301897269395,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/compat.py": 5871636909854554063,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/styles/murphy.py": 8177992406082781615,
- "venv/lib/python3.13/site-packages/pygments/lexers/esoteric.py": 16839499623020685146,
- "backend/alembic/versions/2a7b8c9d0e1f_add_target_languages_to_translation_jobs.py": 7201017059554918882,
- "backend/src/plugins/translate/__tests__/test_dictionary_correction.py": 17508858180216288123,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py": 2609365889369107154,
- "venv/lib/python3.13/site-packages/PIL/PpmImagePlugin.py": 7107324729714470853,
- "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/RECORD": 16342326945648353387,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexing.py": 9988098331562906950,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/py.typed": 9796674040111366709,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapper.py": 16715864918034312591,
- "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/INSTALLER": 17282701611721059870,
- "frontend/playwright-report/trace/index.html": 6654608714409350530,
- "venv/lib/python3.13/site-packages/passlib/handlers/cisco.py": 15004707325761459775,
- "venv/lib/python3.13/site-packages/PIL/ImageMorph.py": 13861961228125789866,
- "venv/lib/python3.13/site-packages/more_itertools/__init__.pyi": 16479506520351014608,
- "venv/lib/python3.13/site-packages/smmap/test/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/gitdb/test/__init__.py": 18393574323937353933,
- "venv/lib/python3.13/site-packages/more_itertools/more.py": 1631135582441184133,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/sum_.py": 7062070517544958546,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi": 16312114056447366970,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_timedeltaindex.py": 2359681317403710563,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_formats.py": 17821648708413143557,
- "venv/lib/python3.13/site-packages/pandas/_libs/lib.pyi": 3049004444338566197,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_indexing.py": 4063662953863959087,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_highlight.py": 7573043358244876807,
- "venv/lib/python3.13/site-packages/passlib/ifc.py": 14479133654556657428,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_antijoin.py": 14435396877404907826,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/datonly.f90": 10495925225338237742,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/sqltypes.py": 2952996080192295188,
- "venv/lib/python3.13/site-packages/numpy/tests/test_warnings.py": 3154249157134620649,
- "venv/lib/python3.13/site-packages/idna/core.py": 7725813731640753267,
- "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/WHEEL": 7454950858448014158,
- "venv/lib/python3.13/site-packages/psycopg2/_psycopg.cpython-313-x86_64-linux-gnu.so": 13471342289207537479,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90": 7957683453180939605,
- "venv/lib/python3.13/site-packages/pydantic/v1/mypy.py": 17076910404409672245,
- "venv/lib/python3.13/site-packages/numpy/core/_dtype.pyi": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_records.py": 12217508428903265797,
- "venv/lib/python3.13/site-packages/anyio/_core/_typedattr.py": 17584691045493791349,
- "venv/lib/python3.13/site-packages/pandas/core/common.py": 14578909424716153057,
- "venv/lib/python3.13/site-packages/greenlet/greenlet.cpp": 3281107194043468270,
- "venv/lib/python3.13/site-packages/pandas/tests/libs/test_lib.py": 6721066015604956469,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_type_check.py": 3935091606923106753,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_numpy_compat.py": 9112925138440787555,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/models.py": 16636119441941357281,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_indexing.py": 14717641281147152159,
- "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.py": 12771179468704314203,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_sort.py": 11941630642630249576,
- "venv/lib/python3.13/site-packages/pandas/io/sas/sas_constants.py": 14492427939536692313,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_add_prefix_suffix.py": 8367793476246001244,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_hist_method.py": 2109257663592928,
- "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.pyi": 1826323011169529229,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_indexing.py": 8943385096811168079,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_csv.py": 6678500392137188521,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_base.py": 8678387511873412922,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/_typing.py": 10524021526716767489,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_nonunique_indexes.py": 15468078561381939405,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayobject.h": 4345432890284821918,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/base.py": 7110726987481713080,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_pickle.py": 388513670243918273,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_get_dummies.py": 16112674981222844375,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets2.py": 11100501798741918610,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertsql.py": 4633484475514351889,
- "venv/lib/python3.13/site-packages/charset_normalizer/md.py": 2029760700380476138,
- "venv/lib/python3.13/site-packages/authlib/oauth1/errors.py": 1154126353335030046,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_records.py": 6252761812228230408,
- "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/METADATA": 7214286447912789067,
- "venv/lib/python3.13/site-packages/pandas/core/computation/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/linalg/__init__.py": 15647756307608142577,
- "venv/lib/python3.13/site-packages/pygments/lexers/freefem.py": 9851243865301700231,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_generate_schema.py": 7343380095251236503,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/infer.py": 12541904372617915365,
- "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/connection.py": 15405047955974108860,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_frame.py": 9378623452601244234,
- "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/licenses/LICENSE": 3868190977070717994,
- "venv/lib/python3.13/site-packages/pygments/lexers/lisp.py": 11872331622183590758,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arithmetic.pyi": 467927803068643024,
- "venv/lib/python3.13/site-packages/h11/_readers.py": 832030916375670301,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_format.py": 16150524965028369071,
- "frontend/src/lib/api.js": 7712788935523484149,
- "frontend/src/lib/components/ui/SearchableMultiSelect.svelte": 1872229619122554196,
- "venv/lib/python3.13/site-packages/cryptography/x509/certificate_transparency.py": 11337143186866439208,
- "venv/lib/python3.13/site-packages/requests/__init__.py": 2604491098990438229,
- "venv/bin/activate.csh": 14513616043256836238,
- "frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte": 13452471817010485891,
- "frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js": 5677983810932562795,
- "frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js": 7606382627471479368,
- "backend/src/plugins/translate/__tests__/test_token_budget.py": 2275341408164077909,
- "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/RECORD": 9964194961227523130,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/index.py": 16715578868094112894,
- "venv/lib/python3.13/site-packages/authlib/oidc/registration/claims.py": 4161520263207458028,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_openssl.py": 10446441599800965961,
- "venv/lib/python3.13/site-packages/_pytest/timing.py": 14080119171718125986,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_extending.py": 10202091354750153497,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/replace.py": 1708865864686705833,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_series.py": 17126297747681689408,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqldb.py": 2138006249556140141,
- "venv/lib/python3.13/site-packages/click/testing.py": 15973659312284678327,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/dml.py": 6567627855667533645,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_impl.py": 15673691977157706075,
- "venv/lib/python3.13/site-packages/pygments/lexers/elm.py": 14683437310498104916,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/__init__.py": 5732822354953774657,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/windows.py": 16452996247375488034,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/sqlalchemy.py": 811968833735951956,
- "venv/lib/python3.13/site-packages/requests/models.py": 9104898985870652256,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/buffer.py": 12961802206383700922,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.cpython-313-x86_64-linux-gnu.so": 12776951671822017500,
- "venv/lib/python3.13/site-packages/pygments/lexers/x10.py": 6167378515780115912,
- "frontend/src/components/RepositoryDashboardGrid.svelte": 8427306073875543545,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py": 6109201994963211857,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/__init__.py": 14268033439436797364,
- "venv/lib/python3.13/site-packages/pygments/lexers/apl.py": 16767474673619335683,
- "venv/lib/python3.13/site-packages/bcrypt/__init__.py": 11415155211917181362,
- "venv/lib/python3.13/site-packages/pyasn1/type/univ.py": 7163437624197683039,
- "venv/lib/python3.13/site-packages/h11/_events.py": 13800479928851716538,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cosh.csv": 9287774220881887502,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_timedelta.py": 12822713918114715561,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_utils.py": 15197339054699289627,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimes.py": 10585034798097337148,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__init__.py": 8880435562116660648,
- "venv/lib/python3.13/site-packages/git/objects/tag.py": 7954808535585493300,
- "venv/lib/python3.13/site-packages/git/index/base.py": 641556304637379636,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pop.py": 5700439923973346681,
- "venv/lib/python3.13/site-packages/httpx/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/cffi/_cffi_errors.h": 1479575326813300292,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90": 7589258200398878529,
- "venv/lib/python3.13/site-packages/_pytest/pytester.py": 5423287282155948827,
- "venv/lib/python3.13/site-packages/numpy/__init__.py": 2331213407497901634,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_indexing.py": 6039808271042864401,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_kurt.py": 2898715045429898166,
- "venv/lib/python3.13/site-packages/pygments/lexers/solidity.py": 5071425960622305629,
- "venv/lib/python3.13/site-packages/pip/_internal/network/utils.py": 13421242949994555055,
- "venv/lib/python3.13/site-packages/gitdb/utils/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/_pytest/stepwise.py": 3527630676691417317,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_complex.py": 4290059580478881700,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.pyi": 13083543811193933305,
- "frontend/src/services/__tests__/gitService.test.js": 2011135397906862721,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2py2e.py": 8571347023940385644,
- "backend/src/plugins/__init__.py": 17194112070692432889,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/errors.py": 16711622442922413520,
- "venv/lib/python3.13/site-packages/gitdb/db/pack.py": 13460574575424209609,
- "backend/src/plugins/translate/_llm_http.py": 15686826696693103176,
- "backend/git_repos/remote/test-repo.git/objects/48/c3fde4d5fff5bf98e9bcaa5f328b199aa18292": 6121250272621110311,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_libgroupby.py": 9985769511561272200,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_counting.py": 5628494712451120258,
- "venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py": 1532245423878428608,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/url.py": 1558176735588971829,
- "venv/lib/python3.13/site-packages/jeepney/bus_messages.py": 5871341372541525842,
- "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/__init__.py": 9820770319106921495,
- "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.cpython-313-x86_64-linux-gnu.so": 17652852308919396403,
- "venv/lib/python3.13/site-packages/pygments/lexers/rego.py": 16022844238903541738,
- "frontend/public/vite.svg": 13568221685541582385,
- "backend/src/plugins/translate/preview_session_ops.py": 2497494071534748391,
- "backend/git_repos/remote/test-repo.git/objects/22/c0ea49cea7e5138fb91b25b1bc0e101ae6e017": 17630871400599334193,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_is_full.py": 9577318758326279694,
- "venv/lib/python3.13/site-packages/numpy/lib/_version.pyi": 10804755840730584157,
- "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/assertion_session.py": 18109848200936213195,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hashes.py": 8545380307201732345,
- "venv/lib/python3.13/site-packages/passlib/utils/handlers.py": 10182859005870689026,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_validate_call.py": 4078236486720616395,
- "venv/lib/python3.13/site-packages/click/_utils.py": 16491408631876616271,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_analytics.py": 8155550493311083506,
- "venv/lib/python3.13/site-packages/pandas/core/computation/expr.py": 13085709365673019494,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_non_unique.py": 15286893322149413712,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/http/h11_impl.py": 1419719055394402145,
- "venv/lib/python3.13/site-packages/pygments/lexers/elpi.py": 5736689911777977822,
- "frontend/build/_app/immutable/nodes/32.Cmesu1rv.js": 1679171227981656667,
- "venv/lib/python3.13/site-packages/pycparser/ast_transforms.py": 9032453625977464506,
- "frontend/build/_app/immutable/chunks/BVk3Uk_6.js": 15316567731933897520,
- "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/device_code.py": 6712610002227849281,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/memmap.pyi": 15629663272474054909,
- "venv/lib/python3.13/site-packages/pygments/styles/coffee.py": 17584414468786822371,
- "venv/lib/python3.13/site-packages/numpy/core/function_base.py": 12696640832638144604,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_clip.py": 13498704233745189154,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.h": 16138871162713175599,
- "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/pandas/_libs/index.pyi": 17679349633640606985,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/io/sas/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/fastapi/requests.py": 14587947416691824903,
- "venv/lib/python3.13/site-packages/ecdsa/_sha3.py": 10353612776869489378,
- "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/__init__.py": 17630019785411546070,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_arithmetic.py": 11620920548943067949,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_deprecations.py": 16124509063246256847,
- "venv/lib/python3.13/site-packages/pygments/lexers/maple.py": 7402467573829618534,
- "venv/lib/python3.13/site-packages/pandas/core/internals/ops.py": 4740509262379451243,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/compat.py": 1841193561752758336,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_assumed_shape.py": 18361009188431483164,
- "venv/lib/python3.13/site-packages/pygments/lexers/kusto.py": 16285533608924436308,
- "venv/lib/python3.13/site-packages/pygments/cmdline.py": 15628499088643246809,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_indexing.py": 6539365174681852769,
- "venv/lib/python3.13/site-packages/pygments/lexers/dylan.py": 16246299896150112270,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/scripts.py": 8759605303886441976,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_pickle.py": 8705060420848529055,
- "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_expanding.py": 12504275097476819918,
- "venv/lib/python3.13/site-packages/keyring/testing/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarbuffer.py": 16859789411010045795,
- "venv/lib/python3.13/site-packages/pandas/_config/localization.py": 11197430792343731762,
- "venv/lib/python3.13/site-packages/anyio/_core/_streams.py": 6436461519284884601,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/unitofwork.py": 3177255974394221645,
- "frontend/src/lib/stores/__tests__/taskDrawer.test.js": 9115135514077743547,
- "venv/lib/python3.13/site-packages/pip/_internal/build_env.py": 3614358934066127900,
- "venv/lib/python3.13/site-packages/pandas/compat/numpy/function.py": 18405870240333383757,
- "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/INSTALLER": 17282701611721059870,
- "frontend/build/_app/immutable/chunks/DA0oX2nF.js": 4762485859359244720,
- "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/LICENSE": 11167201188673981085,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_random.py": 4179188367630060654,
- "venv/lib/python3.13/site-packages/httpcore/__init__.py": 5897259569277532401,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npz": 12369168483236619421,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_index_col.py": 17604191644943383567,
- "venv/lib/python3.13/site-packages/starlette/formparsers.py": 9019779181100355515,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/asyncio.py": 2517623574187179319,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_show_versions.py": 10577134135855180356,
- "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector.py": 15458248567257759500,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/dictionary.py": 9599439750713575741,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/__init__.py": 2397613800206300456,
- "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/RECORD": 9974324769263969827,
- "venv/lib/python3.13/site-packages/anyio/streams/file.py": 15232345967545920863,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_np_datetime.py": 18363183516409621205,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_unary.py": 7128845965976836334,
- "frontend/playwright-report/trace/uiMode.C2Efnu2P.js": 2717171022864487300,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_jsonschema_test_suite.py": 12733761462141495972,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_recfunctions.py": 16014503284544747867,
- "venv/lib/python3.13/site-packages/pyasn1/compat/integer.py": 7365270971777550573,
- "venv/lib/python3.13/site-packages/numpy/_array_api_info.pyi": 13283968924732680159,
- "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/METADATA": 11557342107649194148,
- "venv/lib/python3.13/site-packages/numpy/f2py/rules.py": 9322914583460630877,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_operators.py": 12686786829906210592,
- "venv/lib/python3.13/site-packages/yaml/reader.py": 9873075843010693205,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/claims.py": 11853156183819186599,
- "venv/lib/python3.13/site-packages/pygments/lexers/gdscript.py": 12775803139854052838,
- "backend/src/api/routes/__tests__/test_migration_routes.py": 487639430753650879,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_api.py": 5287018911951723034,
- "frontend/src/components/git/DeploymentModal.svelte": 3761818357348583741,
- "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/RECORD": 7320381591791379627,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_leaks.py": 1219835696230215605,
- "venv/lib/python3.13/site-packages/pydantic/fields.py": 4142211199816898047,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_openid.py": 8708980645667847439,
- "venv/bin/pyrsa-sign": 15564653706771700451,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/cmdoptions.py": 12107733000019393631,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraysetops.pyi": 1782641795267171928,
- "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/METADATA": 1266134223155266488,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/style.py": 15214295655795348821,
- "venv/lib/python3.13/site-packages/pygments/lexers/praat.py": 54226477748516386,
- "venv/lib/python3.13/site-packages/pygments/lexers/tablegen.py": 2917626373516779857,
- "frontend/build/_app/immutable/nodes/6.DJ9MrKC-.js": 8967503365556189617,
- "venv/lib/python3.13/site-packages/pandas/plotting/__init__.py": 13230487326686617492,
- "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/METADATA": 6502714564886871819,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/codec.py": 14814999235499530522,
- "venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py": 10265081145401348863,
- "venv/lib/python3.13/site-packages/pandas/tests/computation/test_eval.py": 2921337784087808487,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/__init__.py": 15130871412783076140,
- "frontend/build/_app/immutable/chunks/DsnmJJEf.js": 17416107759626312632,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-1.csv": 5708101386018266998,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_kwargs.py": 10173906126211473463,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numerictypes.pyi": 15443101937711720707,
- "frontend/src/routes/datasets/__tests__/split_view.test.js": 6143972529940917004,
- "backend/tests/services/clean_release/test_policy_resolution_service.py": 684362936473488668,
- "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.py": 7365943844063702766,
- "backend/src/core/__tests__/test_superset_preview_pipeline.py": 13996819877413389729,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_sparse_accessor.py": 6774374030220202353,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ext.py": 8361831054662096695,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/list/__init__.py": 10072943986583771248,
- "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pygments/lexers/haskell.py": 8011341851439354724,
- "venv/lib/python3.13/site-packages/h11/py.typed": 12358286306858197118,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs12.pyi": 7801211423226951223,
- "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.pyi": 7410507092040239447,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hi77.f": 10617763407280454334,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_formats.py": 9738552308554950419,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/securetransport.py": 12104888897121018676,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pyi": 14150710436003340771,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/token_endpoint.py": 6118770923176099889,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_slp_switch.hpp": 1694714764745718414,
- "venv/lib/python3.13/site-packages/pandas/_libs/properties.pyi": 9268470215750269699,
- "venv/lib/python3.13/site-packages/httpx/_transports/__init__.py": 5931944625631942279,
- "venv/lib/python3.13/site-packages/pandas/core/ops/__init__.py": 4049432353810047365,
- "venv/lib/python3.13/site-packages/numpy/tests/test__all__.py": 10689265249302359388,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_groupby_shift_diff.py": 1210657479716368827,
- "frontend/build/_app/immutable/nodes/40.CNZCEv_K.js": 15374574306536825164,
- "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/WHEEL": 9788895026336324100,
- "venv/lib/python3.13/site-packages/attr/filters.py": 14156141488477438777,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_index_as_string.py": 292438690259156869,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arrow_compat.py": 12986187285988432338,
- "venv/lib/python3.13/site-packages/_pytest/recwarn.py": 15312759837838083596,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/validator_creation.py": 2745563768861102999,
- "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.pyi": 8879196542984811747,
- "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.pyi": 14181518821845356636,
- "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_slice.py": 9936085512921529417,
- "backend/src/api/routes/dashboards/_helpers.py": 13624740316332136004,
- "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/RECORD": 15194367076254806710,
- "models": 14346352665111990852,
- "venv/lib/python3.13/site-packages/jeepney/io/threading.py": 525625939662612746,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_classes.py": 1440926036579216168,
- "frontend/src/lib/components/translate/CorrectionCell.svelte": 17398304999652244378,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_s390_unix.h": 5161826643658505126,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polyutils.py": 675639791972685455,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_common.py": 9446944526144164255,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo77.f": 7353666717928699883,
- "venv/lib/python3.13/site-packages/numpy/linalg/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/recarray_from_file.fits": 15116318600514274152,
- "venv/lib/python3.13/site-packages/numpy/_typing/_extended_precision.py": 4201820494689784136,
- "venv/lib/python3.13/site-packages/pandas/plotting/_misc.py": 10202078355301731720,
- "venv/lib/python3.13/site-packages/pyasn1/compat/__init__.py": 5902203086150636670,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/types.py": 1343652083039949282,
- "venv/lib/python3.13/site-packages/passlib/hosts.py": 11171402820797380938,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sinh.csv": 12358602501260667480,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/_arrow_utils.py": 17808805047762566525,
- "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.pyi": 18395688193449688360,
- "venv/lib/python3.13/site-packages/apscheduler/executors/twisted.py": 2695602672085615762,
- "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.py": 3001896031623204147,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/python3.npy": 4957143805477405905,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/version.py": 14723293207188512766,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_asfreq.py": 12721047184483392773,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_nat.py": 18428782698385974380,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_convert.py": 77283525137564255,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/region.py": 12579403230062395563,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_arithmetic.py": 15071337112968886738,
- "venv/lib/python3.13/site-packages/numpy/ma/extras.pyi": 15292036493781556342,
- "venv/lib/python3.13/site-packages/yaml/error.py": 5626374410579058436,
- "venv/lib/python3.13/site-packages/numpy/_distributor_init.pyi": 1308368231471324581,
- "venv/lib/python3.13/site-packages/pygments/regexopt.py": 16073437303824961930,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/specifiers.py": 12284901056355482991,
- "run_clean_tui.sh": 14305120550349644601,
- "venv/lib/python3.13/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz": 17626265752554406355,
- "frontend/src/lib/stores/__tests__/test_sidebar.js": 2607679830387722396,
- "backend/src/api/routes/__tests__/test_datasets.py": 5175841745704208723,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/strings.pyi": 15361498560917514616,
- "backend/tests/test_api_key_routes.py": 8620555141760963281,
- "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/RECORD": 1051307407005554409,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi": 9294219058621261971,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/toml.py": 2225382735669153136,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/stride_tricks.pyi": 8257977532799807847,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending_distributions.pyx": 15302775787158991386,
- "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/_core/printoptions.pyi": 16758392990920041462,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/__init__.py": 5118993772178969104,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo.f": 5690596225005490325,
- "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.pyi": 8607205990821121708,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/inference.py": 2786441797589123900,
- "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_stat_reductions.py": 11569525436540769152,
- "venv/lib/python3.13/site-packages/dateutil/relativedelta.py": 5903095963079475484,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/type_check.pyi": 1599910480066368464,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/__init__.py": 1948986914452928735,
- "frontend/build/_app/immutable/chunks/Cr-9eaXZ.js": 55845366387923127,
- "venv/lib/python3.13/site-packages/PIL/AvifImagePlugin.py": 1872412416505003364,
- "backend/src/api/routes/reports.py": 11259252279199691691,
- "venv/lib/python3.13/site-packages/numpy/_core/defchararray.py": 15550230459945996915,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_datetimelike.py": 10294379314868108649,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_dtypes.py": 6831042272921908068,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/__init__.py": 7062045842767697645,
- "venv/lib/python3.13/site-packages/websockets/legacy/server.py": 5390090919193784186,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_factorize.py": 861897342553280506,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sample.py": 16877779557071324115,
- "venv/lib/python3.13/site-packages/PIL/ImageCms.py": 5610897002957128546,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/__init__.py": 12793458753561114666,
- "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.py": 11393954913234866059,
- "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django.py": 3210697476292094384,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/gevent.py": 4811840397266785551,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/tornado.py": 6491136785917169991,
- "venv/lib/python3.13/site-packages/numpy/lib/user_array.pyi": 1968484998382771986,
- "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_builtin.py": 74545289993348593,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_hour.py": 13754646634123368797,
- "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD": 16740224557818847141,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/base_command.py": 10660882478126415399,
- "venv/lib/python3.13/site-packages/websockets/http11.py": 11022534176398053082,
- "venv/lib/python3.13/site-packages/pandas/_libs/indexing.cpython-313-x86_64-linux-gnu.so": 13188040757764159731,
- "venv/lib/python3.13/site-packages/pygments/lexers/kuin.py": 2818054539831699366,
- "venv/lib/python3.13/site-packages/pygments/lexers/csound.py": 2175454840368374515,
- "venv/lib/python3.13/site-packages/_pytest/legacypath.py": 7512065138259788426,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_ticks.py": 11649965080303468085,
- "venv/lib/python3.13/site-packages/packaging/licenses/__init__.py": 15879493360260891293,
- "venv/lib/python3.13/site-packages/_pytest/outcomes.py": 12782895027812738142,
- "venv/lib/python3.13/site-packages/pyasn1/codec/cer/encoder.py": 3261739474564948330,
- "frontend/src/components/TaskList.svelte": 17511781335293490363,
- "backend/src/models/filter_state.py": 9299838116029912439,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_reindex.py": 15680924058960901067,
- "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.py": 5583478355093966990,
- "venv/lib/python3.13/site-packages/numpy/strings/__init__.py": 6523674574341354095,
- "venv/lib/python3.13/site-packages/passlib/handlers/argon2.py": 835074952952017434,
- "venv/lib/python3.13/site-packages/pygments/lexers/c_cpp.py": 1211842877043321095,
- "venv/lib/python3.13/site-packages/requests/help.py": 1885413874621672882,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_markdown.py": 9964642152916165317,
- "venv/lib/python3.13/site-packages/pandas/_libs/sas.cpython-313-x86_64-linux-gnu.so": 16309838137741124637,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimes.py": 8863748366184419339,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe.py": 16525846817331842080,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/ec_key.py": 5961540064444749833,
- "venv/lib/python3.13/site-packages/idna/__init__.py": 6489437464172324468,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py": 8706265665356094801,
- "venv/lib/python3.13/site-packages/pandas/tests/io/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/styles/nord.py": 8469538903422182155,
- "venv/lib/python3.13/site-packages/starlette/testclient.py": 16088848330558215194,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/INSTALLER": 17282701611721059870,
- "backend/src/models/report.py": 12105030884508258995,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_csv.py": 571991535656576735,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_scalar_compat.py": 10068989979144965125,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot.py": 334735766122314163,
- "venv/lib/python3.13/site-packages/fastapi/__init__.py": 11054203163075417954,
- "venv/lib/python3.13/site-packages/pydantic/json.py": 4109352930301629308,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/numerictypes.pyi": 15565573472138344755,
- "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/pip/_internal/req/req_install.py": 7181005402818830655,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/structs.py": 4479429145468072604,
- "venv/lib/python3.13/site-packages/pandas/tests/internals/test_internals.py": 2049484047553296860,
- "venv/lib/python3.13/site-packages/pytest/__main__.py": 8747175113746141224,
- "backend/tests/test_storage_audit_fixes.py": 6119862973635892572,
- "backend/git_repos/remote/test-repo.git/hooks/fsmonitor-watchman.sample": 14381968406977928721,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/highway/LICENSE": 15636145745140922094,
- "venv/lib/python3.13/site-packages/PIL/GbrImagePlugin.py": 7681313333602257802,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/generic.py": 4857114071347950833,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_set.py": 14375107704596905983,
- "venv/lib/python3.13/site-packages/uvicorn/config.py": 17317823506849880916,
- "venv/lib/python3.13/site-packages/keyring/__main__.py": 14602212239605295451,
- "venv/lib/python3.13/site-packages/pygments/lexers/matlab.py": 1880915927722177654,
- "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.cpython-313-x86_64-linux-gnu.so": 1211491156495529145,
- "venv/lib/python3.13/site-packages/pydantic/alias_generators.py": 5991580234179623842,
- "frontend/src/lib/components/reports/__tests__/fixtures/reports.fixtures.js": 9590309593907049070,
- "backend/src/core/middleware/trace.py": 132582224686397900,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/conftest.py": 12368472226536104037,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.cpython-313-x86_64-linux-gnu.so": 13104135217735363438,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/__init__.py": 6654484356035994666,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_interpolate.py": 7354685880215444946,
- "venv/lib/python3.13/site-packages/passlib/handlers/ldap_digests.py": 8658529184965699766,
- "venv/lib/python3.13/site-packages/cffi/commontypes.py": 11198107299826138465,
- "backend/src/plugins/llm_analysis/service.py": 8630918629937474981,
- "frontend/src/components/TaskHistory.svelte": 2442500891309602262,
- "merge_kilo.py": 4282227344165325430,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_is_homogeneous_dtype.py": 15378147393056707851,
- "backend/src/plugins/llm_analysis/plugin.py": 7300309025111736,
- "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/WHEEL": 7795541085444298627,
- "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/METADATA": 9586902338916246692,
- "venv/lib/python3.13/site-packages/click/parser.py": 13988544851350599869,
- "venv/lib/python3.13/site-packages/pyasn1/type/char.py": 16518487114777185541,
- "venv/lib/python3.13/site-packages/pandas/tests/libs/test_libalgos.py": 13934861984871432400,
- "venv/lib/python3.13/site-packages/pandas/tests/window/conftest.py": 10673264126684571493,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_errors.py": 3301889847545579393,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.pyi": 2700568594438441246,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90": 10939657740734987454,
- "venv/lib/python3.13/site-packages/pandas/_libs/__init__.py": 17117112389651696580,
- "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/LICENSE": 6774760218010069963,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_parser.py": 8145921552236189367,
- "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.cpython-313-x86_64-linux-gnu.so": 11074560904305737689,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_compression.py": 8577756801858495168,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_arithmetic.py": 4858019700859362660,
- "frontend/src/routes/settings/LoggingSettings.svelte": 5172094246995863925,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/ma/LICENSE": 6723325434476453127,
- "frontend/build/_app/immutable/nodes/34.BvudVJiY.js": 938635370536078571,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_day.py": 6371851881186970754,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/apply.py": 3906017176873949738,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.pyf": 14358606965464506398,
- "backend/git_repos/remote/test-repo.git/hooks/applypatch-msg.sample": 12627299623252391515,
- "venv/lib/python3.13/site-packages/pip/__main__.py": 574438877257676911,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/pivot.py": 4736553530021653868,
- "venv/lib/python3.13/site-packages/ecdsa/curves.py": 812969717084691115,
- "backend/git_repos/remote/test-repo.git/objects/c2/491dfd8c841bacd5f491510f6334aa4a626f00": 6297303620364618482,
- "venv/lib/python3.13/site-packages/pygments/lexers/tls.py": 3552078393009383412,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/qt.py": 12828696264909048448,
- "backend/src/services/clean_release/stages/data_purity.py": 7015962973560119808,
- "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/sqlalchemy/events.py": 9329355486544822483,
- "venv/lib/python3.13/site-packages/packaging/_musllinux.py": 2568338440457080365,
- "venv/lib/python3.13/site-packages/passlib/hash.py": 5238710192614935875,
- "venv/lib/python3.13/site-packages/httpcore/_async/http2.py": 16350817785499681224,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_types.py": 651959450717569029,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_macosx.h": 3653129798702716366,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/list.py": 13035925292530461722,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_known_annotated_metadata.py": 9308620143218174987,
- "venv/lib/python3.13/site-packages/numpy/random/lib/libnpyrandom.a": 1802449692091040396,
- "venv/lib/python3.13/site-packages/pandas/util/_decorators.py": 14780166101442507665,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_ewm.py": 13789842684407148830,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timestamp.py": 10308799534491190078,
- "venv/lib/python3.13/site-packages/pandas/_testing/compat.py": 10172779814048259850,
- "venv/lib/python3.13/site-packages/pygments/lexers/jslt.py": 11805394130669644345,
- "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/METADATA": 4975169119201255384,
- "venv/lib/python3.13/site-packages/numpy/core/_multiarray_umath.py": 10973016138581934035,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/test_blocking.py": 6312017389529916004,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/assertion.py": 5287436128235488464,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_empty.py": 6845813091876023610,
- "venv/lib/python3.13/site-packages/cffi/lock.py": 13507686939203117974,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.pyx": 17138729833735744777,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_formats.py": 12299393760307251036,
- "venv/lib/python3.13/site-packages/PIL/ImageChops.py": 16368812693381154921,
- "venv/lib/python3.13/site-packages/PIL/ImagePalette.py": 9227837918026991107,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90": 8308927438994838783,
- "backend/src/api/routes/plugins.py": 6640856303389338188,
- "venv/lib/python3.13/site-packages/pygments/lexers/rita.py": 8105458520706587972,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/common.py": 2075178842766962782,
- "venv/lib/python3.13/site-packages/h11/_util.py": 9362339074207904329,
- "venv/lib/python3.13/site-packages/psycopg2/_range.py": 7184417109068014771,
- "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.pyi": 2029639875417260268,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/meson.build": 8784756284679859367,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/diagnose.py": 17275977405061138181,
- "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.pyi": 9206355685192026844,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/distributions.h": 17162252287980242413,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/api.py": 13134394673408254097,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_reductions.py": 2816859231048302619,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/__init__.py": 697601512486720554,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/common.py": 11384497819737275399,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/compat.py": 16148553252010089561,
- "frontend/playwright-report/trace/sw.bundle.js": 10879347794748701702,
- "frontend/src/routes/settings/git/+page.svelte": 16557825098267956169,
- "venv/lib/python3.13/site-packages/pandas/tests/base/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.py": 2215312866861772848,
- "venv/lib/python3.13/site-packages/greenlet/platform/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta_range.py": 15081095442418142820,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/core.py": 14576109242055156193,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_array.py": 11271807719833350332,
- "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.pyi": 15864712173815045309,
- "frontend/build/_app/immutable/nodes/7.uApaBQtS.js": 122651088329333182,
- "frontend/build/_app/immutable/chunks/DcMPZ_fa.js": 6501595943098370468,
- "backend/src/scripts/create_admin.py": 12963729348700590154,
- "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.pyi": 18193727720492050602,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_update.py": 12293424926920594944,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_constructors.py": 9767900500541600486,
- "backend/src/core/auth/logger.py": 13549160352454060608,
- "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.py": 15031197044862908440,
- "backend/git_repos/remote/test-repo.git/objects/38/0395343915d386a8d58774cc6c6677205065e8": 5481382229802988191,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_item.py": 17619314877770917080,
- "frontend/src/lib/api/translate/corrections.js": 3619404083693055292,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/scalars.pyi": 3130685119595923378,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.pyf": 10179237442840865225,
- "frontend/build/_app/immutable/nodes/3.DC_u72aE.js": 9573850396512596892,
- "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/METADATA": 15987199384245264478,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tan.csv": 6233924374281534211,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/base.py": 11386927749822539057,
- "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/numpy/core/numeric.py": 17025007229779320230,
- "venv/lib/python3.13/site-packages/jeepney/io/asyncio.py": 13239992245695516007,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append_common.py": 2377351120083195530,
- "venv/lib/python3.13/site-packages/websockets/speedups.pyi": 10322382420215791091,
- "venv/lib/python3.13/site-packages/pydantic/_internal/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayterator.pyi": 15722265241660279277,
- "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/LICENSE": 17675192170670564526,
- "venv/lib/python3.13/site-packages/pygments/formatters/terminal256.py": 11473927781167132440,
- "frontend/build/_app/immutable/nodes/11.AnPCb-Ut.js": 13179973353447891567,
- "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.pyi": 15745512451486888537,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexer.py": 14400766876373764268,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_take.py": 9847808489301498487,
- "venv/lib/python3.13/site-packages/gitdb/db/git.py": 13552203494737962026,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/env.py": 1254612137164491329,
- "venv/lib/python3.13/site-packages/pygments/lexers/tcl.py": 10343667975436015855,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/__init__.py": 16532856661318424631,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/retry.py": 17371295199208325375,
- "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/RECORD": 8956798822782402202,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi": 1626154870044880426,
- "venv/lib/python3.13/site-packages/_pytest/_py/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.pyi": 3814281717779245045,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c": 17333399794446198412,
- "venv/lib/python3.13/site-packages/pip/_internal/models/direct_url.py": 4619204214785230341,
- "venv/lib/python3.13/site-packages/pandas/_libs/sas.pyi": 873957906443703977,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/melt.py": 14109947554124551986,
- "frontend/static/favicon.svg": 6451919037497541980,
- "frontend/src/routes/translate/dictionaries/[id]/+page.svelte": 17719561272401762626,
- "venv/lib/python3.13/site-packages/greenlet/PyModule.cpp": 3464405102256525511,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/structures.py": 2668010839316715865,
- "venv/lib/python3.13/site-packages/pydantic/v1/fields.py": 3948219773415054006,
- "venv/lib/python3.13/site-packages/greenlet/_greenlet.cpython-313-x86_64-linux-gnu.so": 6036818030377883416,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/filewrapper.py": 17786759398959482432,
- "venv/lib/python3.13/site-packages/passlib/handlers/sha1_crypt.py": 5752556581809938954,
- "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/METADATA": 11419135077900073883,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_subclassing.py": 17318983445227658412,
- "venv/lib/python3.13/site-packages/httpx/_api.py": 6697370469329778523,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/uts46data.py": 1867240043777383728,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarmath.py": 9762951701352556447,
- "venv/lib/python3.13/site-packages/pandas/_libs/pandas_datetime.cpython-313-x86_64-linux-gnu.so": 15874094681262240628,
- "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/METADATA": 2604612822968175379,
- "venv/lib/python3.13/site-packages/sqlalchemy/future/engine.py": 4639404437703898767,
- "venv/lib/python3.13/site-packages/cffi/pkgconfig.py": 16057517851163939571,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/random/c_distributions.pxd": 16574161095720077595,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_timedelta.py": 17052461094717926538,
- "venv/lib/python3.13/site-packages/pandas/_libs/missing.cpython-313-x86_64-linux-gnu.so": 1990755879067132155,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_pickle.py": 4216445955812104014,
- "venv/lib/python3.13/site-packages/pandas/io/formats/printing.py": 3054136648863371285,
- "venv/lib/python3.13/site-packages/pygments/lexers/cplint.py": 13990118342267278047,
- "backend/src/models/__init__.py": 13280325675752905975,
- "venv/lib/python3.13/site-packages/ecdsa/test_keys.py": 17117188373419689467,
- "venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17": 4221600618602131476,
- "venv/lib/python3.13/site-packages/uvicorn/supervisors/basereload.py": 14479857245734482609,
- "venv/lib/python3.13/site-packages/_pytest/_io/pprint.py": 11202117031437223527,
- "frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js": 13812015120538720344,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_reindex.py": 15794750188594767026,
- "backend/src/api/routes/__init__.py": 4671856475376690434,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/concurrency.py": 1325673503812009695,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh18335.f90": 1126438609189294255,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_multi_thread.py": 5660352470978621226,
- "venv/lib/python3.13/site-packages/smmap/util.py": 13276170835044840023,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_quantile.py": 11273403743157110261,
- "venv/lib/python3.13/site-packages/passlib/utils/pbkdf2.py": 15802959653228956404,
- "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py": 9627328185578406121,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_block_internals.py": 17935662848672401507,
- "backend/src/services/clean_release/mappers.py": 16365217670331724280,
- "venv/lib/python3.13/site-packages/apscheduler/executors/debug.py": 14072221218785494847,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_git.py": 8760779092674434712,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/test_typing.py": 10311989961588249147,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_python_parser_only.py": 12231449578582108346,
- "frontend/build/_app/immutable/nodes/39.x6Tr2rq6.js": 8373901766277015937,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_gcc.h": 3561524604274567339,
- "backend/src/plugins/translate/orchestrator_validation.py": 17464651621865127561,
- "frontend/src/routes/settings/MigrationMappingsTable.svelte": 574459541553883663,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_constructors.py": 5627819885594450614,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/module_data_docstring.f90": 18245403117623015312,
- "venv/lib/python3.13/site-packages/passlib/tests/test_pwd.py": 10089138951415591061,
- "venv/lib/python3.13/site-packages/pygments/lexers/html.py": 17288963642862550116,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategies.py": 15673926142454922581,
- "venv/lib/python3.13/site-packages/requests/__version__.py": 6677532709758546816,
- "venv/lib/python3.13/site-packages/_pytest/tracemalloc.py": 5530234062530858720,
- "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/licenses/LICENSE": 9235234428907927646,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arithmetic.pyi": 10265823318697442495,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_values.py": 8372572954663628844,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_reduction.py": 1049551473665255648,
- "venv/lib/python3.13/site-packages/numpy/ma/testutils.pyi": 3899348061346041413,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_apply.py": 7511915990531229598,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_argon2.py": 11345706437113628133,
- "venv/lib/python3.13/site-packages/PIL/IptcImagePlugin.py": 14329453455296600824,
- "venv/lib/python3.13/site-packages/pygments/formatters/latex.py": 7514533384468139434,
- "venv/lib/python3.13/site-packages/pygments/lexers/bdd.py": 5389493859905397060,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_quantile.py": 17110581927381599978,
- "venv/lib/python3.13/site-packages/pydantic_core/py.typed": 15130871412783076140,
- "backend/alembic/versions/f0e9d8c7b6a5_cascade_ondelete_all_env_fks.py": 18274103435952144919,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.pyi": 13173581775000480811,
- "venv/lib/python3.13/site-packages/attr/filters.pyi": 13942974755090135724,
- "venv/lib/python3.13/site-packages/_pytest/stash.py": 14430252294763173610,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fft.pyi": 14454280827038327842,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/_orm_constructors.py": 4276726508722638048,
- "backend/src/api/routes/__tests__/test_reports_api.py": 12407027129865592126,
- "backend/src/plugins/translate/__tests__/test_text_cleaner.py": 5542992003631016259,
- "venv/lib/python3.13/site-packages/pandas/_libs/index.cpython-313-x86_64-linux-gnu.so": 18409579812171549318,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_index.py": 12015738970771703312,
- "backend/src/plugins/translate/dictionary.py": 4150581558765697237,
- "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.pyi": 16573082220135508510,
- "venv/lib/python3.13/site-packages/pandas/core/window/online.py": 13551140636252302201,
- "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/mlib.ini": 16151597765994697599,
- "frontend/src/lib/components/layout/sidebarNavigation.js": 13126350681069395289,
- "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.pyi": 17825266810219495672,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_as_unit.py": 8492383355919959393,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_internals.py": 10472508540875131797,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_accessor.py": 10074496835594855786,
- "venv/lib/python3.13/site-packages/pygments/styles/native.py": 4559566444883341527,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_numpy_array_equal.py": 2089426719574307767,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_na_indexing.py": 8712547126522523899,
- "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_to_xml.py": 8477770807916990981,
- "venv/lib/python3.13/site-packages/cryptography/fernet.py": 10137792148038140630,
- "venv/lib/python3.13/site-packages/pandas/__init__.py": 793698514004377486,
- "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_deprecations.py": 14624516389510242394,
- "frontend/src/lib/ui/Select.svelte": 1377129595022044035,
- "backend/src/api/routes/git/_router.py": 14821560101452369211,
- "venv/lib/python3.13/site-packages/gitdb/base.py": 7927279446353696534,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayterator.pyi": 7439348655567232744,
- "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/RECORD": 4857922668040624663,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/foo.f": 6349567809926050379,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/authorization_server.py": 724388765673082720,
- "venv/lib/python3.13/site-packages/pyasn1/error.py": 11036037300994516747,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_join.py": 13115782559805895662,
- "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/RECORD": 3649834117451110628,
- "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA": 732041908491732594,
- "docker/nginx.conf": 14595959129793115016,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_pad.pyi": 14755435694146003896,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_setops.py": 10550603120090683350,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_resolution.py": 18198858926948468112,
- "venv/lib/python3.13/site-packages/numpy/rec/__init__.pyi": 1782063765067823837,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_categorical.py": 9923236395692943732,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/instrumentation.py": 13198832283145198959,
- "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/request.py": 17642741955458391050,
- "venv/lib/python3.13/site-packages/rsa/key.py": 4783269051050521475,
- "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/styles/stata_light.py": 16319330015324455277,
- "venv/lib/python3.13/site-packages/pygments/lexers/zig.py": 470431199354307668,
- "frontend/src/lib/api/reports.js": 12520710039739782171,
- "frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js": 1278883813018181993,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/repr.py": 839417422880281122,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/random.pyi": 9425735458050148191,
- "venv/lib/python3.13/site-packages/httpx/_multipart.py": 2181282475656908730,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/wrappers.py": 315409799569602977,
- "venv/lib/python3.13/site-packages/pydantic/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90": 5765181406654284736,
- "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_tests.cpython-313-x86_64-linux-gnu.so": 442168371609469538,
- "venv/lib/python3.13/site-packages/pandas/core/nanops.py": 18291534943985310005,
- "venv/lib/python3.13/site-packages/pluggy/_result.py": 16790448391766505769,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_halfyear.py": 587199217232946404,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_period.py": 6255181868181182780,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_writers.py": 103545128256076790,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/create.py": 16693261531832306870,
- "venv/lib/python3.13/site-packages/PIL/Jpeg2KImagePlugin.py": 16905402423248975204,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_constructors.py": 1697610790604400105,
- "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/licenses/LICENSE": 11986475601091748012,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/auto.py": 12818217385551437286,
- "venv/lib/python3.13/site-packages/pygments/formatters/rtf.py": 5850574956253747036,
- "venv/bin/pip": 13861749540792881808,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/models.py": 5656065513234782067,
- "frontend/playwright-report/trace/uiMode.Btcz36p_.css": 7361350017361398233,
- "backend/src/core/middleware/__init__.py": 13917394130915533209,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/client.py": 18443944554871937480,
- "venv/lib/python3.13/site-packages/smmap/test/test_tutorial.py": 16309370344201290582,
- "backend/src/api/routes/maintenance/_router.py": 1368406181799456173,
- "venv/lib/python3.13/site-packages/passlib/utils/compat/__init__.py": 17369882236606423129,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/categorical.py": 16588862198627920420,
- "venv/lib/python3.13/site-packages/pip/_vendor/distro/__init__.py": 11414161642984633362,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.f": 18215492757907465667,
- "frontend/src/routes/settings/+page.ts": 3719008513710037840,
- "venv/lib/python3.13/site-packages/greenlet/TGreenlet.cpp": 4121171004360760212,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_drop_duplicates.py": 12601598844977346213,
- "backend/src/models/dataset_review_pkg/_semantic_models.py": 6371476812115351221,
- "venv/lib/python3.13/site-packages/pyasn1/codec/ber/decoder.py": 12653470212935324322,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_spinners.py": 15873416546130487469,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_regression.py": 12593643817685777170,
- "venv/lib/python3.13/site-packages/jose/backends/native.py": 50023158618000658,
- "backend/src/api/routes/dashboards/_detail_routes.py": 10963740344709618288,
- "venv/lib/python3.13/site-packages/pygments/lexers/tact.py": 1164971357219795420,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_repr.py": 16609300578827398344,
- "venv/lib/python3.13/site-packages/fastapi/background.py": 16533963020573865222,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/util.py": 1520899420719605380,
- "venv/lib/python3.13/site-packages/pytest_asyncio/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/minecraft.py": 10133579583270214110,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_functions.py": 16376319335326812580,
- "venv/lib/python3.13/site-packages/pygments/lexers/perl.py": 17014528337020572681,
- "venv/lib/python3.13/site-packages/apscheduler/events.py": 10748346950729364899,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/idnadata.py": 1169745920682458213,
- "venv/lib/python3.13/site-packages/_pytest/monkeypatch.py": 2635774457434545573,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_indexing.py": 2274965639578580723,
- "venv/lib/python3.13/site-packages/PIL/ImageStat.py": 18442709639217312689,
- "venv/lib/python3.13/site-packages/yaml/emitter.py": 6036657460416912844,
- "backend/src/services/notifications/providers.py": 12802217818475476969,
- "venv/lib/python3.13/site-packages/pygments/lexers/spice.py": 1376126320935115350,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_skiprows.py": 8764515842253490735,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_abstract_interface.py": 17625870734108222276,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunc_config.pyi": 11754104063443791746,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.cpython-313-x86_64-linux-gnu.so": 12654188486128938170,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/__init__.py": 15130871412783076140,
- "backend/git_repos/remote/test-repo.git/objects/5d/9eb555c4cac2d3ffdba84c07682b154fe4180d": 10756202165146702691,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/__init__.py": 4752355175318979033,
- "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA": 18410956221497090898,
- "backend/src/__init__.py": 11250920420388310655,
- "venv/lib/python3.13/site-packages/keyring/backends/null.py": 12740996416911604870,
- "venv/lib/python3.13/site-packages/pandas/io/formats/format.py": 3364941338174434661,
- "venv/lib/python3.13/site-packages/python_multipart/exceptions.py": 5971058243218049183,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/syntax.py": 18070449217682341495,
- "venv/lib/python3.13/site-packages/rapidfuzz/__init__.py": 12462153783886855740,
- "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.pyi": 2744889206277418389,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine.py": 4446011286411407708,
- "venv/lib/python3.13/site-packages/pip/_internal/index/sources.py": 11609272011565024668,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval.py": 18040371224712437126,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/sync.py": 6189260178302531376,
- "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/METADATA": 5628172948035858892,
- "frontend/playwright-report/data/36557793d7fda8ef412a553a55389600452506f9.png": 8526067803082440263,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_holiday.py": 8541197358003711845,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/compatibility_tags.py": 15862649917149158291,
- "venv/lib/python3.13/site-packages/passlib/tests/test_apache.py": 12515001998770565375,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/virtualenv.py": 14416705841810221305,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/cli.py": 6382193953727339271,
- "venv/lib/python3.13/site-packages/pip/_internal/models/candidate.py": 3099785363867247334,
- "venv/lib/python3.13/site-packages/websockets/asyncio/async_timeout.py": 7267209982032642028,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.BSD": 16833702494864671773,
- "venv/lib/python3.13/site-packages/_pytest/mark/structures.py": 12237146603608917650,
- "venv/lib/python3.13/site-packages/_pytest/logging.py": 10972553724755511468,
- "venv/lib/python3.13/site-packages/ecdsa/ecdh.py": 12596317261561755793,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_bcrypt.py": 11146468670439284889,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.pyi": 3783371827926657291,
- "venv/lib/python3.13/site-packages/pandas/core/computation/scope.py": 16859504937881548797,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/scipy_sparse.py": 2091608752719976909,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename.py": 16148017223289654683,
- "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.py": 546976622482819095,
- "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/WHEEL": 12146818530001975731,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_common.py": 2265736743367879051,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timezones.py": 1962830142478494009,
- "venv/lib/python3.13/site-packages/_pytest/assertion/truncate.py": 14000392306994773741,
- "venv/lib/python3.13/site-packages/numpy/_core/__init__.pyi": 2783897020308040960,
- "venv/lib/python3.13/site-packages/numpy/_core/_internal.py": 13056946834347643109,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/conftest.py": 12065119814157197510,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_utils.pyi": 3708905060001289515,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_utils.py": 4612923732868929770,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema_ext_dtype.py": 13021437050542691118,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/provision.py": 17812733620485633975,
- "venv/lib/python3.13/site-packages/keyring/util/__init__.py": 9635016046220094473,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/negative_bounds/issue_20853.f90": 3911644649277659333,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlite.py": 16550134594771291234,
- "venv/lib/python3.13/site-packages/PIL/JpegPresets.py": 12342262642420923471,
- "venv/lib/python3.13/site-packages/fastapi/_compat/shared.py": 5249003014594464718,
- "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pydantic/__init__.py": 11536052293866174672,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslib.pyi": 16170606956605100142,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_coercion.py": 7261787308019145312,
- "frontend/src/lib/stores/sidebar.js": 4584261073573678043,
- "frontend/src/lib/api/translate/dictionaries.js": 13928848549982189213,
- "backend/src/api/routes/datasets.py": 3167720733470487965,
- "frontend/build/_app/immutable/chunks/C20922N0.js": 14681700380768364777,
- "backend/src/api/routes/__tests__/test_dataset_review_api.py": 9392418725327519178,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_repeat.py": 11360772447747837958,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/encoding.py": 12702053687535473061,
- "venv/bin/py.test": 2593802493707545818,
- "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/METADATA": 6596896092754256988,
- "backend/src/api/routes/assistant/_llm_planner_intent.py": 1835887541250815399,
- "venv/lib/python3.13/site-packages/dateutil/tz/_common.py": 9009072600471223066,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90": 13943066317159236257,
- "venv/lib/python3.13/site-packages/attr/_typing_compat.pyi": 2823472697859409877,
- "venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-94e588ba.so.2.5.4": 2483101806045986252,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.pyi": 15498895254516573071,
- "backend/src/services/dataset_review/clarification_pkg/_helpers.py": 16131390986170241319,
- "backend/src/plugins/translate/orchestrator_query.py": 4760681990145471312,
- "frontend/build/_app/immutable/chunks/CyrRIrvE.js": 6233954911328508847,
- "backend/src/services/mapping_service.py": 14740129302452546978,
- "venv/lib/python3.13/site-packages/jose/backends/cryptography_backend.py": 2875270748627611635,
- "backend/tests/test_resource_hubs.py": 1620639151885021568,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py": 6205112277291935767,
- "backend/src/plugins/translate/_batch_proc.py": 1865600844314846685,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccos.csv": 3026156288992132911,
- "backend/src/api/routes/dashboards/_schemas.py": 4116381929361209080,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py": 10843527833285941674,
- "venv/lib/python3.13/site-packages/dotenv/version.py": 13508433229287636267,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate.py": 16723865897349422996,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_construction.py": 13953424340346625390,
- "venv/lib/python3.13/site-packages/ecdsa/test_jacobi.py": 1249543655136186433,
- "venv/lib/python3.13/site-packages/keyring/compat/__init__.py": 7578020229796085753,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/jwk.py": 6458001384702613165,
- "venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp": 15599148954148720463,
- "venv/lib/python3.13/site-packages/numpy/typing/mypy_plugin.py": 1306129775649200113,
- "venv/lib/python3.13/site-packages/numpy/char/__init__.pyi": 12214207343146244743,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby.py": 16180421154734310873,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data": 11957232619107868023,
- "venv/lib/python3.13/site-packages/PIL/MpoImagePlugin.py": 644327650732339301,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_index.py": 10971093361190283675,
- "venv/lib/python3.13/site-packages/anyio/_core/_fileio.py": 4507100568401692983,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/testing.pyi": 16263777835572515739,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo77.f": 12000068001851270396,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reshaping.py": 18085648077811502689,
- "venv/lib/python3.13/site-packages/pandas/io/feather_format.py": 13242733585787888812,
- "venv/lib/python3.13/site-packages/PIL/ImtImagePlugin.py": 17599267755504817169,
- "venv/lib/python3.13/site-packages/git/py.typed": 15130871412783076140,
- "backend/src/api/routes/migration.py": 16089356899043357784,
- "venv/lib/python3.13/site-packages/numpy/core/__init__.pyi": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_repr.py": 13147587049887075335,
- "venv/lib/python3.13/site-packages/jeepney/fds.py": 16573439672758641560,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccosh.csv": 5882025767947638305,
- "venv/lib/python3.13/site-packages/anyio/abc/_testing.py": 16484863782452886547,
- "frontend/build/_app/immutable/nodes/20.BboyjuGl.js": 11318425268071802665,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_results.py": 18145930285449734975,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/web.py": 11104721221615804497,
- "venv/lib/python3.13/site-packages/git/objects/submodule/__init__.py": 12958523219496107878,
- "frontend/src/routes/settings/settings-utils.js": 1940619437304867415,
- "venv/lib/python3.13/site-packages/pandas/errors/__init__.py": 13444371880185740908,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/client.py": 17305914656270781911,
- "venv/lib/python3.13/site-packages/anyio/_core/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_internal/models/installation_report.py": 14534544543677907640,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_compression.py": 8061288329598682752,
- "venv/lib/python3.13/site-packages/pygments/formatters/pangomarkup.py": 17135620955205945255,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_mips_unix.h": 17373389962405490482,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py": 5132658725516243311,
- "venv/lib/python3.13/site-packages/uvicorn/supervisors/watchfilesreload.py": 13062440477475586751,
- "venv/lib/python3.13/site-packages/sqlalchemy/connectors/__init__.py": 17194870661869873083,
- "backend/src/core/superset_client/_base.py": 8704044125468217140,
- "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/METADATA": 7727489762869155085,
- "venv/lib/python3.13/site-packages/gitdb/test/test_base.py": 16305779366785148795,
- "venv/lib/python3.13/site-packages/rpds/__init__.py": 5862197328247012275,
- "venv/lib/python3.13/site-packages/passlib/tests/backports.py": 17098448557554464521,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/__init__.py": 293004106962245584,
- "venv/lib/python3.13/site-packages/attr/_funcs.py": 5302917072419624193,
- "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/licenses/COPYING": 15270149301471737292,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_reductions.py": 633644255158859565,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_categorical_equal.py": 7942323667866280872,
- "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/licenses/LICENSE": 3996324383113221529,
- "venv/lib/python3.13/site-packages/numpy/_core/multiarray.py": 4484782354376574355,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_auth.py": 15125055415702968414,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq_py.py": 16054175754674285311,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet_trash.py": 6191655521667576604,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/implicit.py": 7379110378465568776,
- "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_version.py": 849232015288488204,
- "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_salsa.py": 1756536674254931838,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/claims.py": 12645788445743898136,
- "venv/lib/python3.13/site-packages/passlib/registry.py": 5050675058011850564,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/var_.py": 12699521091170347311,
- "venv/lib/python3.13/site-packages/pandas/api/internals.py": 5188134630996087511,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_period.py": 10309599277099605395,
- "venv/lib/python3.13/site-packages/numpy/lib/mixins.pyi": 15597536290223628777,
- "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_can_hold_element.py": 5406431247116557833,
- "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/LICENSE": 8423899413955829149,
- "venv/lib/python3.13/site-packages/pandas/tests/test_multilevel.py": 10500316376521962061,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/types.py": 12298292195929126306,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath.py": 13010939919217862164,
- "venv/lib/python3.13/site-packages/PIL/ImageText.py": 15322496455608242001,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/setup.py": 5482352991573617756,
- "venv/lib/python3.13/site-packages/pandas/tests/test_register_accessor.py": 16661086720613729974,
- "venv/lib/python3.13/site-packages/yaml/dumper.py": 11376022992370902766,
- "venv/lib/python3.13/site-packages/pygments/formatters/img.py": 18230180171537565208,
- "venv/lib/python3.13/site-packages/urllib3/util/response.py": 6106698559175827207,
- "venv/lib/python3.13/site-packages/pygments/plugin.py": 18006138132596504101,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_localize.py": 18409231586451494605,
- "venv/lib/python3.13/site-packages/pillow.libs/libjpeg-32d42e18.so.62.4.0": 11717944412021329207,
- "venv/lib/python3.13/site-packages/secretstorage/util.py": 1004887530903069622,
- "venv/lib/python3.13/site-packages/pygments/lexers/basic.py": 12723021007042054402,
- "frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js": 966219842574639412,
- "frontend/src/routes/translate/+page.svelte": 15284819686967093613,
- "backend/src/api/routes/dashboards/_listing_routes.py": 5891601903803528865,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/style.py": 10665998898253460114,
- "backend/src/api/routes/git/_environment_routes.py": 5687847761729712859,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/modeline.py": 6194365452131561478,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/pretty.py": 2448541115957861214,
- "backend/src/services/notifications/__tests__/test_notification_service.py": 13027609991239837872,
- "backend/src/plugins/translate/preview_session_serializer.py": 8901687711861433007,
- "frontend/src/lib/components/health/ScheduleAtAGlance.svelte": 10633565118611866798,
- "frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js": 6211740843387025179,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_parser.py": 3540203683732744499,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/conftest.py": 8406022190801970256,
- "backend/git_repos/remote/test-repo.git/objects/4f/4e0958b3a42eff67a2b8cfd084d05c43e54716": 6040513978194442637,
- "backend/src/core/utils/superset_context_extractor/__init__.py": 16372223806424875537,
- "backend/src/core/auth/config.py": 4868978979228156169,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_melt.py": 15663807247682146566,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_arithmetic.py": 16829312896275893002,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/flatiter.py": 3066469329738423021,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/methods.py": 8059372834301557565,
- "venv/lib/python3.13/site-packages/passlib/tests/test_registry.py": 15377817946543064293,
- "backend/src/api/routes/git/_repo_operations_routes.py": 11164792016063890809,
- "backend/src/api/routes/translate/_correction_routes.py": 9348235443422223333,
- "venv/lib/python3.13/site-packages/apscheduler/executors/pool.py": 10344126569001032241,
- "venv/lib/python3.13/site-packages/_pytest/junitxml.py": 5871715626272366062,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_dispatcher.py": 2063037275809439611,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop.py": 17940792593116540139,
- "backend/src/services/maintenance/_dashboard_scanner.py": 1401108008906511280,
- "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/METADATA": 15970460108484113417,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_legacy.py": 9226692984248279094,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py": 8079219938116542284,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_interface.py": 13648006002292914247,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_snap.py": 4515844385819802784,
- "venv/lib/python3.13/site-packages/pip/_internal/index/collector.py": 7454652626329467900,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_set_name.py": 9094608008538024609,
- "venv/lib/python3.13/site-packages/pandas/io/formats/__init__.py": 18140261896107421679,
- "frontend/src/lib/components/health/PolicyForm.svelte": 17995152707951193436,
- "venv/lib/python3.13/site-packages/pygments/lexers/typst.py": 8883289726601667104,
- "backend/src/schemas/__tests__/test_settings_and_health_schemas.py": 17933166680828315099,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector_cpp.cpython-313-x86_64-linux-gnu.so": 16337157355618216738,
- "frontend/build/favicon.png": 16740551781088792605,
- "backend/src/plugins/translate/_run_service.py": 1705461175389858266,
- "backend/src/plugins/translate/service_target_schema.py": 5277952452702772295,
- "backend/tests/test_task_manager.py": 4305202721942095979,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_join.py": 1697622393195784944,
- "venv/lib/python3.13/site-packages/numpy/random/_pickle.py": 7774620933480975313,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/astype.py": 9925183787411796679,
- "frontend/src/lib/Counter.svelte": 3616557554460116236,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_function.py": 13492077564015386528,
- "venv/lib/python3.13/site-packages/pandas/core/ops/missing.py": 9493665944764255854,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reduce.py": 14976712507854054776,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asfreq.py": 2701081989348180239,
- "venv/lib/python3.13/site-packages/attr/__init__.pyi": 13203080513025719049,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta.py": 7742506012012398830,
- "venv/lib/python3.13/site-packages/pygments/lexers/verification.py": 16645885125604874183,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/emoji.py": 9166774203918731896,
- "venv/lib/python3.13/site-packages/anyio/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_base.py": 16710163879060522196,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_util.py": 16908393806993809474,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/elements.py": 11185011314498348980,
- "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/emscripten_fetch_worker.js": 10530710876604536879,
- "venv/lib/python3.13/site-packages/pygments/styles/vs.py": 4188729978573652106,
- "frontend/src/lib/ui/Card.svelte": 8508366526326051165,
- "venv/lib/python3.13/site-packages/attr/validators.pyi": 15579625896285277321,
- "frontend/build/_app/immutable/nodes/13.CWfoAyT-.js": 16342502651271133149,
- "backend/src/models/__tests__/test_report_models.py": 1002634514476529590,
- "backend/src/services/superset_lookup_service.py": 13103450036073956615,
- "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py": 990102078989024575,
- "backend/tests/core/migration/test_dry_run_orchestrator.py": 5618205549212894117,
- "venv/lib/python3.13/site-packages/git/types.py": 13960696584646279283,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log2.csv": 13979868713429167140,
- "venv/lib/python3.13/site-packages/httpx/_transports/mock.py": 13564349939188292363,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.pyi": 13110894861187422750,
- "venv/lib/python3.13/site-packages/anyio/_core/_subprocesses.py": 7271614043537119143,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_printing.py": 8859757563354666575,
- "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/METADATA": 14608873187265321271,
- "frontend/build/_app/immutable/chunks/BddPqa-e.js": 3040470451817822725,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_records.py": 18167578114159312327,
- "venv/lib/python3.13/site-packages/urllib3/connectionpool.py": 7493427857878469165,
- "venv/lib/python3.13/site-packages/cffi/model.py": 13544803366359102016,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine.py": 16193618152415684421,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-2.csv": 16611724551361692999,
- "venv/lib/python3.13/site-packages/fastapi/middleware/trustedhost.py": 4285622102799027823,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_take.py": 14969455660160053080,
- "venv/lib/python3.13/site-packages/idna-3.11.dist-info/INSTALLER": 17282701611721059870,
- "frontend/build/_app/immutable/nodes/12.DDTJ85nU.js": 2496436780075636781,
- "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/apscheduler/executors/gevent.py": 17122637996105344344,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_convert_dtypes.py": 5005259275646154894,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_stata.py": 3030675968330529905,
- "venv/lib/python3.13/site-packages/charset_normalizer/legacy.py": 1706599349563920562,
- "venv/lib/python3.13/site-packages/_pytest/skipping.py": 10561585274103209115,
- "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/RECORD": 6488682447051657004,
- "venv/lib/python3.13/site-packages/pygments/styles/xcode.py": 14124729477757765388,
- "frontend/src/routes/datasets/MetricsTable.svelte": 4644516916752609053,
- "backend/src/core/__tests__/test_throttled_scheduler.py": 3526995607557121417,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/period.py": 11560984428402318984,
- "venv/lib/python3.13/site-packages/itsdangerous/signer.py": 3694661094753475840,
- "venv/lib/python3.13/site-packages/websockets/sync/connection.py": 2791040669094103200,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/util.py": 5252158959761945519,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/parse.py": 2427019397934437210,
- "venv/lib/python3.13/site-packages/pandas/core/indexing.py": 15507869313676722071,
- "backend/src/core/auth/jwt.py": 11190403692794990534,
- "backend/git_repos/remote/test-repo.git/objects/ae/8d2f5dec5d421b2d6cc1eebaad6d2ef901a90d": 15877648001251681939,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_core_utils.py": 13248004771466837645,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.py": 4672871351134074735,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_endian.h": 2761502363895204652,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_asfreq.py": 6162659555626011770,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polyutils.pyi": 3841660741524427413,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite_e.py": 8912795372542950449,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/_mapping.py": 17519715342700184302,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_interp_fillna.py": 5530041283991655415,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_timegrouper.py": 276805119790266454,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/jupyter.py": 4446535289156468239,
- "venv/lib/python3.13/site-packages/httpcore/_backends/__init__.py": 15130871412783076140,
- "backend/src/api/routes/tasks.py": 13688847871690186483,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_finalize.py": 12539815426478689538,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/AUTHORS": 3558407083075395848,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__init__.py": 8811477458865810434,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo90.f90": 15981076495193915107,
- "venv/lib/python3.13/site-packages/numpy/ma/core.py": 338350463523585845,
- "venv/lib/python3.13/site-packages/websockets/sync/server.py": 7966978001578584901,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_extension.py": 4831602527247293866,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_3kcompat.h": 5377305123299457337,
- "venv/lib/python3.13/site-packages/tzlocal/win32.py": 1949985224569608978,
- "venv/lib/python3.13/site-packages/pip/_internal/network/session.py": 293771075394156394,
- "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_cat_accessor.py": 4304062895283374927,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/types.py": 356973910046950951,
- "venv/lib/python3.13/site-packages/pydantic/datetime_parse.py": 196119761382305574,
- "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_digest.py": 7988469818593853943,
- "venv/lib/python3.13/site-packages/pandas/core/indexers/utils.py": 5861072573716897447,
- "venv/lib/python3.13/site-packages/pygments/lexers/_asy_builtins.py": 1665617945818958781,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapped_collection.py": 11377280960650304531,
- "venv/lib/python3.13/site-packages/six.py": 948867418687428421,
- "frontend/src/types/backup.ts": 1741234034896689348,
- "venv/lib/python3.13/site-packages/smmap/mman.py": 9091562788592406032,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_generator.py": 14156412320760444199,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/RECORD": 11904769847385571600,
- "venv/lib/python3.13/site-packages/passlib/handlers/django.py": 66638338316838351,
- "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/METADATA": 14070889071949105584,
- "venv/lib/python3.13/site-packages/websockets/sync/router.py": 10335595955948355382,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_structures.py": 16375837477294135345,
- "venv/lib/python3.13/site-packages/rpds/__init__.pyi": 12037474523494903587,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_index.py": 10837492069089787028,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_formats.py": 10263085276270778330,
- "frontend/build/_app/immutable/nodes/24.lnfcaE4o.js": 4000891976750157851,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_dict_compat.py": 18196543090455290455,
- "backend/src/plugins/translate/__tests__/test_preview.py": 13201708414970983394,
- "frontend/src/lib/ui/PageHeader.svelte": 16740944781208407079,
- "backend/tests/test_translate_history.py": 4612852312641794586,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/challenge.py": 6388445104761482746,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_numpy.py": 4073641912755651877,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_values.py": 430620320423334461,
- "venv/lib/python3.13/site-packages/pygments/lexers/_lasso_builtins.py": 4006621424665751347,
- "venv/lib/python3.13/site-packages/pandas/api/executors/__init__.py": 16954693181142010028,
- "backend/src/core/superset_client/_layout_utils.py": 1180616937544609564,
- "backend/src/services/validation_service.py": 4040391162969506763,
- "venv/lib/python3.13/site-packages/ecdsa/test_eddsa.py": 1785854649532849946,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli/__init__.py": 12906995259233516197,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/_globals.pyi": 12839879732484756979,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/generate_umath_validation_data.cpp": 10880681943327843928,
- "venv/lib/python3.13/site-packages/pyasn1/type/error.py": 1479878696626082697,
- "venv/lib/python3.13/site-packages/jsonschema/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/test_asyncio.py": 2820168745710754136,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_util.py": 6573034224727513309,
- "venv/lib/python3.13/site-packages/pandas/core/computation/ops.py": 18250656489649699560,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_keys.py": 10813898277355150779,
- "venv/lib/python3.13/site-packages/PIL/ImageGrab.py": 11114379915762058868,
- "venv/lib/python3.13/site-packages/packaging/version.py": 13470993734108007779,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_other.py": 783701524491896337,
- "venv/lib/python3.13/site-packages/uvicorn/loops/asyncio.py": 16496916527760969173,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_string.py": 11422235699126032386,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_skew.py": 5276102682005383261,
- "venv/lib/python3.13/site-packages/starlette/middleware/base.py": 16850428285382256618,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_conversion.py": 9159276697339089788,
- "backend/src/core/superset_client/_dashboards_crud.py": 8682388093872211883,
- "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD": 12015288851076448205,
- "backend/src/services/maintenance/_banner_renderer.py": 17250656767428031478,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/http/flow_control.py": 4822804840057360506,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_crackfortran.py": 10278720705326601943,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/numpyconfig.h": 13339221870252345205,
- "venv/lib/python3.13/site-packages/numpy/random/_generator.cpython-313-x86_64-linux-gnu.so": 15625019745021657670,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py": 14350609278188982939,
- "venv/lib/python3.13/site-packages/pydantic/v1/error_wrappers.py": 5701679786078971939,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraypad.pyi": 12178766981280242620,
- "venv/lib/python3.13/site-packages/PIL/ImageFont.py": 15621336334706847865,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/parasail.py": 7758704230750989282,
- "frontend/build/_app/immutable/nodes/31.BylL8uTk.js": 7722395710886140688,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/quantile.py": 17341029201525362074,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_droplevel.py": 2071197388394658690,
- "venv/lib/python3.13/site-packages/_pytest/_version.py": 4890545974654141536,
- "venv/lib/python3.13/site-packages/secretstorage/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/__init__.py": 260774374497653876,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/bitgen.h": 12421210767114721499,
- "backend/src/api/routes/assistant/__init__.py": 16856916031113491888,
- "venv/lib/python3.13/site-packages/websockets/client.py": 5229500079651465772,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/markers.py": 5247208668583898949,
- "venv/lib/python3.13/site-packages/_pytest/_io/__init__.py": 1510478951261938348,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_bin_groupby.py": 14831211659124136806,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_ordered.py": 13827016781743929164,
- "venv/lib/python3.13/site-packages/urllib3/http2/__init__.py": 62108352209996836,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/deprecations.py": 7020540470348910770,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/base.py": 10514193453447954780,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_misc.py": 9190561773853901527,
- "backend/src/api/routes/dashboards/_router.py": 8641007051243802224,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/base.py": 13444129650880426353,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/astype_copy.pkl": 4470155972891419163,
- "backend/src/api/routes/git_schemas.py": 13106485698039147691,
- "venv/lib/python3.13/site-packages/httpx/_models.py": 6516278895118988231,
- "venv/lib/python3.13/site-packages/greenlet/__init__.py": 3447613556981242475,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sin.csv": 1443087417808027268,
- "venv/lib/python3.13/site-packages/PIL/EpsImagePlugin.py": 1824020964179364491,
- "frontend/build/_app/immutable/chunks/_Pf3rQig.js": 13183249556030654823,
- "venv/lib/python3.13/site-packages/httpx/_transports/asgi.py": 12335675489870745729,
- "venv/lib/python3.13/site-packages/pandas/io/formats/csvs.py": 17223598248259691292,
- "venv/lib/python3.13/site-packages/pygments/styles/rrt.py": 9490973359165080360,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_constructors.py": 9478848417896027917,
- "backend/src/core/utils/superset_context_extractor/_templates.py": 13945363390780279343,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/WHEEL": 16097436423493754389,
- "backend/src/core/auth/__tests__/test_auth.py": 9431831634377714320,
- "venv/lib/python3.13/site-packages/pygments/filters/__init__.py": 2992007913496948339,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlcipher.py": 11225173272050906977,
- "backend/src/api/routes/translate/_dictionary_routes.py": 5668671879929670471,
- "backend/src/services/__tests__/test_health_service.py": 3030803881074527861,
- "venv/lib/python3.13/site-packages/pyasn1/codec/ber/encoder.py": 8912119133548489544,
- "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/RECORD": 9803861100978586236,
- "venv/lib/python3.13/site-packages/pydantic/validate_call_decorator.py": 11130572937843915026,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.cpython-313-x86_64-linux-gnu.so": 12473903676666680134,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/__init__.py": 4014740126161973332,
- "venv/lib/python3.13/site-packages/numpy/random/__init__.py": 11732100564412485633,
- "venv/lib/python3.13/site-packages/pip/_internal/models/search_scope.py": 9282393652860589543,
- "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/RECORD": 9502524172853437600,
- "venv/lib/python3.13/site-packages/PIL/BlpImagePlugin.py": 7209218638257731375,
- "venv/lib/python3.13/site-packages/git/db.py": 6680123567509774609,
- "venv/lib/python3.13/site-packages/PIL/ImageDraw2.py": 13610162107593278891,
- "backend/src/core/auth/repository.py": 15675496219240601253,
- "venv/lib/python3.13/site-packages/idna/idnadata.py": 200840860629525970,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/subcomponents.py": 10365594934527289233,
- "venv/lib/python3.13/site-packages/pyasn1/type/namedtype.py": 1859990775875190116,
- "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_insert.py": 9195027887301180927,
- "backend/alembic/README": 17625003422504608299,
- "backend/src/api/routes/git/__init__.py": 16110760382314808406,
- "venv/lib/python3.13/site-packages/pip/_vendor/__init__.py": 11734104142988812647,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_manylinux.py": 12272275001961360101,
- "venv/lib/python3.13/site-packages/pandas/io/json/_normalize.py": 15938855324762935595,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_nonkeyword_arguments.py": 11676809974120007408,
- "frontend/src/routes/maintenance/+page.svelte": 5467232163447861441,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/azure.py": 13529763490186254462,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/combining.py": 1264860868414723829,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_html.py": 7732330576029516854,
- "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.py": 5570375156851166818,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_odfreader.py": 2760916559416783928,
- "venv/lib/python3.13/site-packages/charset_normalizer/__main__.py": 8887772289570078278,
- "frontend/build/_app/immutable/nodes/14.DQdp2XM0.js": 13691839198161634025,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_subclass.py": 11096337912872573314,
- "frontend/src/lib/stores/assistantChat.js": 16716458796178537885,
- "backend/src/plugins/translate/prompt_builder.py": 11939931262286362350,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/halffloat.h": 16913381775994652343,
- "backend/src/plugins/translate/__tests__/test_orthogonal_fixes.py": 12993935170413202399,
- "venv/lib/python3.13/site-packages/pandas/api/__init__.py": 1145864207387918302,
- "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.py": 4037074830103951000,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_packbits.py": 7592956764084658562,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npz": 9481735723557962988,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_tracing.py": 10227316489696807112,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/common.py": 10996276696597806957,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py": 5728866271812501558,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_equals.py": 18261810467289276844,
- "frontend/src/routes/settings/MigrationSettings.svelte": 12844990967512238268,
- "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.py": 1094797446508902066,
- "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.pyi": 12052895927933479005,
- "venv/lib/python3.13/site-packages/numpy/version.pyi": 5075382895829889457,
- "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/WHEEL": 16097436423493754389,
- "backend/src/api/routes/__tests__/conftest.py": 3768471623650776808,
- "frontend/src/routes/settings/SystemSettings.svelte": 17084926955388049976,
- "venv/lib/python3.13/site-packages/click/formatting.py": 6694583529073729642,
- "venv/lib/python3.13/site-packages/uvicorn/logging.py": 12858188863836778374,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_cat.py": 15988884721768567895,
- "venv/lib/python3.13/site-packages/pip/_internal/pyproject.py": 6155748929233245415,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py": 1359143503575245224,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_cumulative.py": 16283954014170928273,
- "venv/lib/python3.13/site-packages/dateutil/parser/__init__.py": 11377431154251655738,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_delitem.py": 16538190861492829338,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_searchsorted.py": 12074107109575676897,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_wrap.py": 17083394123203662880,
- "venv/lib/python3.13/site-packages/pygments/lexers/textedit.py": 14872291021083255414,
- "venv/lib/python3.13/site-packages/pygments/lexers/fortran.py": 6859638690245583968,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/METADATA": 9041650844081036822,
- "venv/lib/python3.13/site-packages/jeepney/low_level.py": 6546206679858571608,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayprint.py": 5912583751693302370,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_semicolon_split.py": 8153770165829451525,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg.py": 8023549900603235601,
- "frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte": 5121541182559165710,
- "backend/tests/test_maintenance_service.py": 15566750462318533004,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/revocation.py": 5718403706971163960,
- "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.cpython-313-x86_64-linux-gnu.so": 16963890771704942465,
- "venv/lib/python3.13/site-packages/pandas/util/_tester.py": 1033951890304257539,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.pyi": 1942236362568669510,
- "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/AUTHORS": 17022185907188244883,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/testing.pyi": 9317922890783549326,
- "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.py": 1590647503660777156,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/pyproject.py": 12684373765476932108,
- "venv/lib/python3.13/site-packages/numpy/ma/__init__.py": 214772578978182427,
- "venv/lib/python3.13/site-packages/pydantic/decorator.py": 6984214881365537811,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_retain_attributes.py": 16210262356844956764,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_memmap.py": 8709963808115492688,
- "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/events.py": 10224214051422678828,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/reporters.py": 10760889726586439724,
- "venv/lib/python3.13/site-packages/numpy/fft/_helper.py": 15906444100774706395,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resampler_grouper.py": 8388490036390951341,
- "venv/lib/python3.13/site-packages/websockets/legacy/auth.py": 16685128086396181286,
- "venv/lib/python3.13/site-packages/pandas/io/formats/html.py": 11849941990375030601,
- "venv/lib/python3.13/site-packages/pandas/io/html.py": 2727247063231114153,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/starlette/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/WHEEL": 2823347510103459191,
- "venv/lib/python3.13/site-packages/pandas/_libs/indexing.pyi": 90995502095752726,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py": 6152202474302791232,
- "venv/lib/python3.13/site-packages/PIL/DdsImagePlugin.py": 10646832373516499548,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_html.py": 12040484325988635032,
- "venv/lib/python3.13/site-packages/yaml/scanner.py": 8554164423030397366,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/METADATA": 8985010079096958084,
- "venv/lib/python3.13/site-packages/websockets/streams.py": 15786581670248099415,
- "venv/lib/python3.13/site-packages/pycparser/yacctab.py": 18018314512916353707,
- "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/METADATA": 317417773265681256,
- "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/RECORD": 15574202654585730126,
- "venv/lib/python3.13/site-packages/pygments/styles/algol.py": 3040373291664740876,
- "frontend/src/routes/settings/LlmSettings.svelte": 10881646244972773692,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_scalar_compat.py": 10534925655070162459,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_bus_messages.py": 4323093138307306385,
- "frontend/src/routes/admin/roles/+page.svelte": 7687872545536151950,
- "backend/src/core/superset_client/_charts.py": 15609724925814918066,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/modules.pyi": 14176187662591164602,
- "backend/src/core/migration/archive_parser.py": 16510017196974398795,
- "venv/lib/python3.13/site-packages/httpcore/_async/http11.py": 7565741048880549265,
- "venv/lib/python3.13/site-packages/passlib/handlers/des_crypt.py": 15304795681178011265,
- "backend/src/plugins/git_plugin.py": 14230780209237230648,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/tools.py": 16466182352694741629,
- "examples/maintenance-api-python.py": 18279360934407602079,
- "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/RECORD": 12733654377842895588,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/conftest.py": 16886862391161243448,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numba.py": 18148155441554555618,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/plugin.py": 16042078006552521613,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.pyi": 1830368009811266890,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hmac.py": 18132740541139891824,
- "venv/lib/python3.13/site-packages/numpy/random/_pcg64.cpython-313-x86_64-linux-gnu.so": 5759445712745875888,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsin.csv": 1665171675551692225,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_parameter.py": 15173522343126004527,
- "venv/lib/python3.13/site-packages/pip/_internal/__init__.py": 7060345458485901709,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/box.py": 14303526978791498662,
- "venv/lib/python3.13/site-packages/dateutil/utils.py": 7067026915090881998,
- "venv/lib/python3.13/site-packages/dateutil/tz/tz.py": 5258008267965780817,
- "venv/lib/python3.13/site-packages/pygments/styles/pastie.py": 15784474766258831882,
- "venv/lib/python3.13/site-packages/httpcore/_async/__init__.py": 491192949420297153,
- "frontend/build/_app/immutable/nodes/25.DDfuZIEE.js": 7817480037775221276,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_xlrd.py": 14430937200583666658,
- "venv/lib/python3.13/site-packages/tzlocal/__init__.py": 11017072814026497364,
- "venv/lib/python3.13/site-packages/h11/_abnf.py": 10456996134895429201,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/__init__.py": 15487893533770969571,
- "frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte": 8694552424163588390,
- "venv/lib/python3.13/site-packages/smmap/buf.py": 18231775424238352734,
- "venv/lib/python3.13/site-packages/websockets/connection.py": 5168795926684067030,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/direct_url_helpers.py": 6075890513530296650,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/highlighter.py": 10615901258492570740,
- "venv/lib/python3.13/site-packages/pillow.libs/libpng16-4a38ea05.so.16.53.0": 13136089038268964667,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_style.py": 10405592363651914796,
- "venv/lib/python3.13/site-packages/pandas/api/interchange/__init__.py": 181911269762882069,
- "frontend/build/_app/immutable/chunks/BAEbOLv3.js": 18043792224008034479,
- "backend/src/api/__init__.py": 5287505122015708040,
- "backend/src/plugins/translate/orchestrator_lang_stats.py": 5713612003349083382,
- "venv/lib/python3.13/site-packages/numpy/_core/shape_base.py": 3996519099530770308,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py": 8981142329261965538,
- "venv/lib/python3.13/site-packages/_pytest/setupplan.py": 7496801885995567141,
- "venv/lib/python3.13/site-packages/fastapi/utils.py": 15402403831700548944,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_constructors.py": 13890224577680389718,
- "venv/lib/python3.13/site-packages/numpy/lib/__init__.pyi": 1537495515469182226,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_style.py": 6849613206971398029,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_online.py": 11850497659869773510,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_query_eval.py": 17613800806748649144,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_numpy.py": 9663734591667845940,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_ops.py": 3875181889032080505,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/default_comparator.py": 47118577003622736,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/endpoints.py": 18334891787808122725,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/array.py": 13840510238256626632,
- "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.py": 6205675182996213576,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/floating.py": 1215586266958421991,
- "backend/src/services/clean_release/report_builder.py": 14118825155100404762,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_model_construction.py": 694471028676746110,
- "venv/lib/python3.13/site-packages/numpy/fft/tests/test_helper.py": 5362180645056413158,
- "frontend/src/components/tasks/TaskResultPanel.svelte": 2978429516796744791,
- "venv/lib/python3.13/site-packages/pydantic/v1/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/httpx/_transports/default.py": 8391302827983907910,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py": 14995426099932276090,
- "venv/lib/python3.13/site-packages/httpcore/_backends/base.py": 5491727479625093183,
- "backend/src/api/routes/__tests__/test_dashboards.py": 3130878778754818679,
- "backend/src/services/llm_provider.py": 7079748167598543116,
- "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/__init__.py": 16416360448593978041,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/__main__.py": 487896753130729554,
- "venv/lib/python3.13/site-packages/pandas/core/computation/pytables.py": 16326122536715961388,
- "venv/lib/python3.13/site-packages/pandas/tseries/__init__.py": 2648641118117738895,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/__init__.py": 3795218871212151351,
- "venv/lib/python3.13/site-packages/passlib/handlers/scrypt.py": 10089372287597257402,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_as_unit.py": 4283520188709399244,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_file_handling.py": 732772718210067599,
- "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/h11/_connection.py": 6971907312737339559,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_categorical.py": 9615571808720893016,
- "venv/lib/python3.13/site-packages/pygments/styles/bw.py": 869630132791421268,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_searchsorted.py": 11161416745923343741,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_numba.py": 1548992314517942530,
- "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.pyi": 362674842164060822,
- "frontend/src/lib/toasts.js": 17626443524470260846,
- "frontend/src/lib/components/ui/MultiSelect.svelte": 1475503303018683038,
- "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/licenses/LICENSE": 5757922580822401219,
- "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.py": 13115032674230220791,
- "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/_gen_files.py": 6273314671315377131,
- "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.py": 3646474165295296669,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_iterator.py": 13869355993837330406,
- "venv/lib/python3.13/site-packages/pygments/lexers/whiley.py": 218468511185731869,
- "venv/lib/python3.13/site-packages/urllib3/util/proxy.py": 17667887856427739069,
- "venv/lib/python3.13/site-packages/gitdb/pack.py": 7828244200815444166,
- "frontend/src/routes/settings/automation/+page.svelte": 13199339263146300897,
- "frontend/src/routes/migration/mappings/+page.svelte": 1070046408170579565,
- "frontend/src/components/PasswordPrompt.svelte": 6647880254998908582,
- "venv/lib/python3.13/site-packages/pygments/lexers/macaulay2.py": 8022891778577314212,
- "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.py": 6142062990691556076,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_round.py": 14996007456708990295,
- "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.pyi": 18290764713161282980,
- "venv/lib/python3.13/site-packages/pluggy/_version.py": 7195758686717994475,
- "venv/lib/python3.13/site-packages/anyio/abc/_eventloop.py": 2023190981288767991,
- "venv/lib/python3.13/site-packages/attr/converters.py": 5179615793507170642,
- "venv/lib/python3.13/site-packages/passlib/handlers/pbkdf2.py": 16686685453577026643,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_concat.py": 4472503149811617440,
- "venv/lib/python3.13/site-packages/sqlalchemy/connectors/pyodbc.py": 4146960201984489604,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/conftest.py": 13798335354961261346,
- "backend/src/services/git/_base.py": 18009686862342149948,
- "backend/tests/test_deprecation_audit_fixes.py": 17902995210831708431,
- "backend/tests/test_translate_jobs.py": 14073962595360719355,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/test_threading.py": 6656552495241857519,
- "venv/lib/python3.13/site-packages/anyio/to_thread.py": 12767326212338028587,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/__init__.py": 12849371269359608058,
- "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_datetime.py": 3499461736474530062,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE": 4274653168153720331,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_categorical.py": 1329115818264527103,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_constructors.py": 2439700578107653984,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/period.py": 1181348384346239378,
- "backend/src/core/utils/dataset_mapper.py": 3978140070131451501,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/unicode_comment.f90": 11326797716215117266,
- "venv/lib/python3.13/site-packages/pygments/lexers/phix.py": 16775285097768256238,
- "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.pyi": 7171810177801103765,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/url.py": 9692934100602135106,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufuncs.pyi": 14995898537484305307,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pillow.libs/libwebp-d8b9687f.so.7.2.0": 116215608212382352,
- "venv/lib/python3.13/site-packages/authlib/jose/util.py": 14843923624043422219,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_comparison.py": 4611207880323503098,
- "venv/lib/python3.13/site-packages/git/refs/tag.py": 9979537867501757110,
- "frontend/build/_app/immutable/chunks/Ck4a7ANl.js": 3561562300210641559,
- "venv/lib/python3.13/site-packages/starlette/requests.py": 4582424111350387010,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_quarter.py": 6795026338946382805,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_os.h": 7883047506449405400,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/httpx/_exceptions.py": 18399489130669465891,
- "venv/lib/python3.13/site-packages/numpy/rec/__init__.py": 7467092880535460658,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/models.py": 11521700876708601977,
- "backend/src/api/routes/dashboards/__init__.py": 14480706693953038818,
- "venv/pyvenv.cfg": 2513607356761047446,
- "venv/lib/python3.13/site-packages/click/_textwrap.py": 14586282603215052310,
- "venv/lib/python3.13/site-packages/httpcore/_trace.py": 9576253018891841832,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/mock.py": 14010776046610111182,
- "backend/src/api/routes/translate/_router.py": 18140665710457768874,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/resource_protector.py": 4823504113176750140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_mask.py": 9654897363729130542,
- "venv/lib/python3.13/site-packages/pygments/lexers/robotframework.py": 11507713622179102496,
- "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/METADATA": 12747626683405487434,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_concatenate_chunks.py": 9693420220003544490,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_index_equal.py": 10617870815989304510,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/checks.pyx": 13187505236986855177,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_store.py": 1500300322083708794,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/_psycopg_common.py": 4111797647365870137,
- "venv/lib/python3.13/site-packages/pygments/lexers/amdgpu.py": 17249439604111838979,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/default_styles.py": 4469204219504675080,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ma.pyi": 6467636381637286867,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_arrayobject.py": 9578555381494297966,
- "venv/lib/python3.13/site-packages/httpx/_auth.py": 1283189552342958900,
- "venv/lib/python3.13/site-packages/pandas/_config/config.py": 1494288055210911451,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/getitem.py": 556339939822508169,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/test_runtime.py": 12534621594420844770,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_reductions.py": 1713831062142840146,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/aiomysql.py": 12999962380333482189,
- "frontend/build/_app/immutable/entry/app.B3VIvO3J.js": 430434855117608941,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/modules.py": 9023244176010175562,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_re.py": 1296579393600719224,
- "backend/src/api/routes/__tests__/test_reports_detail_api.py": 8519050847848949612,
- "venv/lib/python3.13/site-packages/pygments/styles/lightbulb.py": 12433916113773598760,
- "venv/lib/python3.13/site-packages/pandas/core/window/__init__.py": 15180240812077877933,
- "venv/lib/python3.13/site-packages/pandas/util/_print_versions.py": 15326663505771588740,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/frozen.py": 1419685664276640120,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_array.f90": 9711940829820746513,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_format.py": 9331389900588353667,
- "venv/lib/python3.13/site-packages/httpcore/_models.py": 2501866419898326733,
- "venv/lib/python3.13/site-packages/pygments/lexers/_mysql_builtins.py": 16087227298679432006,
- "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pydantic/warnings.py": 5142352784799639092,
- "backend/src/services/clean_release/__tests__/test_preparation_service.py": 1135205964675811608,
- "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.py": 14446508217220482719,
- "backend/git_repos/remote/test-repo.git/objects/6a/f2b28e314c04fb4e03476c12d6491213591512": 4526311953587849385,
- "venv/lib/python3.13/site-packages/numpy/lib/introspect.pyi": 12239924839764265507,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/unix.py": 13808187640638677050,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/aioodbc.py": 12704729841432715246,
- "venv/lib/python3.13/site-packages/pygments/lexers/_postgres_builtins.py": 2383906454995727700,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp": 8819301638282185623,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/range.py": 3838277376774246164,
- "venv/lib/python3.13/site-packages/fastapi/security/__init__.py": 1345944646061334046,
- "venv/lib/python3.13/site-packages/numpy/_core/function_base.py": 5676611841071163854,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py": 3072714633272661847,
- "examples/maintenance-api-bash.sh": 674396824183793987,
- "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/WHEEL": 8954358347596196608,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_lexsort.py": 10394832796613968484,
- "backend/src/api/routes/assistant/_dataset_review.py": 4389080462745572364,
- "venv/lib/python3.13/site-packages/pygments/lexers/unicon.py": 1155454077052833821,
- "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/apps.py": 4219758952914498116,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/npyio.pyi": 15811156298637131744,
- "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.py": 12796890117561096360,
- "venv/lib/python3.13/site-packages/pandas/_libs/pandas_parser.cpython-313-x86_64-linux-gnu.so": 18056339336364727359,
- "venv/lib/python3.13/site-packages/packaging/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/__version__.py": 14138134075118474134,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/__init__.py": 8632038387100622009,
- "venv/lib/python3.13/site-packages/_pytest/unittest.py": 10848803633530338204,
- "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/PIL/ImageEnhance.py": 3218405223202808764,
- "frontend/src/lib/stores/taskDrawer.js": 16349119158364586930,
- "frontend/e2e/tests/migration.e2e.js": 8226804598977954559,
- "frontend/tests/maintenance-store.test.ts": 7211673236234440419,
- "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/WHEEL": 11630459739183915695,
- "backend/src/plugins/translate/dictionary_correction.py": 10188420840444526264,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/modes.py": 6832635056228445650,
- "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.pyi": 6796322258258182775,
- "venv/lib/python3.13/site-packages/pandas/core/missing.py": 13332302791063948992,
- "venv/lib/python3.13/site-packages/httpx/_client.py": 1063593889704982038,
- "venv/lib/python3.13/site-packages/PIL/FitsImagePlugin.py": 618556384932056120,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/base.py": 14908084548919567658,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/topological.py": 11586868018611359415,
- "venv/lib/python3.13/site-packages/numpy/tests/test_configtool.py": 8208415015478205502,
- "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_py.py": 6428078990080243608,
- "venv/lib/python3.13/site-packages/keyring/credentials.py": 14515496037842724455,
- "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/RECORD": 3205266407680661753,
- "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth2_client.py": 6742098857947604729,
- "venv/lib/python3.13/site-packages/passlib/handlers/bcrypt.py": 8125664010268654055,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/parse.py": 819235411736647763,
- "venv/lib/python3.13/site-packages/authlib/jose/__init__.py": 317573635113539563,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_overrides.py": 92685611709898742,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/date/array.py": 18073740473413382768,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/expression.py": 1248029135284283479,
- "venv/lib/python3.13/site-packages/PIL/PcxImagePlugin.py": 1691405132377495336,
- "venv/lib/python3.13/site-packages/dateutil/tzwin.py": 5149446703746204349,
- "venv/lib/python3.13/site-packages/pygments/styles/friendly.py": 13799024964803741891,
- "venv/lib/python3.13/site-packages/pygments/formatters/groff.py": 6480830447984073574,
- "venv/bin/fastapi": 12400009726251862770,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/mongodb.py": 5310116401542377882,
- "venv/lib/python3.13/site-packages/pydantic/types.py": 785880062468926292,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi": 2777456956260371820,
- "venv/lib/python3.13/site-packages/numpy/ma/__init__.pyi": 1855615156913010107,
- "venv/lib/python3.13/site-packages/requests/utils.py": 17045260098091371478,
- "venv/lib/python3.13/site-packages/git/objects/base.py": 11498407361286170399,
- "venv/lib/python3.13/site-packages/pygments/lexers/_lilypond_builtins.py": 1766946089314631488,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/filetypes.py": 4415340223268174913,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/chararray.pyi": 17340224970247832290,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_add_prefix_suffix.py": 4815518357936092237,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_extint128.py": 11074657869101074458,
- "venv/lib/python3.13/site-packages/pydantic/v1/datetime_parse.py": 10467114625921924095,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_mixins.py": 12351373879926460719,
- "venv/lib/python3.13/site-packages/git/objects/commit.py": 12317865358846331802,
- "venv/lib/python3.13/site-packages/dateutil/_version.py": 8279235793001245767,
- "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/RECORD": 1556051687830913019,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/char.f90": 12203871998988759364,
- "venv/lib/python3.13/site-packages/sqlalchemy/event/api.py": 987321343916500337,
- "frontend/postcss.config.js": 5714274776976071678,
- "venv/lib/python3.13/site-packages/pandas/util/__init__.py": 4070574585004336241,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/__init__.py": 2791238481813240414,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/_natype.py": 12013743717306900860,
- "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/_mapping.py": 11752660241391232497,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_version.pyi": 18093228021414910594,
- "venv/lib/python3.13/site-packages/numpy/_configtool.py": 2946953194004101078,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/converter.py": 9041278869295701566,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_base.py": 15292769510056833117,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_console.py": 11657469008721907972,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/memmap.pyi": 2834143910417841603,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_reduction.py": 2671872764983553906,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/http/auto.py": 15947958974558543657,
- "venv/lib/python3.13/site-packages/numpy/lib/format.py": 14971167445246135440,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_regression.py": 16266600037241221681,
- "venv/lib/python3.13/site-packages/numpy/lib/array_utils.pyi": 14646405559193539455,
- "venv/lib/python3.13/site-packages/numpy/ma/mrecords.pyi": 8945514863366384484,
- "venv/lib/python3.13/site-packages/pygments/lexers/_usd_builtins.py": 8671446144574174964,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/__init__.py": 237070345717942041,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_concat.py": 1351478313334379336,
- "frontend/src/routes/migration/+page.svelte": 9446845081074850594,
- "frontend/src/components/MappingTable.svelte": 16339628752309005366,
- "frontend/build/_app/immutable/nodes/10.D79erIQG.js": 35496247013741914,
- "frontend/src/routes/datasets/review/ReviewWorkspaceRightRail.svelte": 13437011381072252917,
- "frontend/build/_app/immutable/nodes/37.qmsMPGgB.js": 3325998617833460603,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_delitem.py": 14336697139511118920,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/queue.py": 1289234691048379395,
- "venv/lib/python3.13/site-packages/pandas/tests/api/test_api.py": 13385690673368400635,
- "backend/src/core/superset_profile_lookup.py": 7466572583388472449,
- "venv/lib/python3.13/site-packages/pandas/tests/test_downstream.py": 5635510753354256507,
- "venv/lib/python3.13/site-packages/gitdb/test/test_example.py": 3039934065817753241,
- "venv/lib/python3.13/site-packages/authlib/integrations/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.pyi": 15420142722808118826,
- "venv/lib/python3.13/site-packages/pygments/lexers/ncl.py": 14838368780033177943,
- "venv/lib/python3.13/site-packages/pygments/lexers/hare.py": 8693002231020751711,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_groupby.py": 12709199432838648700,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/pkg_resources.py": 14271077832999370068,
- "venv/lib/python3.13/site-packages/numpy/core/defchararray.py": 11371045148957547088,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_numeric.py": 17391095502314929042,
- "venv/lib/python3.13/site-packages/numpy/random/_pcg64.pyi": 14785496840737986355,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/parameters.py": 247312908510013930,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/authorization_server.py": 2913800420669417152,
- "venv/lib/python3.13/site-packages/dotenv/__main__.py": 16883579879172186355,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cython.py": 14695721638531081573,
- "venv/lib/python3.13/site-packages/passlib/utils/des.py": 2650106381178222229,
- "venv/lib/python3.13/site-packages/pandas/plotting/_core.py": 6766059152026241747,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimelike.py": 4356700619632833878,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/categorical.py": 15993211255162930859,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_string.py": 13234624995755549329,
- "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/METADATA": 4954909612926293404,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_dtypes.py": 481191723198819568,
- "venv/lib/python3.13/site-packages/pygments/token.py": 6987328478153445584,
- "backend/src/services/reports/normalizer.py": 13510015789619559475,
- "backend/src/plugins/translate/preview_response_parser.py": 15690759478655959205,
- "backend/tests/test_datasets.py": 9766141609165223604,
- "backend/git_repos/remote/test-repo.git/objects/ed/0432f88f5f7d95b26ecde34345abe741dd9db2": 13426916511127204463,
- "venv/lib/python3.13/site-packages/jeepney/auth.py": 10565040329507087892,
- "venv/lib/python3.13/site-packages/pandas/core/tools/datetimes.py": 13313374952742129866,
- "venv/lib/python3.13/site-packages/starlette/middleware/gzip.py": 4321371046149637632,
- "venv/lib/python3.13/site-packages/pandas/compat/pyarrow.py": 13693379998785127538,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/errors.py": 14634768861119075506,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_cython.py": 2933400021016349431,
- "venv/lib/python3.13/site-packages/pygments/styles/staroffice.py": 11694998942433220413,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/install/__init__.py": 10456333337205488584,
- "venv/lib/python3.13/site-packages/pygments/lexers/mojo.py": 8616283481592061285,
- "venv/lib/python3.13/site-packages/pygments/lexers/mime.py": 7768464764849718825,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/util.py": 955993052529739164,
- "backend/src/api/routes/maintenance/_schemas.py": 16377052636841886346,
- "backend/alembic/versions/c4a3a2f74bfe_add_missing_columns_needs_review_.py": 4320606555167902916,
- "venv/lib/python3.13/site-packages/pydantic/v1/env_settings.py": 6194387033830177219,
- "venv/lib/python3.13/site-packages/starlette/middleware/cors.py": 11384893784314197864,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arrow_interface.py": 5231449831607036031,
- "venv/lib/python3.13/site-packages/certifi/core.py": 7472627735517449185,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_qcut.py": 8972418112914954758,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/processors.py": 4817637175145012571,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_convert_dtypes.py": 13612212066710266457,
- "venv/lib/python3.13/site-packages/referencing/_core.py": 14744795336121513230,
- "venv/lib/python3.13/site-packages/tzlocal/unix.py": 995019116408448073,
- "venv/lib/python3.13/site-packages/pydantic/v1/typing.py": 13467331592583800299,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_cell_widths.py": 5724379364993806351,
- "venv/lib/python3.13/site-packages/pandas/core/sorting.py": 689057022713741051,
- "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.py": 7658234162211356265,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/ddl.py": 5006132143435653867,
- "venv/lib/python3.13/site-packages/PIL/QoiImagePlugin.py": 17663704273100331654,
- "venv/lib/python3.13/site-packages/git/repo/fun.py": 9019364012746153312,
- "venv/lib/python3.13/site-packages/rsa/cli.py": 1753949198467694190,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/resolver.py": 9931394693284776391,
- "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/licenses/LICENSE": 2345070715845618109,
- "venv/lib/python3.13/site-packages/passlib/handlers/phpass.py": 16489430001449160264,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_log_render.py": 18076931145915444473,
- "venv/lib/python3.13/site-packages/keyring/backends/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/fastapi/openapi/utils.py": 9058442333718187759,
- "venv/lib/python3.13/site-packages/itsdangerous/encoding.py": 205863946173486958,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/resource_protector.py": 11539718751174980004,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/base.py": 1170652622104554892,
- "venv/lib/python3.13/site-packages/rsa/core.py": 13203947234024924497,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA_py.py": 2494967094400350388,
- "venv/lib/python3.13/site-packages/numpy/_core/_simd.pyi": 13553578040186939249,
- "venv/lib/python3.13/site-packages/pandas/core/tools/numeric.py": 8510988912136285022,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_openpyxl.py": 9542840527483618681,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/bitwise_ops.pyi": 15598239133239520456,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_transform.py": 5674175311567817854,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_series.py": 2980850649986213051,
- "venv/lib/python3.13/site-packages/httpcore/_utils.py": 3255581092836273826,
- "venv/lib/python3.13/site-packages/fastapi/security/open_id_connect_url.py": 3502444317759870079,
- "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/licenses/LICENSE.rst": 5960743202700406649,
- "venv/lib/python3.13/site-packages/uvicorn/middleware/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/random/_common.pyi": 5094115692952609118,
- "venv/lib/python3.13/site-packages/pygments/styles/default.py": 13992125975366109635,
- "venv/lib/python3.13/site-packages/pygments/lexers/smalltalk.py": 6113431347120223592,
- "frontend/e2e/tests/enterprise-clean-setup.e2e.js": 3554788137273369867,
- "backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py": 7304392396276280230,
- "venv/lib/python3.13/site-packages/_pytest/config/compat.py": 13175516717549204627,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/RECORD": 7844752443022514265,
- "venv/lib/python3.13/site-packages/urllib3/py.typed": 12220177918227495093,
- "frontend/e2e/tests/git.e2e.js": 11932601692145051382,
- "backend/src/api/routes/settings.py": 7176893095762662218,
- "backend/src/plugins/translate/service_inline_correction.py": 5367849290612412207,
- "backend/tests/services/clean_release/test_compliance_execution_service.py": 9658943217379916757,
- "venv/lib/python3.13/site-packages/numpy/_core/_dtype.pyi": 17662618580381221543,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_isocalendar.py": 5704842983090753914,
- "venv/lib/python3.13/site-packages/pycparser/plyparser.py": 5251740466238035035,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_timezones.py": 15157687716502574038,
- "venv/lib/python3.13/site-packages/_pytest/assertion/rewrite.py": 2425990712758915831,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/__init__.py": 16029653645350087968,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90": 12296500845667555672,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_join.py": 17508073052750406350,
- "backend/git_repos/remote/test-repo.git/info/exclude": 6403833611826357791,
- "venv/lib/python3.13/site-packages/secretstorage/__init__.py": 4535964275649588672,
- "venv/lib/python3.13/site-packages/pandas/core/flags.py": 4690844374637430013,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_astype.py": 16700461036658228009,
- "venv/lib/python3.13/site-packages/numpy/__config__.py": 15794735729525094396,
- "venv/lib/python3.13/site-packages/_pytest/warning_types.py": 10695097290648045427,
- "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__init__.py": 2833016678144975576,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/base.cpython-313-x86_64-linux-gnu.so": 8335798324308957127,
- "venv/lib/python3.13/site-packages/numpy/_core/_asarray.pyi": 3940937389249665490,
- "venv/lib/python3.13/site-packages/charset_normalizer/models.py": 9917300217816275821,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.pyi": 2700568594438441246,
- "frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js": 10301023261856534116,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_api_info.py": 16491629653122827368,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/status.py": 2214590120238144582,
- "venv/lib/python3.13/site-packages/httpx/_decoders.py": 14478643473006178492,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/scoping.py": 18223258186431020473,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_multiarray.py": 3592197154340095431,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo77.f": 16250175448122328648,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/conftest.py": 9673372914396625461,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/asyncmy.py": 11808138763443525443,
- "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/LICENSE": 16510279186416777136,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_contextvars.py": 6077482318964702132,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_chained_assignment_deprecation.py": 7694137945143129474,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_stmts.f90": 6123192245816905092,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_api.py": 1910541672533352625,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_function.py": 14142346897145169685,
- "venv/lib/python3.13/site-packages/pygments/lexers/numbair.py": 17382646010399794697,
- "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/ext.py": 15699809032725838985,
- "venv/lib/python3.13/site-packages/pandas/_libs/hashing.pyi": 5241441378073929968,
- "venv/lib/python3.13/site-packages/yaml/_yaml.cpython-313-x86_64-linux-gnu.so": 16990140871649227895,
- "venv/lib/python3.13/site-packages/pygments/lexers/nix.py": 15050086330545600356,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi": 1065808244870331598,
- "backend/src/services/clean_release/repositories/audit_repository.py": 1431160646630812395,
- "venv/lib/python3.13/site-packages/pandas/io/parsers/readers.py": 7899068668225389287,
- "backend/src/plugins/translate/orchestrator_runner.py": 6903994426268521649,
- "venv/lib/python3.13/site-packages/attr/_next_gen.py": 16353246941851015420,
- "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/METADATA": 15225661995655327539,
- "venv/lib/python3.13/site-packages/passlib/handlers/roundup.py": 3844280972451753019,
- "backend/src/services/clean_release/__tests__/test_policy_engine.py": 7872293927249163831,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_logical.py": 6242457515917145500,
- "venv/lib/python3.13/site-packages/cffi/_cffi_include.h": 13094899814611950155,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append.py": 13152738905565588661,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.pyi": 16164841755339571545,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_formats.py": 3525283725314253763,
- "venv/lib/python3.13/site-packages/pydantic_settings/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval.py": 1228451182688768814,
- "venv/lib/python3.13/site-packages/passlib/apps.py": 4633269405597895766,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_cut.py": 7800833253841657380,
- "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/METADATA": 2810323639884879396,
- "venv/lib/python3.13/site-packages/pygments/lexers/_sql_builtins.py": 5906655440517434734,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.pyi": 11967691665766452312,
- "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/METADATA": 10810011740984652381,
- "venv/lib/python3.13/site-packages/annotated_types/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/METADATA": 10707390829735099042,
- "venv/lib/python3.13/site-packages/numpy/_core/_internal.pyi": 6840742333427164920,
- "venv/lib/python3.13/site-packages/pyasn1/codec/cer/decoder.py": 17559787396729804535,
- "venv/lib/python3.13/site-packages/bcrypt/py.typed": 15130871412783076140,
- "backend/tests/test_translate_scheduler.py": 9870953183282058719,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nlargest.py": 14518132768753249360,
- "venv/lib/python3.13/site-packages/uvicorn/loops/uvloop.py": 5385425357504191161,
- "venv/lib/python3.13/site-packages/bcrypt/__about__.py": 11196369962175692786,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/connection.py": 5582413226288987808,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/cache.py": 15037055977924167732,
- "venv/lib/python3.13/site-packages/numpy/lib/scimath.py": 7616377937400918724,
- "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/RECORD": 11111103193315065053,
- "venv/lib/python3.13/site-packages/pygments/lexers/ambient.py": 18106929781201758080,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_allocator.hpp": 11041111583319491309,
- "frontend/src/routes/datasets/StatsBar.svelte": 4241697609925045735,
- "frontend/src/lib/stores/__tests__/test_taskDrawer.js": 14849615218402542643,
- "backend/src/models/dataset_review_pkg/_clarification_models.py": 10650387708191883580,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cos.csv": 12896264205153363031,
- "venv/lib/python3.13/site-packages/pygments/styles/friendly_grayscale.py": 16840106759769837649,
- "venv/lib/python3.13/site-packages/pygments/lexers/ldap.py": 17455983150181177257,
- "venv/bin/pyrsa-encrypt": 5858278204727417482,
- "frontend/build/_app/immutable/chunks/C8K-NfB8.js": 522730246953022577,
- "backend/tests/test_smoke_app.py": 15091189356064171349,
- "venv/lib/python3.13/site-packages/_pytest/config/findpaths.py": 7867603756389940562,
- "frontend/src/lib/components/translate/ScheduleConfig.svelte": 9548866160759602637,
- "venv/lib/python3.13/site-packages/pip/_internal/models/wheel.py": 10473287225032326206,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh15035.f": 13126319439858352711,
- "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.py": 2234931733687557433,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/tools.py": 6437315459200419827,
- "backend/src/app.py": 4335519376703786949,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_between.py": 337429135216881486,
- "backend/src/services/reports/__tests__/test_report_normalizer.py": 5081647081006613913,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.py": 1948707545068786,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_time_series.py": 5205199092955498507,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_indexing.py": 9862204223281834360,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_serializers.py": 12077180322353709930,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/__init__.py": 11850945878149145990,
- "venv/lib/python3.13/site-packages/pandas/core/resample.py": 13814298871925341617,
- "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/WHEEL": 8600534672961461758,
- "venv/lib/python3.13/site-packages/pandas/core/ops/invalid.py": 10186546927135277579,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/scoping.py": 17216492046645992674,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/plugin.py": 18006138132596504101,
- "venv/lib/python3.13/site-packages/starlette/middleware/errors.py": 1337979724602864440,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/_arrow_string_mixins.py": 16862663427780315543,
- "venv/lib/python3.13/site-packages/pygments/lexers/shell.py": 3842338968014057744,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.pyi": 17469792319379909312,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_style.py": 14810883299259169406,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_datetime_index.py": 15448494560143263150,
- "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/_pytest/_io/terminalwriter.py": 16852767249156780980,
- "venv/lib/python3.13/site-packages/_pytest/fixtures.py": 1442767529726551116,
- "venv/lib/python3.13/site-packages/click/_compat.py": 14451519072991457993,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_direct.py": 12680113511641199070,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/content": 12465123883296161860,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/dtype.pyi": 12178008080078679769,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_no_deprecated_api.h": 7896028550808252043,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_unsupported.py": 9115440166074553860,
- "venv/lib/python3.13/site-packages/numpy/core/_utils.py": 14108063453670701289,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_missing.py": 3991199131191840903,
- "venv/lib/python3.13/site-packages/jeepney/tests/secrets_introspect.xml": 10717038359151125278,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_core_functionalities.py": 10449747865888948579,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_repr.py": 1758478941817868344,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/names.py": 705261158040926128,
- "venv/lib/python3.13/site-packages/charset_normalizer/utils.py": 11724147997933584095,
- "venv/lib/python3.13/site-packages/pandas/io/parquet.py": 14415622950469421518,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/__init__.py": 1856412417337875350,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/autocompletion.py": 7651919329635563739,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_smoke.py": 7476432112986643847,
- "backend/test_app.db": 2486636812009447051,
- "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD": 17594742868855466393,
- "venv/lib/python3.13/site-packages/numpy/_utils/__init__.pyi": 13530522898409268883,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval_new.py": 3893421355544517336,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi": 9405122752084210696,
- "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.pyi": 13208953770241664384,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iat.py": 3570464615146398178,
- "frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js": 3774268544046391936,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators_v1.py": 16723743964226526155,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/extending.py": 9859383893070793914,
- "frontend/src/lib/components/translate/TranslationPreview.svelte": 9514416214545061268,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/poolmanager.py": 5071697837617938064,
- "venv/lib/python3.13/site-packages/numpy/__init__.pxd": 13527602429695748857,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_cpp_exception.py": 11851283355840567373,
- "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/click/core.py": 16793133181718891193,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multithreading.py": 12547048606098186681,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.APACHE": 8359973023624924624,
- "backend/src/core/superset_client/_dashboards_write.py": 1899473134078622908,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.pyi": 10947021928755741366,
- "venv/lib/python3.13/site-packages/PIL/PcdImagePlugin.py": 922809545463280224,
- "frontend/build/_app/immutable/assets/9.tn0RQdqM.css": 15130871412783076140,
- "venv/lib/python3.13/site-packages/anyio/lowlevel.py": 11919467357746648592,
- "venv/lib/python3.13/site-packages/websockets/extensions/base.py": 2457233337788783873,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period.py": 9715843209581883915,
- "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft_umath.cpython-313-x86_64-linux-gnu.so": 16443444849116065961,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/queue.py": 7820997545569991670,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numeric.py": 5627177940393829333,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_read_fwf.py": 13684564756628524738,
- "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_deprecations.py": 16367195310156359251,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_concat.py": 3788461606817482165,
- "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/METADATA": 2053484635654179443,
- "venv/lib/python3.13/site-packages/anyio/abc/__init__.py": 11428476337116642278,
- "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/licenses/COPYING": 14459782230785388765,
- "frontend/src/lib/components/translate/TermCorrectionPopup.svelte": 2290415616531498089,
- "venv/lib/python3.13/site-packages/pyasn1/type/opentype.py": 340146737126677655,
- "venv/lib/python3.13/site-packages/starlette/middleware/wsgi.py": 12506262030845301606,
- "venv/lib/python3.13/site-packages/pydantic/mypy.py": 10034028441785588819,
- "venv/lib/python3.13/site-packages/pygments/lexers/actionscript.py": 8829560731160428621,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/debug.py": 13528633965821062950,
- "venv/lib/python3.13/site-packages/pygments/lexers/smithy.py": 10789533877863290582,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_app.py": 14788764260762890368,
- "frontend/build/_app/immutable/nodes/8.BFOpA89K.js": 13153301632221690235,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.py": 183817263146423033,
- "backend/src/models/storage.py": 14886607138033931307,
- "venv/lib/python3.13/site-packages/click/types.py": 6491651131669287534,
- "venv/lib/python3.13/site-packages/pygments/lexers/smv.py": 8253688483040957894,
- "frontend/build/_app/immutable/assets/AssistantChatPanel.D4L5jlt0.css": 10724144138366384732,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odf.py": 15484940480924122966,
- "backend/src/services/notifications/__init__.py": 16179868089470006686,
- "venv/lib/python3.13/site-packages/anyio/abc/_resources.py": 8330687082933028623,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo77.f": 4046503346951676582,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_fsspec.py": 6936167344144998172,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-1.csv": 2202360898679162333,
- "venv/lib/python3.13/site-packages/anyio/_core/_contextmanagers.py": 1258491775823080427,
- "frontend/playwright-report/trace/playwright-logo.svg": 4728037962520658573,
- "venv/lib/python3.13/site-packages/numpy/_core/lib/pkgconfig/numpy.pc": 14713682399742251335,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/__init__.py": 63497920264089252,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_setitem.py": 2059440410065814114,
- "venv/lib/python3.13/site-packages/authlib/common/encoding.py": 52296066492753953,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_clipboard.py": 12674078499544938252,
- "venv/lib/python3.13/site-packages/pygments/lexers/ezhil.py": 10294520768762308887,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/base.py": 3250660921154829815,
- "venv/lib/python3.13/site-packages/pandas/tests/test_algos.py": 11860014896449369497,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_iteration.py": 15247340610412364508,
- "venv/lib/python3.13/site-packages/fastapi/_compat/model_field.py": 392699021682253569,
- "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/WHEEL": 14929202952940710322,
- "backend/src/services/git/_branch.py": 1746193863798413085,
- "venv/lib/python3.13/site-packages/numpy/tests/test_matlib.py": 14395481530627870882,
- "venv/lib/python3.13/site-packages/authlib/oidc/discovery/__init__.py": 308178910015974550,
- "venv/lib/python3.13/site-packages/pandas/tests/window/moments/conftest.py": 6137462119729731945,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_indexing.py": 14552860427542050771,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_generics.py": 16438159042939059717,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npy": 9694707264403109829,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/__init__.py": 13331622784664204066,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test__datasource.py": 1747755531265478106,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/freeze.py": 3469845570614985559,
- "venv/lib/python3.13/site-packages/keyring/__init__.py": 991260689223167957,
- "venv/lib/python3.13/site-packages/sqlalchemy/connectors/asyncio.py": 4200928269459447593,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/information_schema.py": 8551227132710897346,
- "venv/lib/python3.13/site-packages/pydantic/v1/validators.py": 1060954771151908883,
- "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/tokens_mixins.py": 9923721909178724437,
- "venv/lib/python3.13/site-packages/jose/jwe.py": 3325660353225624025,
- "frontend/src/components/Toast.svelte": 1736760619841085958,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/__init__.py": 13331622784664204066,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_pyf_src.py": 12351476647369971852,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/markup.py": 5413800947725916538,
- "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/LICENSE": 8177430849046795595,
- "docker/backend.entrypoint.sh": 1034669340368151691,
- "venv/lib/python3.13/site-packages/numpy/fft/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/licenses/LICENSE": 14230156892574098522,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_where.py": 14167991754625133668,
- "venv/lib/python3.13/site-packages/pygments/lexers/prolog.py": 599539463980699865,
- "venv/lib/python3.13/site-packages/numpy/core/_dtype.py": 2806449741844148191,
- "frontend/playwright-report/data/cc5452f8d8c308a176676866ee06628a569362aa.zip": 18382826147717299104,
- "backend/src/services/dataset_review/orchestrator.py": 15350066045014880242,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_keywords.py": 11487954623214475915,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_monotonic.py": 14648437502004398715,
- "venv/lib/python3.13/site-packages/itsdangerous/_json.py": 4872267972688724005,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/__init__.py": 2246704695838251846,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_clip.py": 8087139801274517318,
- "venv/lib/python3.13/site-packages/uvicorn/workers.py": 7213290478118197047,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_interpolate.py": 6154072863387383113,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_ops.py": 16346030307660048773,
- "venv/lib/python3.13/site-packages/_pytest/_py/error.py": 2257336434271433543,
- "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/WHEEL": 8600534672961461758,
- "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/utils.py": 617314300548081590,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_timer.py": 8196003526646080498,
- "venv/lib/python3.13/site-packages/dotenv/parser.py": 17651523026132242005,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply.py": 12349190935180702377,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/libdivide.h": 5314232500579481313,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_chaining_and_caching.py": 11784574265874608859,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/main_parser.py": 7942770969280622910,
- "venv/lib/python3.13/site-packages/fastapi/dependencies/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/version.py": 6401479036177132374,
- "venv/lib/python3.13/site-packages/pandas/core/methods/selectn.py": 13552176539021625776,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/base.py": 496956059910401121,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_iloc.py": 16160558158155038350,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_openpyxl.py": 6676451564208867775,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/layout.py": 11554376181083053156,
- "venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py": 14037211594707072958,
- "venv/lib/python3.13/site-packages/pygments/lexers/_php_builtins.py": 2344562378679281201,
- "frontend/src/lib/stores/__tests__/mocks/stores.js": 12764819706469057535,
- "backend/src/api/routes/git/_config_routes.py": 9064062564638523731,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_repr.py": 5577699046802107144,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_copy.py": 12902342280706372953,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/models.py": 15928924478695638423,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/contains.py": 3098087827310439993,
- "scripts/scan_secrets.sh": 10827095619853567115,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/numba_.py": 15997665748332235683,
- "venv/lib/python3.13/site-packages/pandas/io/iceberg.py": 13137128885014736233,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_setops.py": 15365064654930699428,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_weakref.py": 6780204527427742510,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.asm": 16630507336149184509,
- "venv/lib/python3.13/site-packages/pandas/util/_test_decorators.py": 17930801441803090445,
- "venv/lib/python3.13/site-packages/dateutil/_common.py": 12492546559232079071,
- "backend/src/services/clean_release/repositories/report_repository.py": 8327339942479580975,
- "backend/src/services/clean_release/manifest_service.py": 7248530010607024664,
- "venv/lib/python3.13/site-packages/authlib/oauth2/auth.py": 8455258275234626534,
- "backend/alembic/script.py.mako": 7041141123739810216,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.obj": 2884737706935637437,
- "venv/lib/python3.13/site-packages/pip/_internal/models/selection_prefs.py": 14700113736620314923,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_accuracy.py": 3904008607472505376,
- "backend/git_repos/remote/test-repo.git/objects/d5/0298a42699f39e4601c0aa23eab07bcb0703c7": 1966124163198751340,
- "frontend/src/components/git/GitWorkspacePanel.svelte": 4516972512005887443,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators.py": 9928398334052202841,
- "venv/lib/python3.13/site-packages/git/refs/log.py": 5175801243332619268,
- "frontend/src/lib/components/translate/BulkReplaceModal.svelte": 9447617465987205060,
- "venv/lib/python3.13/site-packages/pygments/formatters/terminal.py": 14380579279194052030,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py": 16386268386376675175,
- "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/INSTALLER": 17282701611721059870,
- "backend/tests/test_models.py": 14571471179954305607,
- "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pydantic/plugin/__init__.py": 16803973597469216174,
- "venv/lib/python3.13/site-packages/pydantic/v1/types.py": 10761779263335288559,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/authorization_server.py": 17967809814827547139,
- "venv/lib/python3.13/site-packages/pip/_internal/models/format_control.py": 12916176880659590456,
- "venv/lib/python3.13/site-packages/pandas/core/computation/api.py": 17919983681396223380,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_factorize.py": 17995673140216929494,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/sessions.py": 5400174351499383072,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_subclass.py": 5540948578269213810,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_timezones.py": 4771674179164304731,
- "venv/lib/python3.13/site-packages/sqlalchemy/event/base.py": 18238453132776154057,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_value_counts.py": 9352540710376306520,
- "venv/lib/python3.13/site-packages/pygments/styles/algol_nu.py": 6229131016121450375,
- "backend/git_repos/remote/test-repo.git/hooks/sendemail-validate.sample": 8058833260784074657,
- "venv/lib/python3.13/site-packages/websockets/asyncio/server.py": 885415484558949506,
- "venv/lib/python3.13/site-packages/more_itertools/__init__.py": 9858612105173082060,
- "venv/lib/python3.13/site-packages/pandas/_libs/arrays.cpython-313-x86_64-linux-gnu.so": 8634234308863090562,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/websockets/auth.py": 499195617702591757,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/greenlet/TUserGreenlet.cpp": 16258622236210473101,
- "venv/lib/python3.13/site-packages/pip/_internal/locations/__init__.py": 8147012724727395488,
- "venv/lib/python3.13/site-packages/jaraco/classes/meta.py": 15930255620248873425,
- "venv/lib/python3.13/site-packages/numpy/fft/__init__.pyi": 10354990065626209946,
- "venv/lib/python3.13/site-packages/passlib/tests/sample_config_1s.cfg": 1809713544666311828,
- "venv/lib/python3.13/site-packages/passlib/handlers/fshp.py": 13298827601291507295,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_shift.py": 14026124784027171225,
- "venv/lib/python3.13/site-packages/pyasn1/type/tag.py": 13912273274509186651,
- "venv/lib/python3.13/site-packages/rapidfuzz/process_py.py": 17563673072076876125,
- "venv/lib/python3.13/site-packages/anyio/_core/_sockets.py": 10525237827959090532,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_period.py": 15671388508498441412,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/sql.py": 13315906751371033170,
- "venv/lib/python3.13/site-packages/pip/_internal/vcs/__init__.py": 1197579313959289096,
- "frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js": 10435439112537278657,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/incfile.f90": 4348588746493647387,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.c": 9134176670140958459,
- "backend/src/api/routes/llm.py": 14720807640771498486,
- "frontend/build/_app/immutable/chunks/DCG5F3ic.js": 10038366451600899187,
- "venv/lib/python3.13/site-packages/psycopg2/errorcodes.py": 6711830404954314463,
- "venv/lib/python3.13/site-packages/numpy/testing/__init__.pyi": 8126257788928282891,
- "venv/lib/python3.13/site-packages/jsonschema/__init__.py": 6925762200139836824,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/PIL/Image.py": 13615925856053031482,
- "venv/lib/python3.13/site-packages/rsa/common.py": 10921682819204792805,
- "venv/lib/python3.13/site-packages/greenlet/tests/__init__.py": 1181423074160870921,
- "venv/lib/python3.13/site-packages/websockets/speedups.cpython-313-x86_64-linux-gnu.so": 10941658763526595989,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.pyi": 17903213294220335051,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.cpython-313-x86_64-linux-gnu.so": 17089839649971421164,
- "venv/lib/python3.13/site-packages/requests/certs.py": 16052880877156864882,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_backend.py": 17793139799410518847,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_feather.py": 13613400750755530364,
- "frontend/src/routes/translate/[id]/+page.svelte": 1911443262444004956,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/privatemod.f90": 8999550841368314739,
- "backend/src/services/clean_release/repositories/publication_repository.py": 1097065694003039928,
- "venv/lib/python3.13/site-packages/keyring/testing/backend.py": 14295829193445781542,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/fields.py": 8923326131649837922,
- "venv/lib/python3.13/site-packages/pandas/tests/base/common.py": 13335865314907577354,
- "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/RECORD": 7810411361439269754,
- "venv/lib/python3.13/site-packages/pygments/styles/stata_dark.py": 324072437809944751,
- "venv/lib/python3.13/site-packages/pydantic/v1/generics.py": 1150594223414883339,
- "venv/lib/python3.13/site-packages/PIL/IcoImagePlugin.py": 14483964191652228364,
- "venv/lib/python3.13/site-packages/cffi/_imp_emulation.py": 17246725564704952212,
- "venv/lib/python3.13/site-packages/numpy/tests/test_public_api.py": 11741922758622705449,
- "venv/lib/python3.13/site-packages/pygments/styles/lovelace.py": 15082819162722685616,
- "venv/lib/python3.13/site-packages/pydantic/_migration.py": 17982816821930887921,
- "backend/src/plugins/translate/orchestrator_config.py": 1227864697811313446,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_compare.py": 3079569478684646491,
- "venv/lib/python3.13/site-packages/fastapi/security/base.py": 15674297568104917749,
- "venv/lib/python3.13/site-packages/pandas/io/sas/sasreader.py": 12766780210114366112,
- "frontend/playwright-report/trace/assets/codeMirrorModule-Ds_H_9Yq.js": 1369559823166915102,
- "frontend/playwright-report/data/b13be72bc9111c369dd61bcb4b41565873341170.zip": 9286336518597330572,
- "frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js": 7475597145566385341,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/themes.py": 6451091097727599550,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/applicator": 6870991911243684132,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_function_base.py": 15241999259666702619,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_constructors.pyi": 164538008396001632,
- "venv/lib/python3.13/site-packages/pygments/lexers/webassembly.py": 17811970490091406867,
- "backend/src/schemas/dataset_review_pkg/_composites.py": 9530969677898630695,
- "venv/lib/python3.13/site-packages/click/exceptions.py": 9734955259447933725,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayterator.py": 3076316311545674897,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/_typing.py": 17598638528781632158,
- "venv/lib/python3.13/site-packages/ecdsa/test_ecdsa.py": 17595025859105321562,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.py": 17112989332785349705,
- "venv/lib/python3.13/site-packages/_pytest/raises.py": 8188402179490363767,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.pyi": 16372699564794732463,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/__init__.py": 7526309124863950484,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/accessors.py": 14394872772838047912,
- "venv/lib/python3.13/site-packages/pandas/io/common.py": 12088195203620154171,
- "frontend/build/_app/immutable/chunks/CuzmfnQu.js": 4320326097426684598,
- "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numerictypes.py": 5719374287454872555,
- "venv/lib/python3.13/site-packages/numpy/_utils/__init__.py": 7731065084036767848,
- "backend/src/services/maintenance/_orchestrators.py": 995360865260101856,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log1p.csv": 16333455295913164408,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/twisted.py": 16059862619165885730,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_get.py": 10255752806860493777,
- "venv/lib/python3.13/site-packages/referencing/tests/test_referencing_suite.py": 8875120876162738440,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pxd": 13413785818999584986,
- "frontend/build/_app/immutable/chunks/0hvOu5jK.js": 10335091194896019556,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/prompt.py": 9561640601516933380,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_symbol.py": 10792387279408528886,
- "venv/lib/python3.13/site-packages/passlib/tests/test_win32.py": 13932956220195912963,
- "venv/lib/python3.13/site-packages/_pytest/_io/wcwidth.py": 13515196388826152383,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_invalid.py": 2762344062554575805,
- "venv/lib/python3.13/site-packages/pandas/core/window/doc.py": 4204367435727844696,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/hist.py": 10928173425078493095,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_split_partition.py": 2715491071550545667,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexers.py": 6773751569163287047,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/__init__.py": 3969805865048730851,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/decl_class.py": 6328411894571735935,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/provision.py": 9472538482404392519,
- "venv/lib/python3.13/site-packages/PIL/ImageWin.py": 13635870584232081323,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_pytables_missing.py": 12154582133989896069,
- "venv/lib/python3.13/site-packages/uvicorn/supervisors/multiprocess.py": 10047012560534876149,
- "venv/lib/python3.13/site-packages/packaging/_parser.py": 13394093358675095309,
- "venv/bin/dotenv": 953953349803507198,
- "backend/src/core/__init__.py": 8673978627093182792,
- "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/RECORD": 5169907629260560698,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_regression.py": 16293647824734937323,
- "venv/lib/python3.13/site-packages/pandas/_libs/writers.pyi": 10494773026133244183,
- "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.py": 6617116180936986481,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_indexing.py": 546024765756472196,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/__init__.py": 15130871412783076140,
- "frontend/vite.config.js": 3769019895915732131,
- "venv/lib/python3.13/site-packages/passlib/crypto/des.py": 14699826058580193499,
- "venv/lib/python3.13/site-packages/urllib3/util/retry.py": 17988032431204662756,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_usecols_basic.py": 16382444980424010514,
- "venv/lib/python3.13/site-packages/pygments/lexers/dax.py": 10868881057512002309,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/candidates.py": 5951912505933673835,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/utils.py": 10346859893683522113,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string_arrow.py": 10008395772220468318,
- "venv/lib/python3.13/site-packages/numpy/tests/test_ctypeslib.py": 9592016432737074765,
- "venv/lib/python3.13/site-packages/attr/converters.pyi": 17675091788614033166,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_truncate.py": 9623613657871046837,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets.py": 4499538899492148499,
- "frontend/build/_app/immutable/chunks/CTzDW2Lk.js": 14040680713815065540,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_filter.py": 2388681477981649268,
- "venv/lib/python3.13/site-packages/dateutil/__init__.py": 17666544837260663800,
- "backend/src/models/api_key.py": 4327024700622965951,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_getitem.py": 18202683049446557047,
- "venv/lib/python3.13/site-packages/pycparser/ply/lex.py": 3393278208465358140,
- "venv/lib/python3.13/site-packages/passlib/tests/utils.py": 15403198680231294263,
- "venv/lib/python3.13/site-packages/cffi/error.py": 8147505969912539538,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo90.f90": 2435648607844815947,
- "backend/src/services/reports/__init__.py": 11818812865847046400,
- "venv/lib/python3.13/site-packages/anyio/_core/_tasks.py": 14104828341875599130,
- "venv/lib/python3.13/site-packages/pandas/core/methods/describe.py": 17006836623161521092,
- "venv/lib/python3.13/site-packages/anyio/abc/_sockets.py": 15042495744291042062,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_constructors.py": 16197656939536784142,
- "venv/lib/python3.13/site-packages/_pytest/warnings.py": 8633394774569709013,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.cpython-313-x86_64-linux-gnu.so": 13209491675968970365,
- "venv/lib/python3.13/site-packages/requests/structures.py": 2668010839316715865,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/util.py": 387985965709546512,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_info.py": 10615285239043745712,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_pyxlsb.py": 10035587889954731645,
- "venv/lib/python3.13/site-packages/pip/_internal/vcs/versioncontrol.py": 13742159245132241245,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/utils.py": 9959199071030996679,
- "venv/lib/python3.13/site-packages/numpy/fft/_helper.pyi": 9546918341939102632,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_axis.py": 4097534573847151853,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_reflection.py": 10520778598547003532,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/block.f": 10727418304254548946,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.pyi": 2884703536776830012,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot_multilevel.py": 9830258607305392103,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_count.py": 9186538441380080087,
- "venv/lib/python3.13/site-packages/PIL/_imagingft.cpython-313-x86_64-linux-gnu.so": 11054435406031360190,
- "venv/lib/python3.13/site-packages/anyio/_core/_tempfile.py": 230288423480899091,
- "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/RECORD": 11604408378998955169,
- "venv/lib/python3.13/site-packages/git/repo/base.py": 13975465345838683533,
- "frontend/e2e/run-e2e.sh": 8106714116467101372,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nditer.pyi": 33523064068376750,
- "venv/lib/python3.13/site-packages/jsonschema/validators.py": 3832874295500213309,
- "venv/lib/python3.13/site-packages/urllib3/util/wait.py": 14629837381061032546,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/associationproxy.py": 7421910137064160936,
- "venv/lib/python3.13/site-packages/iniconfig/_version.py": 8497474654470220170,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_string_array.py": 8260883866404398980,
- "venv/lib/python3.13/site-packages/_pytest/nodes.py": 515939386237558331,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_namespace_utils.py": 5237766366340181382,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/twodim_base.pyi": 3773329770170248877,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_loadtxt.py": 17562784940619942447,
- "venv/lib/python3.13/site-packages/passlib/utils/binary.py": 13123975436674239306,
- "build.sh": 5842665574427443016,
- "venv/lib/python3.13/site-packages/starlette/schemas.py": 697416731579555195,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/main.py": 9304034369762028739,
- "venv/lib/python3.13/site-packages/numpy/typing/__init__.py": 3608665862759745048,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/operators.f90": 5949265961908386974,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/gh_22819.pyf": 14717748358749934995,
- "venv/lib/python3.13/site-packages/pandas/api/types/__init__.py": 3995030354191071797,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/intranges.py": 12536174834761591006,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/masked.py": 13977195666947626206,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_get_numeric_data.py": 5896318696417090902,
- "venv/lib/python3.13/site-packages/uvicorn/__main__.py": 6086938803696646644,
- "venv/lib/python3.13/site-packages/pygments/lexers/_qlik_builtins.py": 1728058904137960444,
- "backend/tests/scripts/test_clean_release_tui.py": 17813178142456308266,
- "backend/git_repos/remote/test-repo.git/description": 15262637409357137373,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_dict.py": 4937173601709369119,
- "venv/lib/python3.13/site-packages/pygments/lexers/graphics.py": 13783143864729682444,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/copy_internals.py": 1245428320513062166,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.py": 13012775703413938576,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/printing.py": 8681519649669408795,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_missing.py": 1963705411068820866,
- "frontend/build/_app/immutable/nodes/21.i4crDxrH.js": 12772123636509212690,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/WHEEL": 9131187629260560775,
- "backend/src/services/__tests__/test_rbac_permission_catalog.py": 2963458864311994307,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/appengine.py": 16194997685865850655,
- "backend/src/plugins/search.py": 13705421801923369220,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_unary.py": 8046543893978198672,
- "venv/lib/python3.13/site-packages/pandas/core/window/rolling.py": 6316477981414191778,
- "frontend/build/_app/immutable/nodes/30.DnYtytFL.js": 2391068517706387105,
- "venv/lib/python3.13/site-packages/ecdsa/numbertheory.py": 13538480862642502330,
- "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/licenses/LICENSE": 7959949171752474553,
- "frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js": 17821671753127603158,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_constructors.py": 11065058462752831997,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_codes.py": 13901854719435716195,
- "venv/lib/python3.13/site-packages/pandas/api/indexers/__init__.py": 17431573013142626187,
- "venv/lib/python3.13/site-packages/git/cmd.py": 8854786163152637148,
- "frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte": 1996807488169542658,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2cffi.py": 5997687240967250164,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_reductions.py": 17810094294132819208,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_tree.py": 15789443159423302291,
- "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/WHEEL": 18203500019759199992,
- "venv/lib/python3.13/site-packages/numpy/_core/overrides.py": 252940520997718714,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_setitem.py": 10389770446834773837,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_sql.py": 3901697517087276687,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/schema.py": 5391655516870611151,
- "frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js": 10120412205695269578,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_character.py": 17168707712220699738,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_alpha_unix.h": 2759424570606117942,
- "venv/lib/python3.13/site-packages/pydantic/annotated_handlers.py": 10186120300163345360,
- "venv/lib/python3.13/site-packages/yaml/nodes.py": 3463622922914760653,
- "backend/git_repos/remote/test-repo.git/objects/17/66251d8cb2693136e09ea3def3e776559cb722": 1137762010493457272,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/tile.py": 17137524194129840833,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_size.py": 12449835577388069407,
- "venv/lib/python3.13/site-packages/cffi/cffi_opcode.py": 8411344362428947268,
- "venv/lib/python3.13/site-packages/ecdsa/eddsa.py": 15966858338456571506,
- "venv/lib/python3.13/site-packages/gitdb/db/loose.py": 17467413653016810702,
- "venv/lib/python3.13/site-packages/pygments/styles/paraiso_dark.py": 3976779833379189837,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_generation_shared.py": 23345689300073549,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_skew_kurt.py": 15225601437354712351,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/__init__.py": 12975130533860125272,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_dtype.py": 1647214604678171565,
- "venv/lib/python3.13/site-packages/pygments/lexers/ecl.py": 12886695201994337568,
- "venv/lib/python3.13/site-packages/passlib/handlers/scram.py": 12281469744083867450,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_matmul.py": 9323220618335072725,
- "frontend/src/routes/settings/EnvironmentsTab.svelte": 13575164255656888464,
- "venv/lib/python3.13/site-packages/uvicorn/_compat.py": 2593000889619875759,
- "venv/lib/python3.13/site-packages/tzlocal/windows_tz.py": 11696765495002954868,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.cpython-313-x86_64-linux-gnu.so": 6726636942028566415,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py": 2873060848310644552,
- "venv/lib/python3.13/site-packages/pygments/styles/colorful.py": 15708848112363953394,
- "venv/bin/numpy-config": 17104619511899110252,
- "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/RECORD": 1164466882742493155,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh22648.pyf": 15094859289098837494,
- "venv/lib/python3.13/site-packages/passlib/handlers/__init__.py": 3424087230285514388,
- "venv/lib/python3.13/site-packages/yaml/constructor.py": 8731384179016992045,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598.f90": 1409455010615482779,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_index.py": 1551768441102117466,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/__init__.py": 7316739139609490520,
- "venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py": 8159971229245441880,
- "venv/lib/python3.13/site-packages/pygments/lexers/rdf.py": 14488319292387226505,
- "backend/tests/test_constants_audit_fixes.py": 18298690956132739779,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/__init__.py": 6758781485387665020,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_types.py": 4083297168618981717,
- "venv/lib/python3.13/site-packages/pygments/lexers/sophia.py": 15971500155124949058,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/_typing.py": 17589387690638097975,
- "venv/lib/python3.13/site-packages/packaging/pylock.py": 15346942039643310253,
- "frontend/build/_app/immutable/chunks/DWg3slHj.js": 16432655720744147297,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE": 17284252174641192866,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_algs.py": 2479791018067637690,
- "venv/lib/python3.13/site-packages/_pytest/python.py": 1829073958095716309,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/__init__.py": 9997757256282720103,
- "venv/lib/python3.13/site-packages/PIL/_tkinter_finder.py": 14045496501810535432,
- "venv/lib/python3.13/site-packages/pygments/lexers/make.py": 5345282370426217663,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_like.pyi": 1968570015765106620,
- "venv/lib/python3.13/site-packages/numpy/random/bit_generator.cpython-313-x86_64-linux-gnu.so": 2574035311375507054,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libssl-81ffa89e.so.3": 13913673119166658781,
- "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/exceptions.py": 11303331612406662162,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rank.py": 5817408252050193538,
- "venv/lib/python3.13/site-packages/pip/_internal/configuration.py": 2563100675379605810,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pymysql.py": 12923876736367229454,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadbconnector.py": 14865906347579451546,
- "venv/lib/python3.13/site-packages/gitdb/typ.py": 16374739906244805047,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/signature.py": 3614545297259098566,
- "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/METADATA": 13428590545328703138,
- "venv/lib/python3.13/site-packages/urllib3/contrib/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/introspection.py": 5447179017910128771,
- "venv/lib/python3.13/site-packages/jsonschema/_typing.py": 13152346021901861822,
- "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.pyi": 3111521453255595221,
- "venv/lib/python3.13/site-packages/psycopg2/sql.py": 18041240927130590808,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/__init__.py": 10834852742917144496,
- "venv/lib/python3.13/site-packages/pydantic/v1/dataclasses.py": 7833468513057242440,
- "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.cpython-313-x86_64-linux-gnu.so": 16327106317503267067,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_periodindex.py": 13430003945574795792,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayprint.pyi": 2053388407376896377,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimelike.py": 5317270578347271174,
- "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/METADATA": 13633829318759752611,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_null_file.py": 6885565068723353414,
- "venv/lib/python3.13/site-packages/numpy/_core/cversions.py": 9724467539503410469,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ma.pyi": 8186102816080813799,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/datasource.pyi": 80441145804744162,
- "venv/lib/python3.13/site-packages/fastapi/concurrency.py": 17937688838625807004,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/generic.py": 17755579497690180620,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/concat.py": 14737724508458849795,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_arrow_compat.py": 17818294260710640443,
- "venv/lib/python3.13/site-packages/numpy/lib/npyio.pyi": 3212440968296555560,
- "venv/lib/python3.13/site-packages/secretstorage/item.py": 15486045386471912693,
- "venv/lib/python3.13/site-packages/pip/_internal/locations/base.py": 7966628150470073365,
- "venv/lib/python3.13/site-packages/numpy/random/mtrand.cpython-313-x86_64-linux-gnu.so": 16146459667121787202,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarraytypes.h": 6765088137325865789,
- "venv/lib/python3.13/site-packages/PIL/ImageFilter.py": 10974179993355630141,
- "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.cpython-313-x86_64-linux-gnu.so": 16604252871044637047,
- "venv/lib/python3.13/site-packages/pygments/lexers/nit.py": 18262907536841158657,
- "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/licenses/LICENSE": 13479831069780783137,
- "frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js": 16164320505605430516,
- "venv/lib/python3.13/site-packages/pandas/_libs/reshape.cpython-313-x86_64-linux-gnu.so": 10639750501333255943,
- "frontend/src/components/git/CommitHistory.svelte": 6419514228971332714,
- "frontend/src/components/llm/DocPreview.svelte": 14266235011755175979,
- "backend/src/services/clean_release/__tests__/test_report_builder.py": 11856874434357958029,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/validation": 5398883285871046811,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_legacy.py": 12735901522735836481,
- "venv/lib/python3.13/site-packages/httpcore/_backends/mock.py": 6849131425727092784,
- "venv/lib/python3.13/site-packages/pandas/_libs/testing.pyi": 16691791330088523786,
- "frontend/src/app.css": 3020720639702954139,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_cpp.py": 10982107081267457286,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine_first.py": 3100691245280812910,
- "venv/lib/python3.13/site-packages/pandas/io/clipboard/__init__.py": 3656451154829206939,
- "venv/lib/python3.13/site-packages/yaml/loader.py": 18284689412149643959,
- "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/RECORD": 963865046004908868,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_day.py": 2200008998040663785,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/__init__.py": 14571251344510763303,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/parameters.py": 1647490964392525933,
- "venv/lib/python3.13/site-packages/requests/sessions.py": 6936640856092320928,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_pydatetime.py": 16228315407662560992,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isetitem.py": 14895552405828068177,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_arrow_interface.py": 9757086292358759236,
- "venv/lib/python3.13/site-packages/pygments/lexers/_csound_builtins.py": 14530739818491398298,
- "venv/lib/python3.13/site-packages/pygments/lexers/cddl.py": 1303059539145221713,
- "backend/src/services/dataset_review/repositories/__tests__/test_session_repository.py": 16488635694638612020,
- "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/RECORD": 6518517239543344179,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/setup.py": 17086801293303202021,
- "venv/lib/python3.13/site-packages/requests/hooks.py": 9888227370911151341,
- "venv/lib/python3.13/site-packages/jaraco/context/__init__.py": 10975097417056278427,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ctypeslib.pyi": 8623725566434725526,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_bool.py": 433342705586552936,
- "venv/lib/python3.13/site-packages/pandas/tests/test_col.py": 14781555956509956371,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_array_to_datetime.py": 3467480435568672840,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_astype.py": 1961831758405941258,
- "venv/lib/python3.13/site-packages/h11/__init__.py": 222801976520197308,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/interfaces.py": 5371646629319169153,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_calendar.py": 12313641252472031631,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.py": 4940170059946018356,
- "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.cpython-313-x86_64-linux-gnu.so": 5284769758475394095,
- "venv/lib/python3.13/site-packages/pip/_internal/models/pylock.py": 16697828625021519459,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/common.py": 9354442374897565498,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg_catalog.py": 15726448028057859831,
- "venv/lib/python3.13/site-packages/charset_normalizer/api.py": 9172704759115759638,
- "backend/src/core/cot_logger.py": 6973572678150364495,
- "venv/lib/python3.13/site-packages/fastapi/dependencies/utils.py": 7687214523082385505,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_resolution.py": 6076761538303762297,
- "venv/lib/python3.13/site-packages/websockets/legacy/handshake.py": 376095144657994920,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_math.h": 16701045088211015518,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_cpython_compat.hpp": 8396413256279803400,
- "venv/lib/python3.13/site-packages/pandas/core/config_init.py": 16537122488227845090,
- "venv/lib/python3.13/site-packages/pyasn1/debug.py": 6305633719847955310,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dtypes.py": 7550022036887594386,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_append.py": 9644955836191900614,
- "venv/lib/python3.13/site-packages/authlib/jose/jwk.py": 13560749074922587626,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi": 11455144434558323236,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/types.py": 13384984564922916167,
- "venv/lib/python3.13/site-packages/pydantic/v1/__init__.py": 1642038155370734658,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_excel.py": 5467043641314706635,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np126.pkl.gz": 9677994062701347206,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.py": 4440659352851541547,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/endpoint.py": 13389763148720370546,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/fields.py": 10090313990429695520,
- "venv/lib/python3.13/site-packages/pillow.libs/libXau-154567c4.so.6.0.0": 4340972632724893052,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexerrors.py": 4434868847540549873,
- "venv/lib/python3.13/site-packages/pandas/core/ops/mask_ops.py": 16152832446926420035,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/endpoint.py": 18260428408051728802,
- "venv/lib/python3.13/site-packages/gitdb/db/__init__.py": 2615504918450276693,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_label_or_level_utils.py": 3423644585913150841,
- "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_numeric.py": 18037815278545274402,
- "venv/lib/python3.13/site-packages/numpy/_core/numeric.pyi": 17785360553418386488,
- "venv/lib/python3.13/site-packages/git/index/fun.py": 18338379518768926372,
- "venv/lib/python3.13/site-packages/urllib3/_collections.py": 3440910792774742262,
- "venv/lib/python3.13/site-packages/pygments/styles/igor.py": 2291640843781128270,
- "frontend/src/components/StartupEnvironmentWizard.svelte": 17705330033482916904,
- "backend/src/plugins/translate/__tests__/test_dictionary_filter.py": 2426844436521732941,
- "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/WHEEL": 5160964596297665692,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel.py": 7728646523045538484,
- "backend/src/plugins/translate/__tests__/test_executor.py": 9030484360469714630,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_laguerre.py": 7475592201750602042,
- "frontend/src/lib/stores/activity.js": 10599836924066718828,
- "backend/src/schemas/translate.py": 15896789917354585618,
- "venv/lib/python3.13/site-packages/pillow.libs/libzstd-761a17b6.so.1.5.7": 17875236748140157032,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/wheel.py": 16397273591245583356,
- "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.c": 9318655518998644962,
- "backend/tests/test_api_key_model.py": 18059967072469014911,
- "venv/lib/python3.13/site-packages/numpy/_core/overrides.pyi": 13121243505132110607,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_fields.py": 2692892815545218335,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust.abi3.so": 2537152913308578487,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_drop.py": 11341278355685583133,
- "venv/lib/python3.13/site-packages/websockets/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_api.py": 14120915875574640262,
- "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/METADATA": 1862765380818895200,
- "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.py": 16856718240972376883,
- "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/licenses/LICENSE": 6965457853328313914,
- "backend/src/core/ws_log_handler.py": 16227392517834423362,
- "venv/lib/python3.13/site-packages/pygments/lexers/savi.py": 95400050302239274,
- "venv/lib/python3.13/site-packages/anyio/from_thread.py": 7973678341601453474,
- "venv/lib/python3.13/site-packages/PIL/MicImagePlugin.py": 13540523615822507963,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_methods.py": 12694335778731418517,
- "venv/lib/python3.13/site-packages/pandas/io/_util.py": 13608922148814398500,
- "venv/lib/python3.13/site-packages/yaml/cyaml.py": 9157893742065554693,
- "venv/lib/python3.13/site-packages/pygments/lexers/_lua_builtins.py": 12653747099659257203,
- "venv/lib/python3.13/site-packages/pygments/lexers/xorg.py": 14591144191879110061,
- "venv/lib/python3.13/site-packages/dateutil/parser/_parser.py": 9443336890192151397,
- "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/fallback.py": 4260636031748548345,
- "venv/lib/python3.13/site-packages/h11/_headers.py": 7592730288271984585,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet.py": 10727595500186011102,
- "venv/lib/python3.13/site-packages/_pytest/threadexception.py": 10464996327276961035,
- "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.py": 11758491058846790938,
- "venv/lib/python3.13/site-packages/apscheduler/executors/tornado.py": 6635576580306890718,
- "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.pyi": 12043292763005874815,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/columns.py": 8488246354818721406,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctan.csv": 4581185622290535488,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_numeric.py": 9417128508433693658,
- "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA": 16498441272591167134,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/blocking.py": 3483388533957772681,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufuncs.pyi": 1808147181379894521,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/api.py": 12339139862411341381,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_cpu.h": 13799366908726531089,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_hashing.py": 11119284926039008503,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/ecdsa/der.py": 9374566189581725372,
- "venv/lib/python3.13/site-packages/pygments/filter.py": 16846063190466267618,
- "venv/lib/python3.13/site-packages/pygments/styles/rainbow_dash.py": 12236746494379891602,
- "frontend/build/_app/immutable/chunks/DkSc7bnI.js": 16633882293462436801,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_types.py": 7175518113263603341,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/oct_key.py": 11504245602045724,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_to_timestamp.py": 17572983799929378095,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/__init__.py": 16123561007855424016,
- "venv/lib/python3.13/site-packages/itsdangerous/url_safe.py": 13454753900702274266,
- "venv/lib/python3.13/site-packages/pydantic/v1/version.py": 2758971830527526972,
- "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/io/parsers/arrow_parser_wrapper.py": 11745253171984606573,
- "frontend/build/_app/immutable/chunks/zkZd1nRa.js": 15711219595002974448,
- "backend/src/api/routes/clean_release_v2.py": 7430240321470425220,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/algorithms.py": 2375452080667815941,
- "venv/lib/python3.13/site-packages/pygments/lexers/special.py": 4972294202790455038,
- "venv/lib/python3.13/site-packages/numpy/char/__init__.py": 4428218097234308768,
- "backend/src/services/clean_release/facade.py": 4588791439430238149,
- "backend/src/services/clean_release/repositories/__init__.py": 10330511711442503831,
- "venv/lib/python3.13/site-packages/websockets/legacy/protocol.py": 762692033188392424,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_infer_objects.py": 16868563755487479303,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_subclass.py": 10949229764696473939,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/provider.py": 16463243654123731993,
- "venv/lib/python3.13/site-packages/numpy/lib/_datasource.pyi": 5894423389796456573,
- "venv/lib/python3.13/site-packages/passlib/tests/test_apps.py": 10454136535890937237,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/column.py": 9498044216416177656,
- "venv/lib/python3.13/site-packages/pandas/_libs/interval.cpython-313-x86_64-linux-gnu.so": 8964760352224019544,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_invalid_arg.py": 610891871484326055,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/string_arrow.py": 16997970607998635570,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_musllinux.py": 2423350951094915747,
- "venv/lib/python3.13/site-packages/numpy/f2py/__init__.py": 7470157159992827389,
- "venv/lib/python3.13/site-packages/pygments/lexers/_vim_builtins.py": 6842381248727719900,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/validation": 13992741783834278677,
- "venv/lib/python3.13/site-packages/referencing/exceptions.py": 2535322334430110414,
- "venv/lib/python3.13/site-packages/pygments/lexers/qlik.py": 3881663935630350152,
- "backend/src/services/clean_release/publication_service.py": 7731809712174358922,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_round.py": 7912161077874611432,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein_py.py": 1933257612725836484,
- "venv/lib/python3.13/site-packages/jose/backends/ecdsa_backend.py": 2684176977865283060,
- "venv/lib/python3.13/site-packages/numpy/lib/introspect.py": 5706729538356302335,
- "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml_dtypes.py": 18293138335799308439,
- "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/RECORD": 4487477737768669516,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/vector.py": 9941185556118343263,
- "venv/lib/python3.13/site-packages/pandas/core/computation/common.py": 5369352684655954608,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_category.py": 3944898528119364040,
- "venv/lib/python3.13/site-packages/pandas/tests/libs/test_join.py": 5982692266872978444,
- "venv/lib/python3.13/site-packages/pygments/lexers/maxima.py": 11824576541091274641,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/utils.py": 8633356372647820801,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_at.py": 1029744344133153888,
- "venv/lib/python3.13/site-packages/pluggy/_hooks.py": 6941854999025808196,
- "frontend/src/components/backups/BackupList.svelte": 7178110735645066783,
- "backend/src/api/routes/assistant/_resolvers.py": 5636628127798453486,
- "venv/lib/python3.13/site-packages/referencing/_attrs.py": 14434891919747863272,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval_pyarrow.py": 3849382723890414899,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/extensions.py": 4132402557064663751,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/base.py": 16891437410462671317,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/json/array.py": 7437107031079833232,
- "venv/lib/python3.13/site-packages/sqlalchemy/event/attr.py": 5971663429221923939,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/auth.py": 912521029864094489,
- "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_gen_files.py": 11149423183253618378,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/padding.py": 7470483648602195268,
- "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/METADATA": 6656194161182818439,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_categorical.py": 8844412630511751140,
- "venv/lib/python3.13/site-packages/pandas/tests/api/test_types.py": 8889829773923216769,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/errors.py": 10750605030539582738,
- "venv/lib/python3.13/site-packages/pygments/lexers/iolang.py": 10997512999728724130,
- "backend/src/plugins/translate/__init__.py": 12400577052797809611,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/__init__.py": 6489437464172324468,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/horizontal_shard.py": 17615732108308858890,
- "venv/lib/python3.13/site-packages/python_multipart/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_astype.py": 10171766562093740708,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/asymmetric_key.py": 14948661854506285135,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_regression.py": 9375525053479844400,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get_value.py": 389530025760539462,
- "venv/lib/python3.13/site-packages/python_multipart/decoders.py": 14252672585219598429,
- "frontend/src/lib/stores/__tests__/assistantChat.test.js": 3754492247057393002,
- "backend/src/plugins/translate/_text_cleaner.py": 13161219043687449729,
- "backend/src/api/routes/maintenance/__init__.py": 8921716690761316245,
- "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/METADATA": 3390257212824996989,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/misc.py": 17461379236189029253,
- "venv/lib/python3.13/site-packages/pandas/core/computation/check.py": 16048939716341154196,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/multi.py": 9115751979327393200,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/okp_key.py": 10312614562914096039,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/hybrid.py": 14287665090144592501,
- "venv/lib/python3.13/site-packages/pandas/tseries/api.py": 14785127136180503704,
- "venv/lib/python3.13/site-packages/starlette/_utils.py": 8384087194580626069,
- "venv/lib/python3.13/site-packages/PIL/ImageDraw.py": 12919304671639673744,
- "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/RECORD": 18294169019244826301,
- "venv/lib/python3.13/site-packages/jose/jwt.py": 3405491994268385178,
- "venv/lib/python3.13/site-packages/pygments/lexers/ptx.py": 4855144232064607995,
- "venv/bin/keyring": 1488968652276547659,
- "venv/lib/python3.13/site-packages/jsonschema/tests/typing/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.pyi": 16176428602589420913,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_data_list.py": 1131520422778420758,
- "venv/lib/python3.13/site-packages/websockets/legacy/framing.py": 12759022769700230409,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.f90": 1249061697041863692,
- "venv/lib/python3.13/site-packages/smmap/test/test_buf.py": 6910367739329016619,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/provision.py": 13156893203444936309,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_forward_ref.py": 10623110912945011703,
- "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.py": 1262543237476191714,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reorder_levels.py": 10996225584998355824,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_typing_extra.py": 14843908493613991959,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray.pyi": 14369009813591437391,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_setitem.py": 15731267129055947469,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_mixed.py": 3476101699679108025,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/common_with_division.f": 13517753924061311074,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-expm1.csv": 8710594949902856122,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/conftest.py": 13388202260795998613,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_mock_val_ser.py": 12265320534388472158,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarrayobject.h": 7320510589635636690,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_astype.py": 15275720655739710249,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_processors.py": 16557117595879208702,
- "venv/lib/python3.13/site-packages/multipart/exceptions.py": 8580522204565816132,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_stack_saved.py": 7767924647054186572,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_regression.py": 6742646011852052645,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/meson.build.template": 9935732744553086652,
- "venv/lib/python3.13/site-packages/pandas/core/strings/object_array.py": 17631047188839635539,
- "backend/src/plugins/translate/__tests__/__init__.py": 2490542523242946173,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py": 9559295461619813890,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/compiler.py": 13924519162400330589,
- "backend/src/plugins/llm_analysis/__tests__/test_service.py": 17317408415318686082,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/datasource.pyi": 16752667877866430577,
- "venv/lib/python3.13/site-packages/pygments/lexers/installers.py": 5083244110640899732,
- "backend/src/services/clean_release/__init__.py": 9144880924791476391,
- "venv/lib/python3.13/site-packages/numpy/random/_philox.cpython-313-x86_64-linux-gnu.so": 9916143171057774705,
- "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nditer.pyi": 2351219156711800159,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_replace.py": 8784361132920473760,
- "venv/lib/python3.13/site-packages/greenlet/PyGreenletUnswitchable.cpp": 3160733517193315684,
- "venv/lib/python3.13/site-packages/numpy/_core/_rational_tests.cpython-313-x86_64-linux-gnu.so": 13475521165331256711,
- "backend/src/plugins/translate/orchestrator_sql.py": 15420456250044832567,
- "frontend/src/lib/stores/__tests__/mocks/state.js": 10691107564567912815,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_setops.py": 9991233160569430204,
- "venv/lib/python3.13/site-packages/pandas/io/formats/style_render.py": 13586834368514801953,
- "backend/src/services/reports/__tests__/test_report_service.py": 2262310201779987221,
- "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/METADATA": 10220680536734745103,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numerictypes.py": 8836108334624807647,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/tags.py": 254599446317461188,
- "venv/lib/python3.13/site-packages/dateutil/parser/isoparser.py": 18015430204844361067,
- "venv/lib/python3.13/site-packages/authlib/jose/errors.py": 15231759002942436632,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/publicmod.f90": 2174121054736811903,
- "venv/lib/python3.13/site-packages/pyasn1/codec/__init__.py": 15728752901274520502,
- "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/WHEEL": 13232065379159720345,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/etcd.py": 4078354986605069279,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numeric_only.py": 13610631681447961840,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/bulk_persistence.py": 2307818727114646866,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/asn1.py": 8801155055979135092,
- "venv/lib/python3.13/site-packages/pygments/lexers/vip.py": 11287963054551122004,
- "venv/lib/python3.13/site-packages/pygments/lexers/q.py": 15426466074881683794,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_round_trip.py": 14684057343786032776,
- "frontend/src/lib/components/layout/Sidebar.svelte": 18409661059413656763,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_value_counts.py": 12340872812120847127,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_ufunclike.py": 13752381070039804384,
- "frontend/build/_app/immutable/nodes/29.56ajaPq7.js": 13881277175518745666,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress.py": 5951745251426856398,
- "docker/frontend.Dockerfile": 11291701046055590331,
- "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_algorithms.py": 15219408648894515493,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_limited_api.py": 15788485008764560845,
- "venv/lib/python3.13/site-packages/pydantic/functional_validators.py": 5835339743072048940,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex.py": 16348619731902304844,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/einsumfunc.py": 9944042006439149561,
- "venv/lib/python3.13/site-packages/annotated_types/test_cases.py": 5123395674810472016,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated": 11193150813314469394,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_range.py": 3544406211185340973,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_values.py": 834951665649981397,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/__init__.py": 2345997696115514124,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py": 6067836157632573182,
- "venv/lib/python3.13/site-packages/PIL/ImagePath.py": 18323293175183057101,
- "venv/lib/python3.13/site-packages/PIL/ImImagePlugin.py": 15452956038794399492,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/temp_dir.py": 8657533190026387896,
- "venv/lib/python3.13/site-packages/numpy/lib/_iotools.pyi": 12873243737872788349,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_import_utils.py": 4029157986210295967,
- "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.pyi": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth1_session.py": 1911069558956893789,
- "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.py": 15854257948148516490,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_iteration.py": 2118501258411211851,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/common.py": 1113935558495455492,
- "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.py": 9409852116555866847,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/orderinglist.py": 10162099108656794338,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/types.py": 16795741817129898714,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_grouping.py": 5994909693214299971,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.cpython-313-x86_64-linux-gnu.so": 15960606468596245469,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.cpython-313-x86_64-linux-gnu.so": 6011605826065363427,
- "venv/lib/python3.13/site-packages/httpcore/_backends/auto.py": 10488908050307887802,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/__init__.py": 10460719978124302175,
- "venv/lib/python3.13/site-packages/pygments/styles/lilypond.py": 12486578704132023691,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.cpython-313-x86_64-linux-gnu.so": 7840846965295537844,
- "venv/lib/python3.13/site-packages/pygments/lexers/factor.py": 15788613154609197002,
- "frontend/e2e/run-enterprise-clean-e2e.sh": 11626901202531925046,
- "frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js": 10735454478982675155,
- "frontend/build/_app/immutable/chunks/DgoIDw4h.js": 10605176285482573925,
- "venv/lib/python3.13/site-packages/pandas/tests/config/test_localization.py": 9524481848419616725,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_read_errors.py": 4559483361564472117,
- "backend/src/schemas/dataset_review.py": 7490971410706145392,
- "backend/src/api/routes/__tests__/test_tasks_logs.py": 13245318244727271907,
- "backend/src/api/routes/__tests__/test_profile_api.py": 10215800611882169470,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_get_numeric_data.py": 11747933921770969706,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_complexcompat.h": 5001035774408914877,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/misc/extended_precision.pyi": 6541258584648209609,
- "backend/src/services/__tests__/test_encryption_manager.py": 11651916791559202800,
- "backend/src/services/clean_release/compliance_execution_service.py": 11572933296960110695,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_discriminated_union.py": 1818179910730401509,
- "venv/lib/python3.13/site-packages/keyring/completion.py": 1027436016070040568,
- "backend/src/plugins/mapper.py": 12075913231649127940,
- "frontend/src/routes/validation/[id]/+page.svelte": 17573557905368368906,
- "backend/src/plugins/llm_analysis/__tests__/test_screenshot_service.py": 359905908083162759,
- "backend/alembic.ini": 8897071018956157084,
- "backend/alembic/versions/ed310b33f02c_multi_language_translation_tables.py": 1424919631205944664,
- "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_builtin_md4.py": 16840174243259839994,
- "venv/lib/python3.13/site-packages/fastapi/openapi/models.py": 1680354178147364813,
- "venv/lib/python3.13/site-packages/pandas/tests/internals/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libk5crypto-b1f99d5c.so.3.1": 10669523137596317954,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/date.py": 9545774812177853725,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/foo.f90": 14491312943942432024,
- "venv/lib/python3.13/site-packages/pygments/lexers/pony.py": 2720635393743617141,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo90.f90": 3492659529812762861,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_equivalence.py": 17843623343419137458,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_applicator_schemas.py": 8395157526634674143,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/theme.py": 14225878259183479398,
- "backend/src/schemas/profile.py": 3926676368643549433,
- "backend/src/api/auth.py": 16676039157915315566,
- "backend/git_repos/remote/test-repo.git/objects/93/9cc583a18267406014c57617ccb557569f6aaf": 5474754694741999746,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.h": 4516275133897904047,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/_locales.py": 18178500267053825979,
- "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.pyi": 11535882608355652318,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_decimal.py": 3515468590005709183,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/cymysql.py": 5570881524647789741,
- "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.pyx": 5760108632332714287,
- "venv/lib/python3.13/site-packages/pygments/lexers/javascript.py": 16869490851285457857,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_chebyshev.py": 8054411443686791426,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_comparison.py": 5348781442514871089,
- "venv/lib/python3.13/site-packages/pygments/lexers/dsls.py": 11696359794961833087,
- "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/INSTALLER": 17282701611721059870,
- "backend/alembic/versions/aa1b2c3d4e5f_drop_deprecated_translate_columns.py": 15433357059529111004,
- "venv/lib/python3.13/site-packages/greenlet/TGreenletGlobals.cpp": 17400526028982558937,
- "venv/lib/python3.13/site-packages/yaml/parser.py": 18021832376874455801,
- "venv/lib/python3.13/site-packages/pip/_internal/network/cache.py": 10606522397693824641,
- "venv/lib/python3.13/site-packages/sqlalchemy/inspection.py": 8563914460959280101,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/_cryptography_key.py": 388489172928969873,
- "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so": 2888939866336522308,
- "venv/lib/python3.13/site-packages/pygments/lexers/slash.py": 8320676560518108343,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_unicode_ddl.py": 2569618488804767890,
- "venv/lib/python3.13/site-packages/numpy/_core/shape_base.pyi": 10225243791643474943,
- "backend/src/plugins/translate/__tests__/test_dictionary_prompt_builder.py": 12854863376472707556,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pyodbc.py": 11271266527234292020,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/plugin_base.py": 2880434680251108786,
- "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.pyi": 5879290708972838025,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/manifest.py": 16998683210177680416,
- "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate_regression.py": 17425202198134409689,
- "venv/lib/python3.13/site-packages/_pytest/_py/path.py": 8464061867075119556,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_ipython_compat.py": 12632271159842988561,
- "venv/lib/python3.13/site-packages/rapidfuzz/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_macos.py": 7028037591427052891,
- "frontend/build/_app/immutable/chunks/b6ODGUZr.js": 3762567609123440186,
- "backend/src/core/task_manager/event_bus.py": 1436794780600195410,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_case_justify.py": 8204537837649550062,
- "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_select_dtypes.py": 3530442956913622572,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/list/test_list.py": 4538625980063375611,
- "venv/lib/python3.13/site-packages/pandas/io/formats/excel.py": 797619981868084011,
- "backend/src/services/profile_preference_service.py": 18087455411779287894,
- "backend/src/plugins/translate/__tests__/test_scheduler.py": 5715885061128238668,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_from_scalar.py": 16520136036631155842,
- "venv/lib/python3.13/site-packages/pip/_internal/wheel_builder.py": 3893922370396791826,
- "venv/lib/python3.13/site-packages/keyring/backends/macOS/api.py": 4502902558534812719,
- "backend/tests/test_sql_table_extractor.py": 13392885324292384588,
- "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/METADATA": 4868544280955034757,
- "venv/lib/python3.13/site-packages/charset_normalizer/cd.py": 8687667152597941021,
- "frontend/src/lib/auth/permissions.js": 7186663483939824478,
- "venv/lib/python3.13/site-packages/cryptography/x509/name.py": 15338066443257445241,
- "frontend/src/lib/components/translate/TranslationRunResult.svelte": 4434171203266080686,
- "backend/tests/test_log_persistence.py": 14027169507280030218,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/min_max_.py": 13457611930368041821,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_iceberg.py": 1726421917529457420,
- "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/licenses/LICENSE": 5669644120528099197,
- "venv/lib/python3.13/site-packages/secretstorage/dhcrypto.py": 8860116996905452758,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/mod.pyi": 10591120373577657317,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/timeseries.py": 17641722582848932332,
- "venv/lib/python3.13/site-packages/pillow.libs/libwebpmux-7f11e5ce.so.3.1.2": 13105940093474848953,
- "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp.cpython-313-x86_64-linux-gnu.so": 14187094676876471848,
- "venv/lib/python3.13/site-packages/fastapi/middleware/cors.py": 7452860773712601508,
- "venv/lib/python3.13/site-packages/greenlet/CObjects.cpp": 3454797518210223926,
- "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/METADATA": 3188324716322823755,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/conftest.py": 1643522609234951699,
- "venv/lib/python3.13/site-packages/pygments/lexers/gleam.py": 5161116162065925222,
- "venv/lib/python3.13/site-packages/ecdsa/test_der.py": 7117444285097824495,
- "venv/lib/python3.13/site-packages/pygments/styles/vim.py": 2621036947954523349,
- "venv/lib/python3.13/site-packages/pygments/lexers/floscript.py": 944042220740663491,
- "venv/lib/python3.13/site-packages/pygments/lexers/graphql.py": 2307854666015224677,
- "venv/lib/python3.13/site-packages/pyasn1/__init__.py": 8089201217593738032,
- "venv/lib/python3.13/site-packages/numpy/_core/getlimits.pyi": 15746478550640231553,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_where.py": 16584772339591698754,
- "venv/lib/python3.13/site-packages/urllib3/__init__.py": 1854778274753799815,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/exc.py": 3242780937124999391,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/packaging/specifiers.py": 2800449842990194437,
- "frontend/build/_app/immutable/nodes/23.y3ghKhH-.js": 13434006313990484006,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/show.py": 11839987586497822300,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_zips.py": 5184894018177148648,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/_oid.py": 755042927629281577,
- "venv/lib/python3.13/site-packages/pandas/core/util/hashing.py": 13106575357604888913,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_partial_slicing.py": 16219611534574666182,
- "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_print.py": 598821365691498702,
- "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/METADATA": 3643456577199395707,
- "venv/lib/python3.13/site-packages/pygments/styles/__init__.py": 18383248976818885498,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/constant_time.py": 2499026008403328245,
- "venv/lib/python3.13/site-packages/pygments/styles/sas.py": 12363791134941577382,
- "venv/lib/python3.13/site-packages/pygments/lexers/tnt.py": 4657130609241407766,
- "venv/lib/python3.13/site-packages/pygments/lexers/trafficscript.py": 776604244051744646,
- "venv/bin/f2py": 11006035631504708368,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/__init__.py": 4761936067832638585,
- "frontend/build/_app/immutable/nodes/17.Dl6K4370.js": 14461856651958270415,
- "venv/lib/python3.13/site-packages/fastapi/param_functions.py": 14585101566697773072,
- "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/RECORD": 17985800801793506250,
- "venv/lib/python3.13/site-packages/pandas/_libs/hashing.cpython-313-x86_64-linux-gnu.so": 16124435225170610034,
- "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_impl.py": 12056958946481531279,
- "venv/lib/python3.13/site-packages/pygments/lexers/theorem.py": 15666523910367201285,
- "backend/src/models/__tests__/test_models.py": 7136192055672203219,
- "backend/git_repos/remote/test-repo.git/hooks/commit-msg.sample": 13435789416588783681,
- "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/RECORD": 12575893084587070195,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/util.py": 2176177435997659667,
- "backend/git_repos/remote/test-repo.git/objects/d8/3fe0db1279ef07c4c4f3de4156a629373b4057": 7507193819578792576,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.pyi": 2101854548535776875,
- "venv/lib/python3.13/site-packages/dotenv/main.py": 7408889670575271484,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/base.py": 10205051944814316388,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pymssql.py": 6650008663791598065,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nested_sequence.pyi": 11245460325970663922,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_inclusive.py": 1389676378885557519,
- "frontend/src/routes/tools/storage/+page.svelte": 8817697925409987305,
- "venv/lib/python3.13/site-packages/authlib/oidc/discovery/models.py": 6924198551176217533,
- "venv/lib/python3.13/site-packages/starlette/convertors.py": 17839747154274354605,
- "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/METADATA": 13695483537390128881,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pydantic/v1/schema.py": 10008526732895436361,
- "venv/lib/python3.13/site-packages/greenlet/TThreadStateDestroy.cpp": 13749797532421836328,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/filepost.py": 16698380375728063923,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/take.py": 3170415198452493008,
- "backend/src/core/task_manager/__tests__/test_task_logger.py": 1314432363993327738,
- "venv/lib/python3.13/site-packages/jeepney/io/blocking.py": 4699555965372200059,
- "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/WHEEL": 7454950858448014158,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/index_tricks.pyi": 11463747060334597941,
- "venv/lib/python3.13/site-packages/keyring/devpi_client.py": 3445890176686211982,
- "backend/src/scripts/seed_superset_load_test.py": 7430188463595432869,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_quarter.py": 11099677280196239755,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_twodim_base.py": 17623133613018058380,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_subclass.py": 12453252499544981915,
- "venv/lib/python3.13/site-packages/charset_normalizer/version.py": 9948878594498587774,
- "venv/lib/python3.13/site-packages/cffi/verifier.py": 8473599757770867754,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/six.py": 1161259802604920635,
- "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pxd": 14261507718442469988,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_comparisons.py": 2764694394636775220,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_cte.py": 9274103293201050794,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/json.py": 14755215397454910426,
- "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.py": 15558318749939680074,
- "venv/lib/python3.13/site-packages/websockets/asyncio/messages.py": 6848925149930551457,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/scanner.py": 5640381644804445932,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/test_pyinstaller.py": 9430762168079129025,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/INSTALLER": 17282701611721059870,
- "frontend/src/components/Footer.svelte": 12838918285533328222,
- "venv/lib/python3.13/site-packages/pydantic/v1/tools.py": 1995883197897112278,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nunique.py": 8450574751331186943,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_network.py": 13159427333040109523,
- "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pxd": 9126772093305708921,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/registration.py": 14639972512303032712,
- "venv/lib/python3.13/site-packages/cffi/_shimmed_dist_utils.py": 4824806157907607487,
- "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pygments/lexers/usd.py": 934820244673741695,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/progress_bars.py": 7584699216537478969,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/retry.py": 15244280495983216204,
- "venv/lib/python3.13/site-packages/numpy/fft/__init__.py": 9343449448737026658,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/status_codes.py": 17005213506461710202,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_na_scalar.py": 13950899907067372014,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/gh19161.f90": 7691871466158049079,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_indexing_slow.py": 12558235638488427077,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/errors.py": 2147619440137604907,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/conftest.py": 4124267277224879990,
- "venv/lib/python3.13/site-packages/sqlalchemy/__init__.py": 9751988289698484530,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex_like.py": 1407890639206728014,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/api.py": 9829629144629841277,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/session.py": 5126234270435358377,
- "venv/lib/python3.13/site-packages/idna-3.11.dist-info/WHEEL": 8600534672961461758,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/_mixins.py": 14293848457775268010,
- "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/httpx/_content.py": 1301854837767395687,
- "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/WHEEL": 15858869568085970864,
- "venv/lib/python3.13/site-packages/pygments/lexers/soong.py": 10273453675034306814,
- "venv/lib/python3.13/site-packages/pygments/lexers/teraterm.py": 16132676290138105984,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_block_docstring.py": 18146459246837890489,
- "venv/lib/python3.13/site-packages/pygments/lexers/_mapping.py": 12987629396101138833,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log10.csv": 13441294827017400897,
- "frontend/src/components/tools/MapperTool.svelte": 17206626649806308945,
- "frontend/build/_app/immutable/chunks/ZvPSSfIA.js": 7807067580962053496,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period_range.py": 9598872514187524706,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/hybrid.py": 5793056975404534989,
- "backend/src/plugins/llm_analysis/scheduler.py": 16461360386665667203,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/totp.py": 11888568940387752607,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/chararray.pyi": 9683985931409244216,
- "venv/lib/python3.13/site-packages/numpy/_core/memmap.py": 4093510602708416858,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filter.py": 16846063190466267618,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiprocessing.py": 5522490547285108448,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_between_time.py": 14266333058913745751,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/userinfo.py": 17201158389976619872,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexing.py": 5910217172351020811,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/descriptor_props.py": 7044852927393650707,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24662.f90": 4241310200087270990,
- "frontend/src/components/llm/ValidationReport.svelte": 17900215752976182981,
- "backend/src/services/dataset_review/orchestrator_pkg/_commands.py": 2554792474786179775,
- "venv/lib/python3.13/site-packages/authlib/oidc/discovery/well_known.py": 8259335680633926377,
- "backend/src/plugins/backup.py": 1465877198420371496,
- "venv/lib/python3.13/site-packages/PIL/MpegImagePlugin.py": 7726254767528154514,
- "venv/lib/python3.13/site-packages/pygments/lexers/typoscript.py": 6706632522710582762,
- "frontend/build/_app/immutable/nodes/26.BHpCifr3.js": 16416419328529145595,
- "docker/frontend.entrypoint.sh": 11397342350356400663,
- "venv/lib/python3.13/site-packages/pygments/lexers/dalvik.py": 5549983892200382076,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/calendarinterval.py": 12481650996882675949,
"venv/lib/python3.13/site-packages/pygments/lexers/_mql_builtins.py": 2376212048709413586,
- "venv/lib/python3.13/site-packages/websockets/http.py": 9406523480132204760,
- "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/METADATA": 3618776395694990076,
- "backend/src/plugins/translate/__tests__/test_dictionary.py": 17641391459012666931,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/parser.py": 1064209424435927674,
- "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd.py": 7577408467041941595,
- "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/__init__.py": 3521833849634327520,
- "venv/lib/python3.13/site-packages/pygments/lexers/eiffel.py": 8964563077187051946,
- "backend/src/plugins/storage/__init__.py": 5046554941488079204,
- "venv/lib/python3.13/site-packages/numpy/_typing/_nbit.py": 15498810174380798405,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/compat.py": 9758194415584776667,
- "venv/lib/python3.13/site-packages/httpx/_urls.py": 4219389176352582046,
- "venv/lib/python3.13/site-packages/gitdb/db/mem.py": 15823812455996199993,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py": 2042509334195547606,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_freq_code.py": 13758353172962109140,
- "dist/docker/backend.0.1.0.tar.xz": 3591917885965226179,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/applicator": 6616723520993329538,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timezones.py": 8042029178538467146,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/api.py": 13750417165301467381,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_dtype.py": 12210524152630532747,
- "backend/src/plugins/translate/events.py": 7105758998894297601,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_astype.py": 6578539240745332772,
- "venv/lib/python3.13/site-packages/pygments/styles/monokai.py": 12381683616720952636,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_utils.pyi": 12312677132342982866,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_html.py": 7947998260347730581,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_warnings.py": 13071210233876253749,
- "backend/src/core/config_models.py": 8511221948925595347,
- "backend/tests/test_core_scheduler.py": 2305397851769292578,
- "venv/lib/python3.13/site-packages/pandas/tests/tools/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/git/diff.py": 6691274015605451565,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_diff.py": 2216748778018882333,
- "venv/lib/python3.13/site-packages/pluggy/_manager.py": 18202550145040079612,
- "venv/lib/python3.13/site-packages/attrs/__init__.pyi": 14353885498883901855,
- "venv/lib/python3.13/site-packages/pyasn1/type/constraint.py": 16776615503418773283,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py": 14216912708889351810,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/base.py": 17992335652981439676,
- "venv/lib/python3.13/site-packages/passlib/tests/__main__.py": 16477180140297957650,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/live_render.py": 14619617939683800204,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_infer_objects.py": 6769980076977692890,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77comments.f": 4801926170672147659,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/LICENSE": 14599279238716790189,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py": 17221368219485351394,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_histograms.py": 47631283818191049,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/control.py": 2034518223411945438,
- "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex.py": 8772423071604000084,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/instrumentation.py": 14882045449667214075,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_fillna.py": 9297637486401098611,
- "venv/lib/python3.13/site-packages/uvicorn/__init__.py": 11517239807926185665,
- "backend/src/plugins/git/llm_extension.py": 5713196889309291531,
- "frontend/playwright.config.js": 13110145576439798725,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/block_docstring/foo.f": 2489756567993745076,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_two_greenlets.py": 11156275429806391390,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/parameters.py": 12219404446503940066,
- "venv/lib/python3.13/site-packages/idna/package_data.py": 6583909243002417298,
- "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/RECORD": 7266315886702289726,
- "venv/lib/python3.13/site-packages/pyasn1/codec/streaming.py": 13202773554072937140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_insert.py": 15536994417338770457,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_multi.py": 4612816468258071810,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_downcast.py": 10399746645741452200,
- "venv/lib/python3.13/site-packages/numpy/_core/defchararray.pyi": 2277933368373498515,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test__version.py": 9037916251087760255,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/accumulate.py": 5780225603819849877,
- "venv/lib/python3.13/site-packages/pydantic/validators.py": 8292819706488319845,
- "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas7bdat.py": 8963983384208121526,
- "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.py": 3654583356259850174,
- "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/licenses/LICENSE": 1424673738228762254,
- "venv/lib/python3.13/site-packages/pandas/_libs/internals.pyi": 11662356720550765508,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.c": 11535375410441493281,
- "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.pyi": 5786150108623563787,
- "venv/lib/python3.13/site-packages/pandas/compat/_constants.py": 3909166275649444824,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.py": 503331864022631297,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategy_options.py": 16342048970907383117,
- "frontend/e2e/tests/login.e2e.js": 9217667783118672119,
- "venv/lib/python3.13/site-packages/PIL/XbmImagePlugin.py": 12256750478268246137,
- "frontend/src/lib/components/DashboardMaintenanceBadge.svelte": 9085495636438661604,
- "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.pyi": 10638891136586198429,
- "venv/lib/python3.13/site-packages/pygments/lexers/hdl.py": 6772823608124143123,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npy": 17303060773267383537,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/check.py": 6937252393012787214,
- "backend/src/core/utils/fileio.py": 8848681882907859355,
- "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/zip-safe": 15240312484046875203,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_version.py": 6317733744899804292,
- "venv/lib/python3.13/site-packages/pandas/core/strings/accessor.py": 14021462534679430426,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authenticate_client.py": 16886645731942472285,
- "venv/lib/python3.13/site-packages/dateutil/zoneinfo/__init__.py": 10261654903106416888,
- "venv/lib/python3.13/site-packages/greenlet/TThreadStateCreator.hpp": 9887867766190459665,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py": 18325640697829098192,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/base.py": 5294446834530589760,
- "backend/src/models/dataset_review.py": 18282368342351080120,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_raises.py": 9678418010293693275,
- "backend/git_repos/remote/test-repo.git/objects/e9/1109abe29d5228675fecd6fc38a097147c090d": 15716642455993350072,
- "backend/git_repos/remote/test-repo.git/objects/5a/82ef700fef88b69cd480e4025283809496ee20": 7003383965314354150,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/pyinstaller-smoke.py": 13570990531070630950,
- "venv/lib/python3.13/site-packages/passlib/handlers/postgres.py": 14162382430051693313,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dot.py": 16876560325283070437,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/entities.py": 8001287806688585081,
- "backend/git_repos/remote/test-repo.git/refs/heads/preprod": 2288780285329550368,
- "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/licenses/LICENSE": 6808958893921859106,
- "venv/lib/python3.13/site-packages/websockets/sync/messages.py": 15699091325918681038,
- "frontend/src/components/tasks/LogEntryRow.svelte": 7224781044020990429,
- "venv/lib/python3.13/site-packages/pydantic_settings/__init__.py": 4374954204580208673,
- "venv/lib/python3.13/site-packages/pandas/_libs/join.pyi": 369262334342439364,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_string.py": 15542851215119662814,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_strings.py": 17398806130402098912,
- "backend/src/services/__init__.py": 15123879863527585264,
- "venv/lib/python3.13/site-packages/fastapi/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/cryptography/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/pascal.py": 5992422120590352714,
+ "venv/lib/python3.13/site-packages/anyio/_core/_resources.py": 8463932838064724564,
+ "venv/lib/python3.13/site-packages/numpy/_core/overrides.pyi": 13121243505132110607,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/mypy.py": 823265492261272631,
+ "venv/bin/pip3": 13861749540792881808,
+ "venv/lib/python3.13/site-packages/websockets/legacy/framing.py": 12759022769700230409,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/requirements.py": 13215932786801020434,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/rule.py": 5318344538761246105,
+ "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/METADATA": 13695483537390128881,
+ "venv/lib/python3.13/site-packages/numpy/core/records.py": 12604652690721760437,
"venv/lib/python3.13/site-packages/numpy/random/_sfc64.cpython-313-x86_64-linux-gnu.so": 17186695607612591922,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/core": 6622984507059115517,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctanh.csv": 8620268345075425735,
- "venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py": 6167729964577005634,
- "backend/src/core/mapping_service.py": 5863886462891122323,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_wrappers.py": 4813328996575597980,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23879.f90": 13174951794239860144,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pipe.py": 7400355977900310233,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/string.f": 17328443345813567449,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/state.py": 10500170103357297551,
- "frontend/src/components/git/useGitManager.js": 1649936771399080281,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/matrix.pyi": 15667024840812783911,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/core.py": 2199607970842512780,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.pyi": 3595910367556664837,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_produces_warning.py": 750781117570375777,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_conversion.py": 7507083194555424923,
+ "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.pyi": 362674842164060822,
+ "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.pyi": 7171810177801103765,
+ "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/INSTALLER": 17282701611721059870,
+ "frontend/src/routes/datasets/DatasetPreview.svelte": 4250995999947659034,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/nested_schemas.py": 4114645644496880787,
+ "backend/src/core/task_manager/task_logger.py": 6134165406387688582,
+ "backend/src/api/routes/__tests__/test_tasks_logs.py": 13245318244727271907,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_conversion_utils.py": 1567199588622767277,
+ "venv/bin/pygmentize": 2166491742035772877,
+ "venv/lib/python3.13/site-packages/passlib/handlers/__init__.py": 3424087230285514388,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/__init__.py": 11808051681178127650,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2cffi.py": 5997687240967250164,
+ "backend/src/api/routes/clean_release_v2.py": 7430240321470425220,
+ "backend/tests/test_core_scheduler.py": 2305397851769292578,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/console.py": 10370334487585281127,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.pyi": 1830368009811266890,
+ "venv/lib/python3.13/site-packages/ecdsa/der.py": 9374566189581725372,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_timestamp_method.py": 11393911418463808195,
+ "venv/lib/python3.13/site-packages/PIL/report.py": 9428754440615681790,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_join.py": 1131792466825856990,
+ "venv/lib/python3.13/site-packages/jsonschema/__main__.py": 18136546137047911521,
+ "venv/lib/python3.13/site-packages/pandas/tests/tools/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_downcast.py": 10399746645741452200,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/util.py": 387985965709546512,
+ "venv/lib/python3.13/site-packages/PIL/PcxImagePlugin.py": 1691405132377495336,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/mock.py": 6849131425727092784,
+ "backend/git_repos/remote/test-repo.git/objects/ed/0432f88f5f7d95b26ecde34345abe741dd9db2": 13426916511127204463,
+ "venv/lib/python3.13/site-packages/fastapi/security/oauth2.py": 1925394177931547776,
+ "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/METADATA": 2624107638694809013,
+ "venv/lib/python3.13/site-packages/gitdb/db/ref.py": 1176701624460337371,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_argsort.py": 7320661835159648143,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_mapping.py": 12987629396101138833,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_arrow_compat.py": 17818294260710640443,
+ "frontend/src/lib/ui/Button.svelte": 14815370250842191735,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/ber/decoder.py": 12653470212935324322,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_localize.py": 18409231586451494605,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename.py": 16148017223289654683,
+ "venv/lib/python3.13/site-packages/pandas/arrays/__init__.py": 10005095663840461954,
+ "frontend/src/lib/components/layout/Sidebar.svelte": 18409661059413656763,
+ "venv/lib/python3.13/site-packages/pandas/api/types/__init__.py": 3995030354191071797,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/__init__.py": 13331622784664204066,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_select_dtypes.py": 3530442956913622572,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_read_fwf.py": 13684564756628524738,
+ "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/jeepney/bindgen.py": 7094585345946943534,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/bar.py": 12859947592168238832,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_function.py": 14142346897145169685,
+ "venv/lib/python3.13/site-packages/cffi/vengine_gen.py": 6582900613549620556,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_ufunc.py": 3326502989311831856,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_rowcount.py": 6682800584070485197,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/instrumentation.py": 13198832283145198959,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pydantic_settings/exceptions.py": 18300876747412267999,
+ "venv/lib/python3.13/site-packages/PIL/_binary.py": 14039167720582222043,
+ "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/licenses/LICENSE": 3509878235770224233,
+ "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/WHEEL": 13232065379159720345,
+ "venv/lib/python3.13/site-packages/pydantic/main.py": 14086938579850319884,
+ "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/RECORD": 8201759541483070364,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/multiarray.pyi": 6368268452184570195,
+ "venv/lib/python3.13/site-packages/sqlalchemy/future/engine.py": 4639404437703898767,
+ "frontend/src/lib/toasts.js": 17626443524470260846,
+ "venv/lib/python3.13/site-packages/pydantic/decorator.py": 6984214881365537811,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_constructors.py": 5627819885594450614,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/filesystem.py": 7716285033598020316,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_astype.py": 11386658862732393123,
+ "venv/lib/python3.13/site-packages/pygments/styles/dracula.py": 12379322008538174078,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/types.py": 12298292195929126306,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ptx.py": 4855144232064607995,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/database.py": 7111764828004587758,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_snap.py": 4515844385819802784,
+ "frontend/src/lib/ui/Input.svelte": 1114920008107220678,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/memmap.pyi": 2834143910417841603,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pop.py": 14885271225856187795,
+ "venv/lib/python3.13/site-packages/PIL/_webp.cpython-313-x86_64-linux-gnu.so": 11070012119632935103,
+ "backend/src/core/config_manager.py": 1668206562922192026,
+ "frontend/src/components/tasks/LogEntryRow.svelte": 7224781044020990429,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi": 3254633032236269842,
+ "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.py": 14696841109142419143,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/unistring.py": 18037463865539157041,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi": 1065808244870331598,
+ "venv/lib/python3.13/site-packages/_pytest/mark/expression.py": 1821437025841201912,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_string.py": 9224234539232195189,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/logging.py": 2426447364230673649,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_like.py": 2778905818573625118,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_auth.py": 15125055415702968414,
+ "venv/lib/python3.13/site-packages/uvicorn/_subprocess.py": 13965754246493254447,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/contains.py": 3098087827310439993,
+ "venv/lib/python3.13/site-packages/h11/_version.py": 9334144031400715479,
+ "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/RECORD": 12598309574903741388,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_extension_interface.py": 11693583111513457974,
+ "venv/lib/python3.13/site-packages/numpy/__config__.pyi": 1422114139050700402,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_loongarch64_linux.h": 6566098590441297326,
+ "venv/lib/python3.13/site-packages/numpy/lib/scimath.py": 7616377937400918724,
+ "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.py": 8786558894094307341,
+ "venv/lib/python3.13/site-packages/pandas/util/version/__init__.py": 3844072588696074141,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/METADATA": 5045041742469375466,
+ "venv/lib/python3.13/site-packages/jsonschema/__init__.py": 6925762200139836824,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_empty.py": 6845813091876023610,
+ "venv/lib/python3.13/site-packages/cffi/_shimmed_dist_utils.py": 4824806157907607487,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dh.py": 5728866271812501558,
+ "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/WHEEL": 7454950858448014158,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_multiplier.f": 13432803601367981068,
+ "venv/lib/python3.13/site-packages/sqlalchemy/event/registry.py": 2857989070743633709,
+ "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py": 7676937747094511752,
+ "venv/lib/python3.13/site-packages/pygments/styles/native.py": 4559566444883341527,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_any_index.py": 10800968419286329268,
+ "venv/lib/python3.13/site-packages/numpy/random/_pickle.py": 7774620933480975313,
"venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/WHEEL": 12054782055241301457,
+ "venv/lib/python3.13/site-packages/pygments/lexers/praat.py": 54226477748516386,
+ "venv/lib/python3.13/site-packages/pygments/lexers/meson.py": 14659991367778746658,
+ "frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte": 1996807488169542658,
+ "frontend/build/_app/immutable/nodes/29.C8L9v-j-.js": 1676851498074311321,
+ "backend/src/api/routes/git/_repo_lifecycle_routes.py": 410621371876058173,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_indexing.py": 17106010337164216722,
+ "backend/tests/test_translate_scheduler_guard.py": 13396608843530344156,
+ "venv/lib/python3.13/site-packages/greenlet/PyGreenletUnswitchable.cpp": 3160733517193315684,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.pyi": 17528421279543420867,
+ "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/WHEEL": 8600534672961461758,
+ "venv/lib/python3.13/site-packages/pygments/lexers/floscript.py": 944042220740663491,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-expm1.csv": 8710594949902856122,
+ "venv/lib/python3.13/site-packages/smmap/test/test_buf.py": 6910367739329016619,
+ "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/WHEEL": 13347410390513723930,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_pbkdf2.py": 4977067068389993374,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_index.py": 12015738970771703312,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/utils.py": 3710235316419562274,
+ "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/licenses/LICENSE.rst": 5960743202700406649,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators.py": 9928398334052202841,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/retry.py": 15244280495983216204,
+ "frontend/build/_app/immutable/chunks/Dcd-DQu-.js": 17770623202860803448,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_iceberg.py": 1726421917529457420,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_explode.py": 16195468192763502449,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_compression.py": 3167245427092658522,
+ "venv/lib/python3.13/site-packages/h11/_abnf.py": 10456996134895429201,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/_ranges.py": 2572903460327860111,
+ "venv/lib/python3.13/site-packages/secretstorage/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_invalid_arg.py": 610891871484326055,
+ "venv/lib/python3.13/site-packages/numpy/_core/strings.pyi": 1981676808027146409,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_common.py": 12064185052519470358,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html.tpl": 12550218314797699304,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/securetransport.py": 12104888897121018676,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/engines.py": 10876954465293959720,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py": 11425629729736599320,
+ "venv/lib/python3.13/site-packages/PIL/WalImageFile.py": 12442826195371137238,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py": 6109201994963211857,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/six.py": 1161259802604920635,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi": 1846673463183660140,
+ "venv/lib/python3.13/site-packages/pandas/__init__.py": 793698514004377486,
+ "venv/lib/python3.13/site-packages/PIL/SpiderImagePlugin.py": 12234762087257163606,
+ "venv/lib/python3.13/site-packages/PIL/GdImageFile.py": 16875784236394545058,
+ "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.pyi": 5892973170789971535,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/errors.py": 10750605030539582738,
+ "venv/lib/python3.13/site-packages/numpy/lib/format.py": 14971167445246135440,
+ "venv/lib/python3.13/site-packages/PIL/PaletteFile.py": 4104323659569809769,
+ "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__init__.py": 2833016678144975576,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_eng_formatting.py": 14768815444701392013,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/api.py": 12339139862411341381,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/sessions.py": 5400174351499383072,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/fetch.py": 13937019222549208796,
+ "venv/lib/python3.13/site-packages/pygments/lexers/graphics.py": 13783143864729682444,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming_py.py": 16133454512601432815,
+ "venv/lib/python3.13/site-packages/pygments/lexers/asm.py": 13861952972248758785,
+ "venv/lib/python3.13/site-packages/pygments/styles/sas.py": 12363791134941577382,
+ "venv/lib/python3.13/site-packages/pygments/lexers/wowtoc.py": 17527844575999013592,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_printing.py": 1901396869745313303,
+ "venv/lib/python3.13/site-packages/pygments/lexers/dsls.py": 11696359794961833087,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_sorting.py": 8944017570338511677,
+ "venv/lib/python3.13/site-packages/pygments/lexers/textfmts.py": 17438453283146671997,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_index_col.py": 17604191644943383567,
+ "venv/lib/python3.13/site-packages/pygments/lexers/berry.py": 4540479522141160472,
+ "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_is_full.py": 9577318758326279694,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/warnings.py": 2552021607611112605,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_chebyshev.py": 8054411443686791426,
+ "venv/lib/python3.13/site-packages/httpcore/_ssl.py": 6665087294869504820,
+ "venv/lib/python3.13/site-packages/_pytest/threadexception.py": 10464996327276961035,
+ "frontend/src/routes/translate/[id]/+page.svelte": 1911443262444004956,
+ "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_regression.py": 5652583095949741238,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libsasl2-883649fd.so.3.0.0": 13306917506408577991,
+ "backend/src/core/utils/superset_context_extractor/_pii.py": 15135596230141304567,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_take.py": 9847808489301498487,
+ "venv/lib/python3.13/site-packages/secretstorage/__init__.py": 4535964275649588672,
+ "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/_pytest/assertion/util.py": 16957445183087315124,
+ "venv/lib/python3.13/site-packages/pydantic/validate_call_decorator.py": 11130572937843915026,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_getlimits.py": 118041882543413669,
+ "venv/lib/python3.13/site-packages/pandas/core/window/doc.py": 4204367435727844696,
+ "backend/src/api/routes/assistant/_dispatch.py": 12376888449563411982,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_argparse.py": 11111699418217357084,
+ "venv/lib/python3.13/site-packages/apscheduler/util.py": 11440701924954413440,
+ "frontend/src/components/git/ConflictResolver.svelte": 12314421232300049275,
+ "backend/src/api/routes/dashboards/_helpers.py": 13624740316332136004,
+ "frontend/src/routes/datasets/review/ReviewWorkspaceHeader.svelte": 15302107925819930527,
+ "backend/src/services/clean_release/__tests__/test_compliance_orchestrator.py": 15537957042757255513,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine.py": 4446011286411407708,
+ "backend/src/core/auth/security.py": 11836436636390315707,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.cpython-313-x86_64-linux-gnu.so": 2311012065007769341,
+ "venv/lib/python3.13/site-packages/cffi/commontypes.py": 11198107299826138465,
+ "venv/lib/python3.13/site-packages/tzlocal/utils.py": 7893867974548929154,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_feather.py": 13613400750755530364,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/yaml.py": 17801117405950663611,
+ "venv/lib/python3.13/site-packages/typing_inspection/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic/config.py": 1450073446492183677,
+ "venv/lib/python3.13/site-packages/rapidfuzz/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet.h": 16216120538647882082,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/aead.py": 8740476942925346444,
+ "venv/lib/python3.13/site-packages/numpy/core/overrides.pyi": 1968648615494204783,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dtype.py": 5336980126536664360,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/validation": 5398883285871046811,
+ "venv/lib/python3.13/site-packages/pandas/util/_test_decorators.py": 17930801441803090445,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/json/__init__.py": 7877061921210840955,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_asof.py": 8656532774394927388,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/categorical.py": 16588862198627920420,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_subclass.py": 12453252499544981915,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_iter.py": 9232021002336641851,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_range.py": 3544406211185340973,
+ "venv/lib/python3.13/site-packages/referencing/exceptions.py": 2535322334430110414,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge.py": 11366935134260232329,
+ "backend/src/schemas/profile.py": 3926676368643549433,
+ "venv/lib/python3.13/site-packages/requests/__init__.py": 2604491098990438229,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/operators.py": 2468046993343796128,
+ "backend/src/api/routes/plugins.py": 6640856303389338188,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_values.py": 12064896795288302730,
+ "backend/src/models/__init__.py": 13280325675752905975,
+ "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/_gen_files.py": 6273314671315377131,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimes.py": 14331984919364185787,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/asn1.py": 8801155055979135092,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_datetimeindex.py": 14816894350435545024,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers.py": 4940305787631493030,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_dropna.py": 3620959914439334511,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/use_modules.f90": 3913612933340746297,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_hour.py": 14128508606361694814,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml.py": 6906547816798138000,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_constructors.py": 17219764538851313252,
+ "venv/bin/activate.csh": 14513616043256836238,
+ "frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js": 7546622841909210622,
+ "backend/src/services/profile_service.py": 7050751066987031905,
+ "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/licenses/COPYING": 15270149301471737292,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_between.py": 337429135216881486,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_numba.py": 8250377774229977284,
+ "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/eval.py": 3176226283265954028,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_constructors.py": 7466113171256856591,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/__init__.py": 237070345717942041,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ext.py": 8361831054662096695,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/interval.py": 16281221279220043867,
+ "venv/lib/python3.13/site-packages/pandas/_version_meson.py": 4875297137037630519,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/twodim_base.pyi": 3773329770170248877,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hiworld.f90": 6321872653169140461,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_year.py": 1478857009124807836,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/_typing.py": 17598638528781632158,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_pyf_src.py": 12351476647369971852,
+ "venv/lib/python3.13/site-packages/pycparser/ply/ygen.py": 5520340773074632724,
+ "venv/lib/python3.13/site-packages/pygments/styles/friendly.py": 13799024964803741891,
+ "venv/lib/python3.13/site-packages/pygments/lexers/mojo.py": 8616283481592061285,
+ "frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js": 8052627851850386760,
+ "venv/lib/python3.13/site-packages/gitdb/db/base.py": 3375449584942578385,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_pickle.py": 388513670243918273,
+ "venv/lib/python3.13/site-packages/anyio/_core/_tempfile.py": 230288423480899091,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_cut.py": 7800833253841657380,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_year.py": 17441853503700184299,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_truncate.py": 9623613657871046837,
+ "frontend/src/routes/datasets/[id]/+page.svelte": 7539252327680602221,
+ "backend/src/api/routes/dataset_review.py": 6955521302681155464,
+ "backend/src/plugins/translate/preview_executor.py": 11680052270975606699,
+ "venv/lib/python3.13/site-packages/fastapi/requests.py": 14587947416691824903,
+ "backend/git_repos/remote/test-repo.git/objects/5a/82ef700fef88b69cd480e4025283809496ee20": 7003383965314354150,
+ "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.py": 2490579175967301457,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_fds.py": 6257376331171761928,
+ "venv/lib/python3.13/site-packages/pygments/styles/lovelace.py": 15082819162722685616,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/WHEEL": 8600534672961461758,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/http11.py": 5947339024588907032,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_indexing_slow.py": 12558235638488427077,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_head_tail.py": 13047338070883375426,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py": 1331438198531942242,
+ "venv/lib/python3.13/site-packages/pandas/io/parsers/c_parser_wrapper.py": 5841064965672872661,
+ "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.cpython-313-x86_64-linux-gnu.so": 13917011878259810696,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/models.py": 9513172366009392193,
+ "venv/lib/python3.13/site-packages/passlib/exc.py": 15559705487889657091,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_period.py": 12593777226419608212,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_from_dummies.py": 5670811108950300761,
+ "frontend/build/_app/immutable/nodes/30.CRJJ7spc.js": 16603457266634306242,
+ "venv/lib/python3.13/site-packages/pyasn1/compat/__init__.py": 5902203086150636670,
+ "backend/src/services/__tests__/test_resource_service.py": 7247551330585718683,
+ "backend/src/plugins/translate/service_target_schema.py": 5277952452702772295,
+ "backend/git_repos/remote/test-repo.git/objects/38/0395343915d386a8d58774cc6c6677205065e8": 5481382229802988191,
+ "venv/lib/python3.13/site-packages/pydantic/v1/decorator.py": 6124748023704700724,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numeric_only.py": 13610631681447961840,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_base.py": 8678387511873412922,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libk5crypto-b1f99d5c.so.3.1": 10669523137596317954,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_compare.py": 171535659467902751,
+ "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.pyi": 1424133074692438241,
+ "frontend/build/_app/immutable/nodes/31.DV0Ccxlo.js": 16322558656544018129,
+ "venv/lib/python3.13/site-packages/jeepney/fds.py": 16573439672758641560,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_polynomial.pyi": 9134949577567498894,
+ "venv/lib/python3.13/site-packages/sqlalchemy/event/attr.py": 5971663429221923939,
+ "venv/lib/python3.13/site-packages/numpy/typing/__init__.py": 3608665862759745048,
+ "venv/lib/python3.13/site-packages/dateutil/tz/_factories.py": 7538654189286887518,
+ "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/RECORD": 15194367076254806710,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/style.py": 13235403689320479165,
+ "venv/lib/python3.13/site-packages/rapidfuzz/_common_py.py": 15410157970973169427,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/tornado.py": 6491136785917169991,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/ber/eoo.py": 5126566925877730303,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/strings/__init__.pyi": 6213864891045042045,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/date.py": 9545774812177853725,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/plugin.py": 18006138132596504101,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_aix.h": 13316272821279308986,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/__init__.py": 7526309124863950484,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_analytics.py": 4510712334676848202,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_subclass.py": 11096337912872573314,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/pool.py": 10344126569001032241,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/index_tricks.py": 10051261976498916957,
+ "venv/lib/python3.13/site-packages/PIL/_imagingcms.pyi": 12476347428820346383,
+ "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/WHEEL": 7454950858448014158,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/_cryptography_key.py": 388489172928969873,
+ "venv/lib/python3.13/site-packages/pygments/styles/pastie.py": 15784474766258831882,
+ "venv/lib/python3.13/site-packages/pygments/lexers/whiley.py": 218468511185731869,
+ "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/RECORD": 8971487317739420905,
+ "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/METADATA": 6656194161182818439,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi": 10548370574281981402,
+ "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.py": 548928042543500365,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/negative_bounds/issue_20853.f90": 3911644649277659333,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/api.py": 17919983681396223380,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg_catalog.py": 15726448028057859831,
+ "venv/lib/python3.13/site-packages/PIL/CurImagePlugin.py": 17697303205012181529,
+ "venv/lib/python3.13/site-packages/_pytest/_io/terminalwriter.py": 16852767249156780980,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_csv.py": 571991535656576735,
+ "frontend/src/routes/datasets/review/[id]/+page.svelte": 3692143812318259790,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/properties.py": 5799883762127872919,
+ "venv/lib/python3.13/site-packages/pygments/lexers/verification.py": 16645885125604874183,
+ "venv/lib/python3.13/site-packages/fastapi/concurrency.py": 17937688838625807004,
+ "frontend/playwright-report/data/dcf41bdb395adaf70707a711375fd3b464dd384f.webm": 3819814233647777883,
+ "frontend/src/lib/stores.js": 8225317698711142177,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_quantile.py": 11966156706220948315,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_repr.py": 7552782621374439569,
+ "venv/lib/python3.13/site-packages/pandas/_testing/asserters.py": 272063856832951430,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tnt.py": 4657130609241407766,
+ "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_numeric.py": 18037815278545274402,
+ "venv/lib/python3.13/site-packages/pandas/io/feather_format.py": 13242733585787888812,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_setitem.py": 15731267129055947469,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/structures.py": 2668010839316715865,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_categorical.py": 1329115818264527103,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/use_data.f90": 14624074967635860696,
+ "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/LICENSE": 17675192170670564526,
+ "venv/lib/python3.13/site-packages/_pytest/config/compat.py": 13175516717549204627,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_clipboard.py": 12674078499544938252,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_xport.py": 14080914637071212225,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pymysql.py": 12923876736367229454,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/req_uninstall.py": 3515239440812977025,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/default_styles.py": 4469204219504675080,
+ "venv/lib/python3.13/site-packages/_pytest/warnings.py": 8633394774569709013,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_openpyxl.py": 6676451564208867775,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/provision.py": 13156893203444936309,
+ "venv/lib/python3.13/site-packages/httpcore/_exceptions.py": 6716590711697088732,
+ "venv/lib/python3.13/site-packages/python_multipart/decoders.py": 14252672585219598429,
+ "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/resolution.py": 5132658725516243311,
+ "frontend/src/routes/admin/users/+page.svelte": 6187566471376083204,
+ "frontend/build/_app/immutable/nodes/21.D7rDHp05.js": 15812987310719032697,
+ "venv/lib/python3.13/site-packages/httpx/_main.py": 1812303705973265093,
+ "venv/lib/python3.13/site-packages/numpy/exceptions.py": 10981418339663118022,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_python_parser_only.py": 12231449578582108346,
+ "venv/lib/python3.13/site-packages/pygments/styles/gh_dark.py": 7717523746712391809,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_common.f": 5913807803369559749,
+ "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/LICENSE": 6774760218010069963,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_set_value.py": 17480833128128893268,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_scheme_builtins.py": 5722444920479775453,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_byteswap.py": 5090287710338893350,
+ "backend/src/core/auth/__init__.py": 16435384828055133073,
+ "backend/src/services/dataset_review/clarification_engine.py": 16343602687904467259,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/claims.py": 14794441479740527265,
+ "venv/lib/python3.13/site-packages/_yaml/__init__.py": 3395829783751571350,
+ "venv/lib/python3.13/site-packages/pandas/core/shared_docs.py": 2173578869755325502,
+ "venv/lib/python3.13/site-packages/pandas/core/indexers/__init__.py": 1756397319068017890,
+ "backend/src/models/report.py": 12105030884508258995,
+ "venv/lib/python3.13/site-packages/httpcore/_async/__init__.py": 491192949420297153,
+ "venv/lib/python3.13/site-packages/_pytest/_version.py": 4890545974654141536,
+ "backend/src/plugins/translate/service_inline_correction.py": 11066393548140180037,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/spinners.py": 7664056305019151182,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/conftest.py": 13381752264278264218,
+ "venv/lib/python3.13/site-packages/numpy/dtypes.pyi": 6713822658171717369,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_reductions.py": 1713831062142840146,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/events.py": 7576713358952064464,
+ "venv/lib/python3.13/site-packages/numpy/ma/extras.pyi": 15292036493781556342,
+ "backend/src/core/utils/matching.py": 1700014874878218207,
+ "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/licenses/LICENSE": 5563356551734678258,
+ "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.py": 6205675182996213576,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_memmap.py": 8709963808115492688,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.cpython-313-x86_64-linux-gnu.so": 11019871270094058038,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_julian_date.py": 850085757774959003,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/key_set.py": 8485970749081951741,
+ "venv/lib/python3.13/site-packages/pygments/lexers/rust.py": 8605690716125176329,
+ "frontend/src/lib/api/reports.js": 12520710039739782171,
+ "backend/src/core/encryption_key.py": 3858659138244440938,
+ "venv/lib/python3.13/site-packages/charset_normalizer/utils.py": 11724147997933584095,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_util.py": 6664989864423807444,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/traceback.py": 2535227583726271746,
+ "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/RECORD": 2963644632913976754,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_floatingpoint_errors.py": 4301355720042319835,
+ "venv/lib/python3.13/site-packages/pandas/core/window/numba_.py": 1444123360986509769,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo90.f90": 3492659529812762861,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite_e.py": 8912795372542950449,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_compiler_compat.hpp": 465436185632243991,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django.py": 3210697476292094384,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distro/__init__.py": 11414161642984633362,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.pyi": 11580106670226366710,
+ "frontend/src/components/__tests__/task_log_viewer.test.js": 4344163242946147110,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_nanfunctions.py": 2356468092336024365,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23879.f90": 13174951794239860144,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/LICENSE": 12688029424398428498,
+ "venv/lib/python3.13/site-packages/pandas/_typing.py": 17795648994662434211,
+ "venv/lib/python3.13/site-packages/_pytest/main.py": 931018496411984909,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.pyi": 11310761736182213265,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/engines.py": 1889823242704769952,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/rec.pyi": 14615751247243515028,
+ "frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js": 5982682724976240528,
+ "venv/lib/python3.13/site-packages/requests/compat.py": 5836590172733661320,
+ "backend/tests/test_resource_hubs.py": 1620639151885021568,
+ "venv/lib/python3.13/site-packages/authlib/oidc/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/size/foo.f90": 18067977329435720684,
+ "backend/src/core/task_manager/__tests__/test_task_logger.py": 2358230637213309608,
+ "venv/lib/python3.13/site-packages/fastapi/testclient.py": 2606236077497278662,
+ "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/utils.py": 617314300548081590,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_hashing.py": 11119284926039008503,
+ "venv/lib/python3.13/site-packages/starlette/_utils.py": 8384087194580626069,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_hashtable.py": 2620207240930665390,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_numpy.py": 222383250675686477,
+ "frontend/playwright-report/data/a19c216148b1612f8e11679d34071559b77021a0.png": 2734494351837969206,
+ "backend/src/core/utils/superset_context_extractor/_filters.py": 14230663187221307078,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/python3.npy": 4957143805477405905,
+ "backend/src/services/clean_release/__tests__/test_report_builder.py": 11856874434357958029,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/astype.py": 9925183787411796679,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/auth.py": 912521029864094489,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/gevent.py": 17122637996105344344,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_fillna.py": 7349777469648334282,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_astype.py": 15768655715952923925,
+ "venv/lib/python3.13/site-packages/pygments/lexers/capnproto.py": 15713281507099411738,
+ "venv/lib/python3.13/site-packages/pygments/lexers/futhark.py": 10102535873433759899,
+ "backend/git_repos/remote/test-repo.git/info/exclude": 6403833611826357791,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_dtypes.py": 481191723198819568,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/conftest.py": 16571782049241458769,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/AUTHORS": 3558407083075395848,
+ "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/RECORD": 16740224557818847141,
+ "venv/lib/python3.13/site-packages/_pytest/debugging.py": 16135285365306979060,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_counting.py": 5628494712451120258,
+ "venv/lib/python3.13/site-packages/attr/filters.py": 14156141488477438777,
+ "venv/lib/python3.13/site-packages/uvicorn/_compat.py": 2593000889619875759,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/string_arrow.py": 16997970607998635570,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/socks.py": 17581293673028078134,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/__init__.py": 7316739139609490520,
+ "venv/lib/python3.13/site-packages/pygments/lexers/math.py": 1647133236144311250,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp.cpython-313-x86_64-linux-gnu.so": 10263790384087091349,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append_common.py": 2377351120083195530,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/smv.py": 8253688483040957894,
+ "frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte": 2349700459673295788,
+ "frontend/src/components/git/GitReleasePanel.svelte": 11177244258160406730,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/accessors.py": 12743680296510533030,
+ "venv/lib/python3.13/site-packages/pandas/_libs/hashing.cpython-313-x86_64-linux-gnu.so": 16124435225170610034,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/reporters.py": 10760889726586439724,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_complex.py": 12963449957363121481,
+ "frontend/build/_app/immutable/chunks/ZvPSSfIA.js": 7807067580962053496,
+ "backend/git_repos/remote/test-repo.git/refs/heads/preprod": 2288780285329550368,
+ "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/WHEEL": 9788895026336324100,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_openid.py": 5670082466989878756,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_hist_box_by.py": 16197297231683144299,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/debug.py": 13528633965821062950,
+ "backend/git_repos/remote/test-repo.git/objects/e9/1109abe29d5228675fecd6fc38a097147c090d": 15716642455993350072,
+ "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.py": 6142062990691556076,
+ "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/npymath.ini": 1071371630695963467,
+ "venv/lib/python3.13/site-packages/charset_normalizer/__init__.py": 12412600648990392633,
+ "venv/lib/python3.13/site-packages/uvicorn/loops/auto.py": 13086005977087619545,
+ "venv/lib/python3.13/site-packages/starlette/background.py": 10232175205397808417,
"frontend/src/components/TaskRunner.svelte": 12776680477391915065,
- "venv/lib/python3.13/site-packages/psycopg2/_ipaddress.py": 12332672835751787869,
- "venv/lib/python3.13/site-packages/starlette/exceptions.py": 15978811612997200737,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_config.py": 12760390602912369447,
+ "venv/lib/python3.13/site-packages/pandas/errors/__init__.py": 13444371880185740908,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/conftest.py": 12368472226536104037,
+ "frontend/static/favicon.svg": 6451919037497541980,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/poolmanager.py": 5071697837617938064,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-1.csv": 16078879475693341404,
+ "venv/lib/python3.13/site-packages/PIL/TiffTags.py": 8688883943071546469,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_mysql_builtins.py": 16087227298679432006,
+ "venv/lib/python3.13/site-packages/dateutil/_common.py": 12492546559232079071,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/extension.py": 7193879749426425951,
+ "venv/lib/python3.13/site-packages/fastapi/templating.py": 10760135144345238340,
+ "venv/lib/python3.13/site-packages/pygments/lexers/fantom.py": 1986459352773446836,
+ "run_clean_tui.sh": 14305120550349644601,
+ "backend/src/plugins/translate/plugin.py": 15783602737040717978,
+ "venv/lib/python3.13/site-packages/pillow.libs/libwebp-d8b9687f.so.7.2.0": 116215608212382352,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/keywrap.py": 10424037418528425800,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py": 14995426099932276090,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_rolling.py": 11118160360072677569,
+ "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/assertion_session.py": 18109848200936213195,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_constructors.py": 16197656939536784142,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked_shared.py": 8453174300922339015,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/getitem.py": 556339939822508169,
+ "venv/lib/python3.13/site-packages/pygments/lexers/dylan.py": 16246299896150112270,
+ "backend/src/api/routes/git/_repo_routes.py": 12158952761025397291,
+ "venv/lib/python3.13/site-packages/sqlalchemy/event/__init__.py": 16182540084654095394,
+ "venv/lib/python3.13/site-packages/fastapi/_compat/may_v1.py": 9880083742927480960,
+ "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.cpython-313-x86_64-linux-gnu.so": 16963890771704942465,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_math.h": 16701045088211015518,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/py.typed": 9796674040111366709,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/block_docstring/foo.f": 2489756567993745076,
+ "venv/lib/python3.13/site-packages/httpx/_content.py": 1301854837767395687,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapper.py": 16715864918034312591,
+ "backend/src/core/ws_log_handler.py": 16227392517834423362,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_period.py": 10309599277099605395,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/hist.py": 10928173425078493095,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_constructors.pyi": 4993066609272697419,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.py": 18402126171936308228,
+ "frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js": 18193433457755419816,
+ "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pygments/lexers/jmespath.py": 7426464251945393925,
+ "venv/lib/python3.13/site-packages/pytest/py.typed": 15130871412783076140,
+ "backend/src/api/routes/tasks.py": 13688847871690186483,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/__init__.py": 15130871412783076140,
+ "backend/tests/services/clean_release/test_approval_service.py": 8273158625698254525,
+ "venv/lib/python3.13/site-packages/anyio/_backends/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/click/globals.py": 18353671282454331523,
+ "venv/lib/python3.13/site-packages/pydantic/v1/class_validators.py": 6471688474853407718,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_copy_deprecation.py": 16045426957636349035,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_duplicate_labels.py": 10663105616336167414,
+ "frontend/src/lib/components/translate/TermCorrectionPopup.svelte": 2290415616531498089,
+ "frontend/build/_app/immutable/chunks/Cr-9eaXZ.js": 55845366387923127,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_setops.py": 5208912445718807372,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_npy_units.py": 8966226962799105383,
+ "venv/lib/python3.13/site-packages/yaml/resolver.py": 6669674521776449098,
+ "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/licenses/LICENSE": 6965457853328313914,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_tree.py": 15789443159423302291,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.py": 17112989332785349705,
+ "venv/lib/python3.13/site-packages/PIL/GbrImagePlugin.py": 7681313333602257802,
+ "backend/src/api/routes/__tests__/test_dashboards.py": 3130878778754818679,
+ "frontend/postcss.config.js": 5714274776976071678,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/interval.py": 3964550092873794670,
+ "venv/lib/python3.13/site-packages/httpcore/_utils.py": 3255581092836273826,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi": 1626154870044880426,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_pickle.py": 6232650893735715362,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_constructors.py": 6440526981746306640,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarinherit.py": 15240535501243623986,
+ "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/METADATA": 3618776395694990076,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-2.csv": 5423145402839576695,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_formats.py": 2743326139283991615,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/macos.py": 17442393555211213147,
+ "venv/lib/python3.13/site-packages/cryptography/fernet.py": 10137792148038140630,
+ "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/LICENSE": 4672913476475760762,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/period.py": 11560984428402318984,
+ "venv/lib/python3.13/site-packages/httpcore/py.typed": 15130871412783076140,
+ "merge_kilo.py": 4282227344165325430,
+ "venv/lib/python3.13/site-packages/uvicorn/main.py": 5843333502356171120,
+ "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.py": 11758491058846790938,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/cache_key.py": 11118819065204404106,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/messages.py": 6848925149930551457,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp.csv": 601782991752922510,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_api.py": 5813060676255093777,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayprint.py": 13335063050941743734,
+ "frontend/e2e/run-e2e.sh": 8106714116467101372,
+ "frontend/src/lib/components/ui/MultiSelect.svelte": 1475503303018683038,
+ "frontend/build/_app/immutable/chunks/KxePT7Ip.js": 8106111085962356816,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/validation": 13992741783834278677,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pipe.py": 7400355977900310233,
+ "venv/lib/python3.13/site-packages/sqlalchemy/connectors/asyncio.py": 4200928269459447593,
+ "venv/lib/python3.13/site-packages/pandas/compat/numpy/__init__.py": 1037113402100731082,
+ "venv/lib/python3.13/site-packages/starlette/middleware/wsgi.py": 12506262030845301606,
+ "venv/lib/python3.13/site-packages/rsa/common.py": 10921682819204792805,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqlconnector.py": 17538029557373507617,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/selectable.py": 14646717349365560549,
+ "venv/lib/python3.13/site-packages/httpcore/_trace.py": 9576253018891841832,
+ "venv/lib/python3.13/site-packages/pygments/lexers/archetype.py": 8995143180482517233,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_round.py": 8336918400205461173,
+ "venv/lib/python3.13/site-packages/gitdb/fun.py": 55226330810782184,
+ "backend/src/core/task_manager/cleanup.py": 13007785075566443785,
+ "backend/src/plugins/translate/orchestrator_cancel.py": 673611364664367049,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_scalar_compat.py": 10534925655070162459,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_construction.py": 13953424340346625390,
+ "frontend/build/_app/immutable/chunks/BVk3Uk_6.js": 15316567731933897520,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/timedeltas.py": 7318851108932357510,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/resource_protector.py": 11539718751174980004,
+ "frontend/build/_app/immutable/chunks/C2DipQLT.js": 333538434576244034,
+ "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.pyi": 18395688193449688360,
+ "venv/lib/python3.13/site-packages/pygments/lexers/typst.py": 8883289726601667104,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_expanding.py": 9047466276603454007,
+ "venv/lib/python3.13/site-packages/httpx/_multipart.py": 2181282475656908730,
+ "backend/src/core/utils/superset_context_extractor/_recovery.py": 11393453671559067169,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/hybrid.py": 5793056975404534989,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi": 3533739482029983817,
+ "venv/lib/python3.13/site-packages/passlib/crypto/_md4.py": 379335134151814809,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_concat.py": 3788461606817482165,
+ "venv/lib/python3.13/site-packages/PIL/IcoImagePlugin.py": 14483964191652228364,
+ "venv/lib/python3.13/site-packages/numpy/_core/printoptions.pyi": 16758392990920041462,
+ "venv/lib/python3.13/site-packages/numpy/core/_dtype.pyi": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/cffi/_embedding.h": 9441285871823018603,
+ "venv/lib/python3.13/site-packages/attrs/exceptions.py": 2871247302586505373,
+ "venv/lib/python3.13/site-packages/pip/_internal/distributions/__init__.py": 1343779312297539596,
+ "venv/lib/python3.13/site-packages/_pytest/freeze_support.py": 494952714451267295,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctan.csv": 4581185622290535488,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/region.py": 12579403230062395563,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dtypes.py": 7550022036887594386,
+ "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/pygments/formatters/svg.py": 11686316844190214147,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ranges.py": 14549386056660231279,
+ "backend/src/services/clean_release/stages/base.py": 14966559035592717091,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_policy.py": 13856626567322091253,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/conftest.py": 13388202260795998613,
+ "venv/lib/python3.13/site-packages/PIL/ImageColor.py": 17058618058554970738,
+ "frontend/src/routes/datasets/__tests__/bulk_actions.test.js": 8445672988319354987,
+ "venv/lib/python3.13/site-packages/pygments/lexers/monte.py": 15158829991357994573,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dlpack.py": 7908102652282922952,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/numeric.py": 17834058423729918687,
+ "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/METADATA": 10220680536734745103,
+ "venv/lib/python3.13/site-packages/fastapi/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/passlib/ext/__init__.py": 15240312484046875203,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_app.py": 4329794049222609894,
+ "venv/lib/python3.13/site-packages/pandas/core/sorting.py": 689057022713741051,
+ "venv/lib/python3.13/site-packages/psycopg2/pool.py": 8855184580138330938,
+ "venv/lib/python3.13/site-packages/requests/status_codes.py": 17005213506461710202,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/test_jsonschema_specifications.py": 12693210357718751894,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_functions.py": 2255133375699086300,
+ "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.py": 7029935879540617057,
+ "venv/lib/python3.13/site-packages/cffi/pkgconfig.py": 16057517851163939571,
+ "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.py": 6348811074249398741,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/comparisons.pyi": 9338084426044982038,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_re.py": 1296579393600719224,
+ "venv/lib/python3.13/site-packages/pandas/compat/pickle_compat.py": 11073483984394766474,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/resolver.py": 9931394693284776391,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/protocol.py": 932296179250981622,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/test_decimal.py": 17811784255174057561,
+ "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.py": 4154852745131464543,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_datetimes.py": 7889573945417063183,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_polynomial.pyi": 4266795948450921502,
+ "venv/lib/python3.13/site-packages/pygments/formatters/rtf.py": 5850574956253747036,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray_misc.pyi": 16219573290116396099,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/session.py": 293771075394156394,
+ "venv/lib/python3.13/site-packages/urllib3/_collections.py": 3440910792774742262,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_asy_builtins.py": 1665617945818958781,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/random.pyi": 1808392097712315455,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/device_code.py": 6712610002227849281,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending.py": 16515485226251040454,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_function_base.pyi": 2792940598392356268,
+ "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.pyi": 84606125837677197,
+ "frontend/build/_app/immutable/nodes/0.C0VwB1oL.js": 4642091940107505621,
+ "backend/src/core/logger/__tests__/test_logger.py": 392344140757115787,
+ "backend/src/api/routes/translate/_dictionary_routes.py": 5668671879929670471,
+ "backend/tests/services/clean_release/test_compliance_execution_service.py": 9658943217379916757,
+ "backend/git_repos/remote/test-repo.git/objects/c5/b992984fe856bd81206304a881faa3087937cf": 2441623644664166468,
+ "backend/src/api/routes/__tests__/test_dataset_review_api.py": 9392418725327519178,
+ "venv/lib/python3.13/site-packages/pydantic/annotated_handlers.py": 10186120300163345360,
+ "venv/lib/python3.13/site-packages/referencing/tests/test_referencing_suite.py": 8875120876162738440,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/char.f90": 12203871998988759364,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/coercions.py": 5112358449376598662,
+ "frontend/build/_app/immutable/nodes/32.DeKrAKQE.js": 400351527217645716,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286_bc.pyf": 10893958728966010450,
+ "frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js": 4930404579577741926,
+ "backend/tests/test_translate_history.py": 4612852312641794586,
+ "backend/src/api/routes/assistant/_history.py": 7072732884181135864,
+ "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_function_base.py": 15241999259666702619,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/stride_tricks.pyi": 8257977532799807847,
+ "venv/lib/python3.13/site-packages/authlib/oidc/registration/claims.py": 4161520263207458028,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_interval.py": 2911379732293827726,
+ "venv/lib/python3.13/site-packages/pandas/tests/api/test_api.py": 13385690673368400635,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_setops.py": 14246225281428284850,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_month.py": 1613806538807726074,
+ "backend/src/services/notifications/__tests__/test_notification_service.py": 13027609991239837872,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi": 11733449165276720901,
+ "venv/lib/python3.13/site-packages/requests/sessions.py": 6936640856092320928,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_index.py": 14187428934500390688,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py": 7624316342162916928,
+ "venv/lib/python3.13/site-packages/numpy/_core/function_base.py": 5676611841071163854,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarbuffer.py": 16859789411010045795,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertsql.py": 4633484475514351889,
+ "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.cpython-313-x86_64-linux-gnu.so": 16604252871044637047,
+ "venv/lib/python3.13/site-packages/smmap/test/lib.py": 2924931247676024085,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/processors.py": 4817637175145012571,
+ "frontend/playwright-report/trace/manifest.webmanifest": 565917384317025203,
+ "frontend/src/lib/auth/store.ts": 5831215136783173107,
+ "backend/src/core/utils/superset_context_extractor/_base.py": 6349561308410782726,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/endpoint.py": 8519226897299461194,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_compression.py": 8577756801858495168,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_reloading.py": 17532116685329953400,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/parameters.py": 12219404446503940066,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_algos.py": 11860014896449369497,
+ "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/METADATA": 9586902338916246692,
+ "venv/lib/python3.13/site-packages/numpy/random/__init__.pxd": 7355772669172093814,
+ "venv/lib/python3.13/site-packages/pycparser/c_ast.py": 5942107079119742,
+ "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/LICENSE": 6989336036499641077,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/errors.py": 18154419146257747681,
+ "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/METADATA": 4868544280955034757,
+ "venv/lib/python3.13/site-packages/urllib3/fields.py": 9503202008440141421,
+ "venv/bin/pyrsa-decrypt": 10929163076272054227,
+ "venv/lib/python3.13/site-packages/pydantic/v1/main.py": 213087273729911492,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/parsing.py": 3084943521520476999,
+ "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py": 14034239842770171660,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_numpy_array_equal.py": 2089426719574307767,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_unique.py": 3989602816674881215,
+ "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/RECORD": 13494296690334916257,
+ "backend/src/services/clean_release/stages/__init__.py": 2966227562547886302,
+ "venv/lib/python3.13/site-packages/itsdangerous/timed.py": 12571102606719555007,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_multi_thread.py": 5660352470978621226,
+ "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/METADATA": 10241403930811743893,
+ "frontend/playwright-report/trace/uiMode.C2Efnu2P.js": 2717171022864487300,
+ "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/RECORD": 8956798822782402202,
+ "frontend/src/lib/stores/__tests__/test_datasetReviewSession.js": 8646274524484627210,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.pyi": 7544619194032232861,
+ "venv/lib/python3.13/site-packages/keyring/testing/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_defmatrix.py": 2982572083770917411,
+ "venv/lib/python3.13/site-packages/passlib/handlers/misc.py": 18255658377109333797,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/base.py": 496956059910401121,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/gevent.py": 4811840397266785551,
+ "venv/lib/python3.13/site-packages/pygments/lexers/javascript.py": 16869490851285457857,
+ "backend/src/plugins/translate/__tests__/test_dictionary_filter.py": 2426844436521732941,
+ "venv/lib/python3.13/site-packages/gitdb/test/test_base.py": 16305779366785148795,
+ "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/unrolled.py": 12651425412640834530,
+ "venv/lib/python3.13/site-packages/pygments/styles/perldoc.py": 4857683935715743356,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval.py": 8549680643865283913,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/value_attrspec/gh21665.f90": 11945588837236968550,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npz": 12369168483236619421,
+ "backend/tests/test_security_audit_fixes.py": 10329229098676202553,
+ "venv/lib/python3.13/site-packages/pygments/formatters/bbcode.py": 8614391937525677922,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py": 15294662527620994511,
+ "frontend/src/routes/settings/settings-utils.js": 1940619437304867415,
+ "backend/alembic/versions/8dd0a93af539_drop_deprecated_source_language_column_.py": 3574830605384611294,
+ "backend/git_repos/remote/test-repo.git/hooks/update.sample": 8204581436750313444,
+ "venv/lib/python3.13/site-packages/anyio/pytest_plugin.py": 4165280709813718099,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_leaks.py": 1219835696230215605,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_types.py": 7175518113263603341,
+ "venv/lib/python3.13/site-packages/rapidfuzz/utils_py.py": 12341806772632276946,
+ "venv/lib/python3.13/site-packages/keyring/util/platform_.py": 16978095707950463638,
+ "venv/lib/python3.13/site-packages/numpy/lib/array_utils.pyi": 14646405559193539455,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_regression.py": 4611768764484593979,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/__init__.py": 10834852742917144496,
+ "venv/lib/python3.13/site-packages/PIL/BufrStubImagePlugin.py": 5520941821175895889,
+ "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.cpp": 7360124705400993707,
+ "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/WHEEL": 18203500019759199992,
+ "venv/lib/python3.13/site-packages/passlib/handlers/fshp.py": 13298827601291507295,
+ "venv/lib/python3.13/site-packages/urllib3/_version.py": 839747992523118887,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/__init__.py": 15487893533770969571,
+ "venv/lib/python3.13/site-packages/PIL/ImagePalette.py": 9227837918026991107,
+ "venv/lib/python3.13/site-packages/pygments/lexers/pony.py": 2720635393743617141,
+ "backend/git_repos/remote/test-repo.git/refs/heads/feature/test": 7714224145564125988,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/operators.f90": 5949265961908386974,
+ "venv/lib/python3.13/site-packages/pandas/core/tools/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.pyi": 6072607880689125113,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arithmetic.py": 14858832264660410908,
+ "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/__init__.py": 6758781485387665020,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/base.py": 7110726987481713080,
+ "venv/lib/python3.13/site-packages/PIL/ImageFont.py": 15621336334706847865,
+ "backend/git_repos/remote/test-repo.git/objects/d5/0298a42699f39e4601c0aa23eab07bcb0703c7": 1966124163198751340,
+ "venv/lib/python3.13/site-packages/PIL/FontFile.py": 112053841436523305,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/__init__.py": 2246704695838251846,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/base.py": 3628510830969664111,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_join.py": 17508073052750406350,
+ "venv/lib/python3.13/site-packages/httpcore/_async/connection.py": 2155744160496556069,
+ "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/METADATA": 11439969143853665311,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/oct_key.py": 11504245602045724,
+ "backend/src/api/routes/translate/_preview_routes.py": 12316180738640292691,
+ "backend/src/services/__tests__/test_llm_plugin_persistence.py": 17921598588767566887,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/reporter.py": 6510864297510700136,
+ "backend/git_repos/remote/test-repo.git/HEAD": 12394318939628232491,
+ "venv/lib/python3.13/site-packages/websockets/sync/client.py": 10892557975919033983,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi": 16048852379621461316,
+ "venv/lib/python3.13/site-packages/_pytest/subtests.py": 14573790885130724739,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_deprecations.py": 16367195310156359251,
+ "venv/lib/python3.13/site-packages/ecdsa/numbertheory.py": 13538480862642502330,
+ "venv/lib/python3.13/site-packages/websockets/typing.py": 13268801935274185287,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh15035.f": 13126319439858352711,
+ "venv/lib/python3.13/site-packages/gitdb/util.py": 645937410168583692,
+ "venv/lib/python3.13/site-packages/pillow.libs/libjpeg-32d42e18.so.62.4.0": 11717944412021329207,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/groupby.py": 14661033005768429774,
+ "venv/lib/python3.13/site-packages/PIL/ImageMorph.py": 13861961228125789866,
+ "frontend/src/components/git/CommitHistory.svelte": 6419514228971332714,
+ "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_algorithms.py": 15219408648894515493,
+ "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.cpython-313-x86_64-linux-gnu.so": 11074560904305737689,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_liboffsets.py": 14705822637347212540,
+ "frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js": 8659643137288661057,
+ "venv/lib/python3.13/site-packages/anyio/to_interpreter.py": 8369454842687342401,
+ "venv/lib/python3.13/site-packages/smmap/mman.py": 9091562788592406032,
+ "venv/lib/python3.13/site-packages/numpy/testing/tests/test_utils.py": 5291132432383518704,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.pyi": 2101854548535776875,
+ "venv/lib/python3.13/site-packages/passlib/tests/backports.py": 17098448557554464521,
+ "venv/lib/python3.13/site-packages/pip/_internal/vcs/bazaar.py": 5630511062945201327,
+ "frontend/src/routes/reports/+page.svelte": 18404964858248487921,
+ "frontend/build/_app/immutable/entry/start.H6-5rz7_.js": 3502595655690893576,
+ "venv/lib/python3.13/site-packages/starlette/middleware/cors.py": 11384893784314197864,
+ "venv/lib/python3.13/site-packages/passlib/handlers/sun_md5_crypt.py": 1949993216707182407,
+ "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.pyi": 10360538024015064036,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_color.py": 3700828402084646308,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_setitem.py": 10389770446834773837,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval.py": 1228451182688768814,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/decl_api.py": 5287018911951723034,
+ "frontend/build/_app/immutable/chunks/DtZqxm39.js": 18304620451061391646,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/resource_protector.py": 17080006010679257864,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_string.py": 10141066226714805009,
+ "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/containers.py": 5969831151685016772,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_pairwise.py": 2673370322448160842,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/elements.py": 11185011314498348980,
+ "backend/git_repos/remote/test-repo.git/hooks/sendemail-validate.sample": 8058833260784074657,
+ "frontend/src/lib/api/maintenance.js": 16247720324991780393,
+ "venv/lib/python3.13/site-packages/numpy/core/numeric.py": 17025007229779320230,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/resources.py": 11533706401259147051,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_ordered.py": 13827016781743929164,
+ "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.py": 13012775703413938576,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/base.py": 7855217087916771270,
+ "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/LICENSE": 16343563559291870811,
+ "venv/lib/python3.13/site-packages/websockets/datastructures.py": 5180442040351387281,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/revocation.py": 5718403706971163960,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__init__.py": 8880435562116660648,
+ "venv/lib/python3.13/site-packages/cryptography/x509/certificate_transparency.py": 11337143186866439208,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_scalars.py": 17701938912160369190,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_update_delete.py": 1317337950621091021,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/provision.py": 9472538482404392519,
+ "venv/lib/python3.13/site-packages/PIL/SgiImagePlugin.py": 6916200065790425497,
+ "venv/lib/python3.13/site-packages/pycparser/__init__.py": 16499940957411260458,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi": 16312114056447366970,
+ "venv/lib/python3.13/site-packages/referencing/_core.py": 14744795336121513230,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta_range.py": 15081095442418142820,
+ "venv/lib/python3.13/site-packages/urllib3/util/response.py": 6106698559175827207,
+ "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.pyi": 7410507092040239447,
+ "venv/lib/python3.13/site-packages/pydantic/root_model.py": 20625057828723317,
+ "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.pyi": 14181518821845356636,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_utils.py": 10936299012115637790,
+ "venv/lib/python3.13/site-packages/pygments/styles/arduino.py": 4578385147314541233,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.py": 5735043585893007971,
+ "venv/lib/python3.13/site-packages/pygments/lexers/fift.py": 7537570342576781911,
+ "frontend/src/lib/utils.js": 2362133402815996206,
+ "venv/bin/pip": 13861749540792881808,
+ "frontend/build/_app/immutable/nodes/39.CtRM7uMz.js": 15276559781688502962,
+ "backend/src/services/reports/__tests__/test_type_profiles.py": 8045459741015920365,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/dml.py": 6567627855667533645,
+ "backend/git_repos/remote/test-repo.git/objects/f7/6ee984d9d47c3cd0b362fdf60a47162bbc202d": 5351983130474596028,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_app.py": 14788764260762890368,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/__init__.py": 15130871412783076140,
+ "frontend/e2e/tests/login.e2e.js": 9217667783118672119,
+ "backend/src/models/dataset_review_pkg/_clarification_models.py": 10650387708191883580,
+ "frontend/playwright-report/trace/index.CzXZzn5A.css": 10367596602957476705,
+ "backend/src/scripts/test_dataset_dashboard_relations.py": 11883199369340933897,
+ "venv/lib/python3.13/site-packages/jeepney/io/trio.py": 11859775321483330469,
+ "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/METADATA": 12747626683405487434,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_backend.py": 17793139799410518847,
+ "venv/lib/python3.13/site-packages/numpy/matlib.py": 112839038090033740,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/http/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/text.py": 10572727755736597715,
+ "frontend/src/lib/i18n/index.ts": 14616557360624297847,
+ "venv/lib/python3.13/site-packages/pip/_internal/locations/__init__.py": 8147012724727395488,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_values.py": 8372572954663628844,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/dtype.pyi": 12178008080078679769,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_function.py": 13492077564015386528,
+ "backend/src/plugins/translate/_text_cleaner.py": 13161219043687449729,
+ "venv/lib/python3.13/site-packages/pygments/lexers/pddl.py": 9256112535059995841,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log.csv": 221209423454319618,
+ "venv/lib/python3.13/site-packages/pyasn1/type/constraint.py": 16776615503418773283,
+ "venv/lib/python3.13/site-packages/websockets/legacy/http.py": 16266924390281399720,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/errors.py": 1154126353335030046,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-2.csv": 14641856424618845798,
+ "venv/lib/python3.13/site-packages/sqlalchemy/schema.py": 16029542421991709659,
+ "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/_libs/testing.cpython-313-x86_64-linux-gnu.so": 16758333404587340103,
+ "venv/lib/python3.13/site-packages/pydantic/mypy.py": 10034028441785588819,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_optional_dependency.py": 7930709646653025355,
+ "venv/lib/python3.13/site-packages/jose/backends/cryptography_backend.py": 2875270748627611635,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.py": 893743087939984792,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_period_index.py": 6634414375581820058,
+ "venv/lib/python3.13/site-packages/authlib/integrations/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.py": 4265012785873472600,
+ "venv/lib/python3.13/site-packages/sqlalchemy/events.py": 9329355486544822483,
+ "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pytest_asyncio/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/RECORD": 5612689057373270213,
+ "venv/lib/python3.13/site-packages/pygments/lexers/webassembly.py": 17811970490091406867,
+ "venv/lib/python3.13/site-packages/more_itertools/__init__.py": 9858612105173082060,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/requests.py": 14847842002253212098,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/dtype.pyi": 465999539608816848,
+ "frontend/src/lib/ui/PageHeader.svelte": 16740944781208407079,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_hist_method.py": 2109257663592928,
+ "venv/lib/python3.13/site-packages/numpy/random/_philox.pyi": 7503018432880404291,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_abstract_interface.py": 17625870734108222276,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_decimal.py": 3515468590005709183,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/__init__.py": 9884041726796476720,
+ "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.py": 2215312866861772848,
+ "frontend/src/lib/stores/__tests__/mocks/environment.js": 3065694655373335793,
+ "venv/lib/python3.13/site-packages/pyasn1/debug.py": 6305633719847955310,
+ "venv/lib/python3.13/site-packages/fastapi/dependencies/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pygments/lexers/sophia.py": 15971500155124949058,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/style_render.py": 13586834368514801953,
+ "backend/tests/services/clean_release/test_demo_mode_isolation.py": 15017454272480710246,
+ "backend/git_repos/remote/test-repo.git/objects/99/38d17c3f4199e53e4d4ebc253fe9c840caa505": 8414792171590415839,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/util.py": 5364455058429522633,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/parameters.py": 5104015814292812973,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_nbit.py": 15498810174380798405,
+ "venv/lib/python3.13/site-packages/pydantic/v1/config.py": 12050640083719340958,
+ "venv/lib/python3.13/site-packages/ecdsa/test_ecdsa.py": 17595025859105321562,
+ "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pyx": 11739218099400096619,
+ "frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js": 7606382627471479368,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/module_data_docstring.f90": 18245403117623015312,
+ "backend/src/models/__tests__/test_models.py": 7136192055672203219,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_core_utils.py": 13248004771466837645,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.pyi": 9935587108964614958,
+ "venv/lib/python3.13/site-packages/pip/_internal/locations/_sysconfig.py": 4773855595767526182,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_map.py": 10769974470610467636,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexing.py": 9988098331562906950,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/style.py": 15214295655795348821,
+ "frontend/build/_app/immutable/nodes/19.CoCKLtZL.js": 4766250160488499555,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numeric.py": 5627177940393829333,
+ "venv/lib/python3.13/site-packages/attrs/__init__.pyi": 14353885498883901855,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__main__.py": 6480933938145689964,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_pad.pyi": 14755435694146003896,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_dict.py": 16252265723192124609,
+ "backend/src/plugins/translate/preview_resolve_provider.py": 7349483761713339246,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_multi.py": 4612816468258071810,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_repeat.py": 18394463352314692642,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_logical.py": 6818185860296232476,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_searchsorted.py": 11161416745923343741,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/signals.py": 13677199634497673845,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args_and_kwargs.py": 3381939712123764154,
+ "venv/lib/python3.13/site-packages/pycparser/c_parser.py": 3954138286651284327,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/client.py": 5694225754072131767,
+ "venv/lib/python3.13/site-packages/gitdb/const.py": 14122142034887286559,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/subprocess.py": 3095012838116670328,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/_mapping.py": 17519715342700184302,
+ "venv/lib/python3.13/site-packages/sqlalchemy/inspection.py": 8563914460959280101,
+ "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/licenses/LICENSE": 3996324383113221529,
+ "venv/lib/python3.13/site-packages/uvicorn/supervisors/statreload.py": 5018382301336802445,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/models.py": 3567900447243180991,
+ "venv/lib/python3.13/site-packages/typing_inspection/introspection.py": 13916695705179237047,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/ansi.py": 948249091929588017,
+ "venv/lib/python3.13/site-packages/passlib/handlers/phpass.py": 16489430001449160264,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_latex.py": 2628895559914914693,
+ "frontend/vitest.config.js": 4756170101280085905,
+ "venv/lib/python3.13/site-packages/pygments/lexers/objective.py": 10966124906622044512,
+ "venv/lib/python3.13/site-packages/attr/__init__.py": 14436902698244718082,
+ "venv/lib/python3.13/site-packages/PIL/MicImagePlugin.py": 13540523615822507963,
+ "backend/src/services/auth_service.py": 5948958621485759282,
+ "venv/lib/python3.13/site-packages/numpy/fft/_helper.py": 15906444100774706395,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/endpoints.py": 18334891787808122725,
+ "frontend/tests/maintenance-api.test.ts": 10196278218740408254,
+ "backend/tests/test_maintenance_service.py": 15566750462318533004,
+ "backend/git_repos/remote/test-repo.git/config": 14478893374498894766,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/linalg.pyi": 7217817172953767893,
+ "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pyi": 14150710436003340771,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_finfo.py": 17174674209412768422,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/signals.py": 10390443713463805090,
+ "venv/lib/python3.13/site-packages/PIL/_imaging.pyi": 17119084207765761921,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/extension_types.py": 1856757457657310231,
+ "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/pygments/lexers/jslt.py": 11805394130669644345,
+ "frontend/src/routes/datasets/__tests__/DatasetList.test.js": 10189122239208504978,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_pickle.py": 4216445955812104014,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/meson.build.template": 9935732744553086652,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_io.py": 4199750143323741326,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_reductions.py": 3227705565578016389,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/sqlalchemy.py": 811968833735951956,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/rec.pyi": 9140655366667421698,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/api.py": 13750417165301467381,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarraytypes.h": 6765088137325865789,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/preloaded.py": 3719702436309355562,
+ "venv/lib/python3.13/site-packages/_pytest/skipping.py": 10561585274103209115,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/groupby.py": 12749730954888633240,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_freq_code.py": 13758353172962109140,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/resource_owner_password_credentials.py": 9559295461619813890,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_core_metadata.py": 5704137311404303574,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/indexable.py": 4131796922597075758,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/cymysql.py": 5570881524647789741,
+ "frontend/src/services/storageService.js": 9489915460172592752,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_set_value.py": 4166411740676564820,
+ "venv/lib/python3.13/site-packages/pydantic/v1/validators.py": 1060954771151908883,
+ "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_parse_dates.py": 7597935994945336408,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel.py": 7728646523045538484,
+ "venv/lib/python3.13/site-packages/jose/backends/_asn1.py": 14123487576864105793,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_contains.py": 5273759677032634868,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/resource_protector.py": 14354891358060085360,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/__init__.py": 293004106962245584,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING": 3474104874623144155,
+ "frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte": 6548767763019176627,
+ "venv/lib/python3.13/site-packages/sqlalchemy/pool/events.py": 13473858896579666058,
"venv/lib/python3.13/site-packages/numpy/f2py/tests/test_modules.py": 16835987029123241300,
+ "venv/lib/python3.13/site-packages/pygments/lexers/qlik.py": 3881663935630350152,
+ "venv/lib/python3.13/site-packages/fastapi/background.py": 16533963020573865222,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_pickle.py": 8705060420848529055,
+ "venv/lib/python3.13/site-packages/pygments/lexers/jsonnet.py": 1314044008440065525,
+ "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/RECORD": 12015288851076448205,
+ "venv/lib/python3.13/site-packages/numpy/exceptions.pyi": 13942486291715303235,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ride.py": 14096748896451437594,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_fileno.py": 15541504502174047167,
+ "venv/lib/python3.13/site-packages/yaml/nodes.py": 3463622922914760653,
+ "frontend/src/routes/migration/+page.svelte": 10701023521907757906,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_symbolic.py": 8093576026032854125,
+ "venv/lib/python3.13/site-packages/passlib/utils/binary.py": 13123975436674239306,
+ "venv/lib/python3.13/site-packages/pyasn1/type/char.py": 16518487114777185541,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_constructors.py": 6515602441449955627,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/sync.py": 6189260178302531376,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_readers.py": 2136472634307645842,
+ "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/mlib.ini": 16151597765994697599,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/request.py": 10492090878715126550,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi": 9294219058621261971,
+ "venv/lib/python3.13/site-packages/fastapi/exception_handlers.py": 9907950997607808699,
+ "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/__init__.py": 5896924546560667519,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/json/array.py": 7437107031079833232,
+ "venv/lib/python3.13/site-packages/pygments/lexers/c_like.py": 13004061780700827047,
+ "venv/lib/python3.13/site-packages/pygments/lexers/yara.py": 17510792615476493957,
+ "frontend/build/_app/immutable/nodes/23.y3ghKhH-.js": 13434006313990484006,
+ "venv/lib/python3.13/site-packages/pandas/_libs/internals.pyi": 11662356720550765508,
+ "venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so": 829323374625147265,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_config.py": 3636377988901907424,
+ "venv/lib/python3.13/site-packages/pygments/lexers/email.py": 4355246279485460399,
+ "venv/lib/python3.13/site-packages/PIL/_avif.pyi": 18222325750818585549,
+ "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/LICENSE": 6581019367004699816,
+ "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.py": 2401931196871484449,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ecl.py": 12886695201994337568,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_string.py": 15542851215119662814,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_federal.py": 16758212916399857971,
+ "venv/lib/python3.13/site-packages/anyio/abc/_subprocesses.py": 4297459042599291531,
+ "backend/src/core/superset_client/_dashboards_crud.py": 8682388093872211883,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/npyio.pyi": 15811156298637131744,
+ "venv/lib/python3.13/site-packages/ecdsa/test_ecdh.py": 3338834550392548171,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/filesize.py": 13234856188049714485,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_searchsorted.py": 11208047646304753715,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/shared.py": 1162754506656505196,
+ "frontend/src/services/taskService.js": 11368052191249479533,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccosh.csv": 5882025767947638305,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename_axis.py": 12432900682994622455,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_extract.py": 14547819021277949280,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/strategies.py": 14007486769065345085,
+ "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/METADATA": 15658158392301945427,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/__init__.py": 14481526616887213120,
+ "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth1_client.py": 3129955464287331242,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_generate_schema.py": 7343380095251236503,
+ "backend/src/plugins/translate/dictionary_correction.py": 18051915404774774954,
+ "venv/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py": 13206297306768491360,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.pyi": 12925006572914814268,
+ "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/_pytest/assertion/truncate.py": 14000392306994773741,
+ "venv/lib/python3.13/site-packages/pydantic/utils.py": 1533455264689378477,
+ "venv/lib/python3.13/site-packages/pandas/tests/construction/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_read_errors.py": 4559483361564472117,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connectionpool.py": 10453724680327835821,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77comments.f": 4801926170672147659,
+ "venv/lib/python3.13/site-packages/keyring/cli.py": 10996746519742056101,
+ "venv/lib/python3.13/site-packages/pygments/styles/inkpot.py": 10516710471319090846,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_block_docstring.py": 18146459246837890489,
+ "backend/src/core/superset_client/_databases.py": 16562767538012813426,
+ "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.pyi": 12144531601504755948,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_endian.h": 2761502363895204652,
+ "venv/lib/python3.13/site-packages/ecdsa/util.py": 10543788809724099209,
+ "venv/lib/python3.13/site-packages/websockets/legacy/server.py": 5390090919193784186,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/temp_dir.py": 8657533190026387896,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_legend.py": 13094583566764796297,
+ "frontend/tests/maintenance.test.ts": 18128393571681331195,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_mask.py": 5451866071307236899,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_numeric.py": 9383693732009547935,
+ "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.pyi": 2042169688753984918,
+ "venv/lib/python3.13/site-packages/pydantic/parse.py": 13750341403702794392,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_string_array.py": 8260883866404398980,
+ "venv/lib/python3.13/site-packages/numpy/_core/_simd.cpython-313-x86_64-linux-gnu.so": 12609666221355091416,
+ "venv/lib/python3.13/site-packages/dotenv/version.py": 13508433229287636267,
+ "run.sh": 16549488891429944178,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/status_codes.py": 17005213506461710202,
+ "venv/lib/python3.13/site-packages/numpy/f2py/__init__.py": 7470157159992827389,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_range.py": 9900908262700749861,
+ "venv/lib/python3.13/site-packages/click/_compat.py": 14451519072991457993,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_scripts.py": 5790352482583964348,
+ "venv/lib/python3.13/site-packages/numpy.libs/libscipy_openblas64_-096271d3.so": 14338208504131470036,
+ "venv/lib/python3.13/site-packages/click/termui.py": 7022374827798605437,
+ "venv/lib/python3.13/site-packages/itsdangerous/url_safe.py": 13454753900702274266,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_slp_switch.hpp": 1694714764745718414,
+ "venv/lib/python3.13/site-packages/tzlocal/windows_tz.py": 11696765495002954868,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py": 1437580234680265326,
+ "venv/lib/python3.13/site-packages/jeepney/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.pyi": 15034917167424979097,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/ops.py": 4740509262379451243,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet_trash.py": 6191655521667576604,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_searchsorted.py": 12074107109575676897,
+ "venv/lib/python3.13/site-packages/cffi/_cffi_errors.h": 1479575326813300292,
+ "venv/lib/python3.13/site-packages/pandas/_libs/properties.cpython-313-x86_64-linux-gnu.so": 7092136701092358552,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/common.py": 11384497819737275399,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_to_xarray.py": 15341013524814290960,
+ "venv/lib/python3.13/site-packages/pandas/io/sql.py": 12592024569011796790,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/_typing.py": 10524021526716767489,
+ "venv/lib/python3.13/site-packages/PIL/GimpGradientFile.py": 9777026720028891154,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_iteration.py": 2118501258411211851,
+ "backend/src/api/routes/dashboards/_schemas.py": 4116381929361209080,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/egg_link.py": 18211947508793805393,
+ "venv/lib/python3.13/site-packages/numpy/dtypes.py": 14128421398870718692,
+ "venv/lib/python3.13/site-packages/PIL/WmfImagePlugin.py": 15685062825106444247,
+ "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.pyi": 4587511199710546030,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_conversion.py": 12184280074522274780,
+ "venv/lib/python3.13/site-packages/pygments/lexers/foxpro.py": 14032656072384708293,
+ "venv/lib/python3.13/site-packages/pygments/styles/igor.py": 2291640843781128270,
+ "backend/src/models/api_key.py": 4327024700622965951,
+ "venv/lib/python3.13/site-packages/pandas/io/iceberg.py": 13137128885014736233,
+ "venv/lib/python3.13/site-packages/PIL/_imagingtk.pyi": 18222325750818585549,
+ "frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js": 3774268544046391936,
+ "backend/git_repos/remote/test-repo.git/objects/93/9cc583a18267406014c57617ccb557569f6aaf": 5474754694741999746,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/__init__.py": 15130871412783076140,
+ "frontend/src/app.css": 3020720639702954139,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/LICENSE": 14599279238716790189,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/string.tpl": 15796203549130590784,
+ "venv/lib/python3.13/site-packages/pyasn1/type/tag.py": 13912273274509186651,
+ "venv/lib/python3.13/site-packages/pandas/_libs/groupby.pyi": 6154952803757623626,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/__init__.py": 5027355874704300832,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/cx_oracle.py": 10093932131797570986,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_utils_pbkdf2.py": 17016810698578473773,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_validate.py": 2133732492454460539,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/kind/foo.f90": 1367964042730902899,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/pytables.py": 16326122536715961388,
+ "venv/lib/python3.13/site-packages/httpcore/_api.py": 16499985295426060327,
+ "frontend/playwright-report/data/ac7f153484f7d6b15b773641e328a5ad9204f736.webm": 17964728097298408466,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/list/__init__.py": 10072943986583771248,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_limited_api.py": 15788485008764560845,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_timedelta.py": 12822713918114715561,
+ "frontend/build/_app/immutable/nodes/27.D9JO1_YZ.js": 1768599772397553118,
+ "backend/git_repos/remote/test-repo.git/objects/59/3a37acec7d2bddce10df90ab17bc9ede52e523": 1117161574576783985,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslib.cpython-313-x86_64-linux-gnu.so": 10742615805788605480,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/masked.py": 13977195666947626206,
+ "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/WHEEL": 8954358347596196608,
+ "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.py": 12796890117561096360,
+ "backend/git_repos/remote/test-repo.git/hooks/push-to-checkout.sample": 4825338927654285910,
+ "venv/lib/python3.13/site-packages/pydantic/v1/error_wrappers.py": 5701679786078971939,
+ "venv/lib/python3.13/site-packages/numpy/_core/umath.py": 6132761780113682667,
+ "venv/lib/python3.13/site-packages/pandas/core/util/numba_.py": 3535857372998653863,
+ "venv/lib/python3.13/site-packages/numpy/random/bit_generator.cpython-313-x86_64-linux-gnu.so": 2574035311375507054,
+ "frontend/build/_app/immutable/chunks/B0K5kI6n.js": 6208436857520817685,
+ "venv/lib/python3.13/site-packages/pip/_internal/distributions/installed.py": 18153165899841229597,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/pivot.py": 4736553530021653868,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nested_sequence.pyi": 10985533017688918283,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/wheel.py": 450504439085405418,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/aiomysql.py": 12999962380333482189,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/mask_ops.py": 16152832446926420035,
+ "venv/lib/python3.13/site-packages/_pytest/deprecated.py": 5452408732344157294,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/__init__.py": 15735839022111230173,
+ "frontend/playwright-report/trace/uiMode.Btcz36p_.css": 7361350017361398233,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/__init__.py": 14571251344510763303,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_formats.py": 17821648708413143557,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/sync.py": 576247220834179928,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.py": 16859854811012717088,
+ "venv/lib/python3.13/site-packages/passlib/utils/pbkdf2.py": 15802959653228956404,
+ "frontend/src/types/dashboard.ts": 9718666955722367566,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/types.py": 1343652083039949282,
+ "venv/lib/python3.13/site-packages/pandas/core/methods/describe.py": 17006836623161521092,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/sphinxext.py": 2403717774564798878,
+ "venv/lib/python3.13/site-packages/PIL/SunImagePlugin.py": 7661622930404688367,
+ "backend/src/scripts/seed_superset_load_test.py": 7430188463595432869,
+ "venv/lib/python3.13/site-packages/pygments/lexers/crystal.py": 3579547906957125755,
+ "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.pyi": 16176428602589420913,
+ "venv/lib/python3.13/site-packages/websockets/frames.py": 4901850477414613953,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/index.py": 16715578868094112894,
+ "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/WHEEL": 17410883677306885019,
+ "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.pyi": 8607205990821121708,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_datetime.py": 1678885152993000592,
+ "venv/lib/python3.13/site-packages/websockets/sync/connection.py": 2791040669094103200,
+ "venv/lib/python3.13/site-packages/pip/_internal/vcs/subversion.py": 7423946096970870727,
+ "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.pyi": 14558091964387571257,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_iloc.py": 16160558158155038350,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/base.py": 16891437410462671317,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/query.py": 3867868366067025348,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/dynamic.py": 15220116196072524330,
+ "venv/lib/python3.13/site-packages/uvicorn/supervisors/basereload.py": 14479857245734482609,
+ "backend/src/services/reports/report_service.py": 9387534669439738529,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_client/apps.py": 14151733532064278336,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.pyi": 2700568594438441246,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py": 10057637461647348368,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/jws.py": 7505219131537941130,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ada.py": 17032408976634308999,
+ "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/INSTALLER": 17282701611721059870,
+ "frontend/build/_app/immutable/chunks/B2x1wvBz.js": 18181710553832181445,
+ "venv/lib/python3.13/site-packages/cryptography/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_map.py": 1115471561925426082,
+ "backend/src/scripts/delete_running_tasks.py": 4209804708500252012,
+ "backend/src/core/task_manager/lifecycle.py": 1696300129247014205,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/json.py": 15373167408891671190,
+ "venv/lib/python3.13/site-packages/requests/exceptions.py": 6474239743209354989,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_unicode_ddl.py": 2569618488804767890,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/compat.py": 5871636909854554063,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_ctors.py": 631744056514965940,
+ "frontend/src/routes/settings/+page.ts": 3719008513710037840,
+ "frontend/build/_app/immutable/chunks/C8K-NfB8.js": 522730246953022577,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.pyf": 14358606965464506398,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/__init__.py": 11709551233929312136,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_constructors.py": 2786493777737472376,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/entities.py": 8001287806688585081,
+ "venv/lib/python3.13/site-packages/sqlalchemy/connectors/__init__.py": 17194870661869873083,
+ "venv/lib/python3.13/site-packages/PIL/BdfFontFile.py": 10811640174253687845,
+ "venv/lib/python3.13/site-packages/pandas/_libs/json.cpython-313-x86_64-linux-gnu.so": 2436285663630821963,
+ "backend/src/core/config_models.py": 4102600119446697065,
+ "backend/src/services/clean_release/manifest_service.py": 7248530010607024664,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/compat.py": 1841193561752758336,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/test_trio.py": 7459901627473962540,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/__init__.py": 17630019785411546070,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.asm": 15349921092257597740,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.pyi": 51728851886466199,
+ "venv/lib/python3.13/site-packages/pandas/_libs/lib.cpython-313-x86_64-linux-gnu.so": 6452315003728497116,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/__init__.py": 10920760520224795596,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_reduction.py": 2671872764983553906,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_strptime.py": 14328510310436552635,
+ "frontend/src/lib/components/translate/TranslationRunProgress.svelte": 12659537213220151902,
+ "frontend/build/_app/immutable/nodes/38.CPUUjahQ.js": 12407535468315561894,
+ "venv/lib/python3.13/site-packages/jsonschema/_typing.py": 13152346021901861822,
+ "frontend/build/_app/immutable/nodes/12.B-78a9ub.js": 3017777354640452876,
+ "frontend/build/_app/immutable/chunks/BHFoudx0.js": 10681906604178491410,
+ "venv/lib/python3.13/site-packages/pydantic/v1/dataclasses.py": 7833468513057242440,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.BSD": 16833702494864671773,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/csvs.py": 17223598248259691292,
+ "frontend/src/lib/components/ui/SearchableMultiSelect.svelte": 1872229619122554196,
+ "venv/lib/python3.13/site-packages/pygments/lexers/amdgpu.py": 17249439604111838979,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_round.py": 9358309072340573675,
+ "backend/git_repos/remote/test-repo.git/hooks/prepare-commit-msg.sample": 7530253302780245896,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937.py": 7299586490442539723,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_wrappers.py": 4813328996575597980,
+ "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/WHEEL": 16223367184831500348,
+ "venv/lib/python3.13/site-packages/starlette/authentication.py": 10905269573809129547,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/expr.py": 13085709365673019494,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_index_new.py": 796607958391882182,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex.py": 8772423071604000084,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/auto.py": 12818217385551437286,
+ "frontend/src/lib/api/translate/schedules.js": 8616345664085016472,
+ "venv/lib/python3.13/site-packages/rsa/randnum.py": 13958355153634534526,
+ "venv/lib/python3.13/site-packages/pandas/core/series.py": 11618272682977710696,
+ "frontend/src/lib/components/translate/ScheduleConfig.svelte": 9548866160759602637,
+ "frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte": 2835359394064716026,
+ "venv/lib/python3.13/site-packages/fastapi/__init__.py": 11054203163075417954,
+ "venv/lib/python3.13/site-packages/pygments/formatters/html.py": 1918541918263449443,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_utils.pyi": 3708905060001289515,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/resource_protector.py": 4823504113176750140,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/router.py": 15039562376314233669,
+ "venv/lib/python3.13/site-packages/pygments/lexers/templates.py": 16267123844830647955,
+ "venv/lib/python3.13/site-packages/sqlalchemy/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/formatters/_mapping.py": 13335227913146542481,
+ "frontend/src/lib/components/assistant/AssistantChatPanel.svelte": 17490466635940795553,
+ "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/_config/localization.py": 11197430792343731762,
+ "venv/lib/python3.13/site-packages/gitdb/db/mem.py": 15823812455996199993,
+ "dist/docker/frontend.0.1.0.tar.xz": 16011357094675100098,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi": 4376871621615688626,
+ "venv/lib/python3.13/site-packages/multipart/exceptions.py": 8580522204565816132,
+ "venv/lib/python3.13/site-packages/numpy/_core/lib/pkgconfig/numpy.pc": 14713682399742251335,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/horizontal_shard.py": 17615732108308858890,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_grouping.py": 5994909693214299971,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libldap-2974a1ba.so.2.0.200": 13590569080612602445,
+ "venv/lib/python3.13/site-packages/pygments/formatters/irc.py": 2133711525226123259,
+ "venv/lib/python3.13/site-packages/pygments/lexers/jsx.py": 13855228003748707341,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.pyi": 16164841755339571545,
+ "venv/lib/python3.13/site-packages/dateutil/rrule.py": 398469817784230512,
+ "venv/lib/python3.13/site-packages/_pytest/faulthandler.py": 13329320306353718649,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_array_like.py": 2161873439361281488,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/stride_tricks.pyi": 5844806555773292985,
+ "venv/lib/python3.13/site-packages/click/_termui_impl.py": 3296085065310341855,
+ "venv/lib/python3.13/site-packages/pillow.libs/libsharpyuv-95d8a097.so.0.1.2": 5320647379976541240,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/ma/LICENSE": 6723325434476453127,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.pyi": 3595910367556664837,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/astype_copy.pkl": 4470155972891419163,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_kind.py": 18178830861475480607,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/env.py": 1254612137164491329,
+ "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_internal_dataclass.py": 13206778611516171760,
+ "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft.pyi": 1521384724035973688,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_converter.py": 7709581879446228856,
+ "venv/lib/python3.13/site-packages/pip/__init__.py": 9449893869469432503,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/exceptions.py": 2873060848310644552,
+ "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/histograms.pyi": 2281259341486424755,
+ "venv/lib/python3.13/site-packages/rpds/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_half.py": 3121836756584726126,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_serializers.py": 12077180322353709930,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_astype.py": 11995587502880659624,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_mask.py": 9654897363729130542,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_html.py": 7732330576029516854,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/checks.pyx": 13187505236986855177,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_overlaps.py": 2328652590379935311,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_base.py": 1251545894005373734,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/orm.py": 7554417559838785150,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reserved_words.py": 8022121780993497971,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/ma/LICENSE": 6723325434476453127,
+ "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/licenses/LICENSE": 11986475601091748012,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598.f90": 1409455010615482779,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/__init__.py": 15130871412783076140,
+ "frontend/build/_app/immutable/chunks/rrOTveCl.js": 6718040498448531057,
+ "backend/src/services/reports/normalizer.py": 13510015789619559475,
+ "backend/src/plugins/translate/dictionary_crud.py": 17858252266960667195,
+ "frontend/src/routes/translate/dictionaries/+page.svelte": 1038433841421198720,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_einsum.py": 17286384318722237180,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.BSD": 3858254215169937333,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_records.py": 6252761812228230408,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/styled.py": 8726407298858811635,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_non_unique.py": 15286893322149413712,
+ "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/licenses/LICENSE": 8438117004702803716,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/mean_.py": 3641008929910474457,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_constructors.py": 12628643543371952431,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/printing.py": 3054136648863371285,
+ "venv/lib/python3.13/site-packages/passlib/tests/sample_config_1s.cfg": 1809713544666311828,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/models.py": 1370998944213578392,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_dialect.py": 6294522482440261756,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_set.py": 14375107704596905983,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/packaging.py": 15555781487631855604,
+ "venv/lib/python3.13/site-packages/PIL/_deprecate.py": 15076725072094847812,
+ "venv/lib/python3.13/site-packages/keyring/backend.py": 14185808762437650951,
+ "venv/lib/python3.13/site-packages/pygments/styles/xcode.py": 14124729477757765388,
+ "venv/lib/python3.13/site-packages/pygments/lexers/macaulay2.py": 8022891778577314212,
+ "venv/lib/python3.13/site-packages/numpy/fft/_helper.pyi": 9546918341939102632,
+ "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/WHEEL": 16097436423493754389,
+ "frontend/src/components/Footer.svelte": 12838918285533328222,
+ "backend/src/api/routes/datasets.py": 3167720733470487965,
+ "backend/src/services/clean_release/source_isolation.py": 9041802363608399236,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_excel.py": 5467043641314706635,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_manylinux.py": 12272275001961360101,
+ "venv/lib/python3.13/site-packages/httpx/_config.py": 8800538050293498928,
+ "venv/lib/python3.13/site-packages/greenlet/TPythonState.cpp": 12828594265749606443,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby.py": 16180421154734310873,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/req_set.py": 534498057184394558,
+ "venv/lib/python3.13/site-packages/idna/codec.py": 4260241549062101779,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_version.py": 10384171076976071398,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_lexsort.py": 10394832796613968484,
+ "venv/lib/python3.13/site-packages/pluggy/_warnings.py": 2664977718908223842,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/exc.py": 1448374203226983757,
+ "backend/tests/test_translate_corrections.py": 6483644195889451514,
+ "venv/lib/python3.13/site-packages/pygments/lexers/srcinfo.py": 16466766917840327610,
+ "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/__init__.py": 16416360448593978041,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distro/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/markers.py": 8297667990263004097,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reset_index.py": 14490875921264161445,
+ "venv/lib/python3.13/site-packages/_pytest/_code/code.py": 5248836309618416369,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_methods.py": 14881910898871057761,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_validate.py": 12789481642730855139,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/events.py": 15099787454570172797,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/unitofwork.py": 3177255974394221645,
+ "venv/lib/python3.13/site-packages/git/objects/base.py": 11498407361286170399,
+ "venv/lib/python3.13/site-packages/uvicorn/middleware/asgi2.py": 5355343704425405009,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/range.py": 3838277376774246164,
+ "venv/lib/python3.13/site-packages/pygments/cmdline.py": 15628499088643246809,
+ "frontend/e2e/fixtures/global-setup.js": 16032945890934324203,
+ "frontend/src/lib/api/translate/runs.js": 1220731879179347641,
+ "frontend/src/routes/migration/__tests__/migration_dashboard.ux.test.js": 17118608261683412409,
+ "backend/src/api/routes/clean_release.py": 9890311709059474429,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_add_prefix_suffix.py": 4815518357936092237,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py": 14571251344510763303,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/buffer.py": 12961802206383700922,
+ "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/RECORD": 10052481303799123207,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/__init__.py": 3247870839323520754,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_strings.py": 7379299916213794543,
+ "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/RECORD": 9974324769263969827,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi": 9405122752084210696,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/setup.py": 5482352991573617756,
+ "venv/lib/python3.13/site-packages/_pytest/pastebin.py": 13946273207624603063,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reduce.py": 14976712507854054776,
+ "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/WHEEL": 13232065379159720345,
+ "venv/lib/python3.13/site-packages/pygments/lexers/arturo.py": 4565524340706235725,
+ "backend/src/models/auth.py": 4040750225610660281,
+ "backend/src/services/notifications/providers.py": 12802217818475476969,
+ "venv/lib/python3.13/site-packages/jose/exceptions.py": 8562012933958941039,
+ "backend/src/core/utils/__init__.py": 12454773556575864508,
+ "backend/src/services/git/_url.py": 11387722385592868210,
+ "venv/lib/python3.13/site-packages/ecdsa/_sha3.py": 10353612776869489378,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_common.py": 9097104320321411408,
+ "venv/lib/python3.13/site-packages/starlette/staticfiles.py": 11256974306202558529,
+ "venv/lib/python3.13/site-packages/idna/core.py": 7725813731640753267,
+ "backend/ss_tools_backend.egg-info/PKG-INFO": 15134841326777953914,
+ "backend/tests/test_deprecation_audit_fixes.py": 17902995210831708431,
+ "frontend/src/lib/components/translate/TranslationRunResult.svelte": 4434171203266080686,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/introspection.py": 5447179017910128771,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_tokenizer.py": 7994281991455916540,
+ "venv/lib/python3.13/site-packages/numpy/lib/mixins.py": 7404729635424818497,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distro/__main__.py": 2688850704829116818,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayprint.pyi": 2424868797160722318,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py": 8864112842559211971,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_frame.py": 4303613319747945709,
+ "venv/lib/python3.13/site-packages/_pytest/tmpdir.py": 10834220332037364219,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_monotonic.py": 4626065848596214108,
+ "venv/lib/python3.13/site-packages/pandas/io/parquet.py": 14415622950469421518,
+ "venv/lib/python3.13/site-packages/PIL/FitsImagePlugin.py": 618556384932056120,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_as_unit.py": 4283520188709399244,
+ "frontend/build/_app/immutable/chunks/DcMPZ_fa.js": 6501595943098370468,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/retry.py": 17371295199208325375,
+ "venv/lib/python3.13/site-packages/uvicorn/server.py": 15714008348292243019,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_style.py": 6849613206971398029,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_setops.py": 15365064654930699428,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_converters.py": 8869440774594127419,
+ "backend/src/plugins/translate/__tests__/__init__.py": 2490542523242946173,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_pick.py": 15760492005471315814,
+ "venv/lib/python3.13/site-packages/passlib/utils/md4.py": 4521366665754877351,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_pwd.py": 10089138951415591061,
+ "backend/tests/test_smoke_plugins.py": 10704454611361370435,
+ "venv/lib/python3.13/site-packages/passlib/handlers/scram.py": 12281469744083867450,
+ "venv/lib/python3.13/site-packages/jaraco/context/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/highway/LICENSE": 15636145745140922094,
+ "venv/lib/python3.13/site-packages/git/remote.py": 1694919255653049944,
+ "venv/lib/python3.13/site-packages/greenlet/TGreenletGlobals.cpp": 17400526028982558937,
+ "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/LICENSE": 11167201188673981085,
+ "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/INSTALLER": 17282701611721059870,
"venv/lib/python3.13/site-packages/pandas/core/computation/align.py": 13027916530558901817,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/client_auth.py": 3301527187487914220,
+ "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/WHEEL": 9100692507274722091,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/errors.py": 16711622442922413520,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_utils.pyi": 12312677132342982866,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_info.py": 10615285239043745712,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/roles.py": 5448455900674232810,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/logging.py": 9639351759822608724,
+ "venv/lib/python3.13/site-packages/pydantic/v1/datetime_parse.py": 10467114625921924095,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_droplevel.py": 2071197388394658690,
+ "venv/lib/python3.13/site-packages/pycparser/c_lexer.py": 10964496587169353564,
+ "frontend/e2e/tests/migration.e2e.js": 7453107045608888506,
+ "backend/src/api/routes/admin_api_keys.py": 6647178786430565995,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_numpy.py": 9825804096508014886,
+ "venv/lib/python3.13/site-packages/pandas/core/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/extensions.py": 217122171232375592,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/enumerated.py": 16623643153933348755,
+ "venv/lib/python3.13/site-packages/pandas/core/apply.py": 17080038932032802984,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/generate_umath_validation_data.cpp": 10880681943327843928,
+ "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/RECORD": 7810411361439269754,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/__init__.py": 1398617034174236358,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_axis.py": 4097534573847151853,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log1p.csv": 16333455295913164408,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_linux.h": 15772978805500070727,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tls.py": 3552078393009383412,
+ "venv/lib/python3.13/site-packages/pydantic/experimental/__init__.py": 492399139963056461,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_scrypt.py": 17378030264314664250,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_struct_accessor.py": 6567451952835390075,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/visitors.py": 5190923415390076080,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/collections.py": 16114931075157411913,
+ "venv/lib/python3.13/site-packages/PIL/GifImagePlugin.py": 16073125611077200693,
+ "venv/lib/python3.13/site-packages/ecdsa/_rwlock.py": 7971972922423146201,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_case_justify.py": 8204537837649550062,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/gcp.py": 12328409672947966867,
+ "venv/lib/python3.13/site-packages/pluggy/_tracing.py": 7276210024011809655,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/numerictypes.pyi": 15565573472138344755,
+ "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.pyi": 9282436354926617898,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/expressions.py": 8015786996064244656,
+ "venv/lib/python3.13/site-packages/fastapi/openapi/models.py": 1680354178147364813,
+ "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.pyi": 2104100025130695295,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_base.py": 15292769510056833117,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_setops.py": 16240008859650640717,
+ "venv/lib/python3.13/site-packages/yaml/loader.py": 18284689412149643959,
+ "venv/lib/python3.13/site-packages/charset_normalizer/__main__.py": 8887772289570078278,
+ "venv/lib/python3.13/site-packages/pygments/lexers/factor.py": 15788613154609197002,
+ "venv/lib/python3.13/site-packages/pygments/lexers/pawn.py": 18127303119414402594,
+ "frontend/playwright-report/trace/codicon.DCmgc-ay.ttf": 15579197054804464248,
+ "frontend/src/lib/stores/__tests__/sidebar.test.js": 3057168376995255911,
+ "frontend/build/_app/immutable/nodes/20.vbM4K1GV.js": 5949005740228816871,
+ "frontend/build/_app/immutable/chunks/433xuBHg.js": 15795952494274306151,
+ "venv/lib/python3.13/site-packages/keyring/http.py": 1408024724330078009,
+ "backend/src/services/llm_prompt_templates.py": 16176053862101644239,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/_libs/join.cpython-313-x86_64-linux-gnu.so": 2947947484481830203,
+ "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/RECORD": 2688648742701423549,
+ "venv/lib/python3.13/site-packages/cffi/parse_c_type.h": 9889309594462820068,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/_mapping.py": 11752660241391232497,
+ "venv/lib/python3.13/site-packages/numpy/f2py/crackfortran.pyi": 9206355685192026844,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/topological.py": 11586868018611359415,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/__init__.py": 15130871412783076140,
+ "backend/src/plugins/translate/_batch_insert.py": 12482635271028646257,
+ "venv/lib/python3.13/site-packages/gitdb/db/__init__.py": 2615504918450276693,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/scipy_sparse.py": 2091608752719976909,
+ "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_frozen.py": 3484963987053884566,
+ "venv/lib/python3.13/site-packages/fastapi/security/api_key.py": 6965937678104291169,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/apps.py": 10758062668702044519,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/http/flow_control.py": 4822804840057360506,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_ada_builtins.py": 16331776886501464264,
+ "venv/lib/python3.13/site-packages/psycopg2/_psycopg.cpython-313-x86_64-linux-gnu.so": 13471342289207537479,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/proxy.py": 13008557041076030198,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_convert_dtypes.py": 5005259275646154894,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/extensions.py": 4132402557064663751,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine.py": 16193618152415684421,
+ "frontend/src/components/git/useGitManager.js": 1649936771399080281,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/base.py": 5294446834530589760,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/scalar_string.f90": 15018631706178918578,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string.py": 3834067244989779682,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_unary.py": 8046543893978198672,
+ "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/METADATA": 15888766579203341778,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/filetypes.py": 4415340223268174913,
+ "venv/lib/python3.13/site-packages/urllib3/connection.py": 12761371748350595804,
+ "venv/lib/python3.13/site-packages/pygments/lexers/dalvik.py": 5549983892200382076,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_setops.py": 9991233160569430204,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/cer/decoder.py": 17559787396729804535,
+ "venv/lib/python3.13/site-packages/iniconfig/__init__.py": 12623265899068631092,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_join.py": 1697622393195784944,
+ "backend/src/schemas/__init__.py": 8700952869915187087,
+ "backend/src/api/routes/assistant/_schemas.py": 17540735345133623114,
+ "venv/lib/python3.13/site-packages/pluggy/_result.py": 16790448391766505769,
+ "frontend/src/routes/datasets/review/+page.svelte": 8512810578824138490,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_is_homogeneous_dtype.py": 15378147393056707851,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period.py": 9715843209581883915,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexers.py": 6773751569163287047,
+ "frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte": 8694552424163588390,
+ "venv/lib/python3.13/site-packages/uvicorn/logging.py": 12858188863836778374,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_smoke.py": 7476432112986643847,
+ "venv/lib/python3.13/site-packages/_pytest/doctest.py": 6126919596776592278,
+ "venv/lib/python3.13/site-packages/pip/_internal/index/package_finder.py": 12631116673181479779,
+ "venv/lib/python3.13/site-packages/h11/_state.py": 11398755254809751139,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/common_with_division.f": 13517753924061311074,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/conftest.py": 17897502508251413988,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_item_selection.py": 1027989019709029615,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/url.py": 1558176735588971829,
+ "venv/lib/python3.13/site-packages/pip/_vendor/certifi/cacert.pem": 15624463015628939254,
+ "venv/lib/python3.13/site-packages/pandas/errors/cow.py": 14381282473643980776,
+ "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.pyi": 3111521453255595221,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_function_base.py": 16624804022675533740,
+ "venv/lib/python3.13/site-packages/pygments/lexers/idl.py": 11454152060351801696,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_constructors.py": 1697610790604400105,
+ "venv/lib/python3.13/site-packages/jose/jwk.py": 2781217726458801910,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/locators.py": 7638945613579396718,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/licenses/COPYING": 14459782230785388765,
+ "venv/lib/python3.13/site-packages/pygments/lexers/hdl.py": 6772823608124143123,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/endpoint.py": 13389763148720370546,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_import_utils.py": 4029157986210295967,
+ "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.py": 12251264586530536622,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/dtypes.py": 9839461501970023861,
+ "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_item.py": 17619314877770917080,
+ "venv/lib/python3.13/site-packages/numpy/random/_pcg64.pyi": 14785496840737986355,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadb.py": 3109042476851791996,
+ "venv/lib/python3.13/site-packages/bcrypt/py.typed": 15130871412783076140,
+ "frontend/playwright-report/data/d3248d538f098a40b756ead1ee1a92a7d61e7c7a.zip": 661058595618012246,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_pickle.py": 3419420815386925630,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/test_array_with_attr.py": 6568496539994758985,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_astype.py": 7542068949396266883,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_loop.py": 6502725909989655118,
+ "venv/lib/python3.13/site-packages/numpy/_globals.py": 8736093011628027941,
+ "venv/lib/python3.13/site-packages/pygments/lexers/functional.py": 15896849233007178031,
+ "frontend/src/components/tools/MapperTool.svelte": 3019722694056442354,
+ "backend/src/api/routes/__tests__/test_reports_detail_api.py": 8519050847848949612,
+ "backend/src/api/routes/git/_helpers.py": 17217408354237437064,
+ "backend/src/services/dataset_review/orchestrator_pkg/_helpers.py": 14441258905942300095,
+ "backend/git_repos/remote/test-repo.git/hooks/pre-rebase.sample": 15693225890270078290,
+ "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/WHEEL": 5076688779572520166,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ctypeslib.pyi": 8623725566434725526,
+ "venv/lib/python3.13/site-packages/anyio/_core/_signals.py": 1204322949639513552,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py": 7301817934902711510,
+ "venv/lib/python3.13/site-packages/attr/exceptions.pyi": 12323493441583681402,
+ "venv/lib/python3.13/site-packages/pygments/lexers/sql.py": 15566262873151658034,
+ "venv/lib/python3.13/site-packages/pygments/lexers/scdoc.py": 8481749542463754279,
+ "backend/tests/test_sql_table_extractor.py": 13392885324292384588,
+ "venv/lib/python3.13/site-packages/pygments/lexers/roboconf.py": 1335271183806115470,
+ "backend/src/services/clean_release/__init__.py": 9144880924791476391,
+ "venv/lib/python3.13/site-packages/jeepney/io/blocking.py": 4699555965372200059,
+ "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptography.py": 4383854709657749855,
+ "venv/lib/python3.13/site-packages/sqlalchemy/log.py": 10101221585967121334,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_delitem.py": 16538190861492829338,
+ "venv/lib/python3.13/site-packages/uvicorn/py.typed": 15240312484046875203,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_astype.py": 7497268667246913350,
+ "frontend/build/_app/immutable/chunks/_Pf3rQig.js": 13183249556030654823,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_palettes.py": 13495896173068490516,
+ "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/RECORD": 1689342214025776630,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_indexing.py": 4334578480714520407,
+ "venv/lib/python3.13/site-packages/pandas/tests/api/test_types.py": 8889829773923216769,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_bool.py": 433342705586552936,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py": 5946672289916692272,
+ "backend/src/api/routes/__tests__/test_git_api.py": 4133163122739824202,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_pickle.py": 16196792378104396231,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/extending.py": 9859383893070793914,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_calamine.py": 13354427767660487637,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_indexing.py": 1926721846569184112,
+ "venv/lib/python3.13/site-packages/charset_normalizer/cli/__main__.py": 2148876100501691980,
+ "venv/lib/python3.13/site-packages/anyio/_core/_eventloop.py": 6853955946028131785,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_shift.py": 9952689832827833247,
+ "venv/lib/python3.13/site-packages/pandas/core/construction.py": 10646956189518908985,
+ "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/RECORD": 11111103193315065053,
+ "venv/lib/python3.13/site-packages/sqlalchemy/event/base.py": 18238453132776154057,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_internal.hpp": 13173115501223013762,
+ "venv/lib/python3.13/site-packages/pandas/tests/libs/test_hashtable.py": 7762405492052106717,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/requirements.py": 11478648568700804705,
+ "venv/lib/python3.13/site-packages/pygments/lexers/sas.py": 6128008194712914874,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_lilypond_builtins.py": 1766946089314631488,
+ "backend/src/api/routes/__tests__/test_reports_api.py": 12407027129865592126,
+ "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/serializer.py": 8708767945343850816,
+ "backend/src/plugins/translate/__tests__/test_inline_correction.py": 9293076489563685553,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/modules.pyi": 131293606732000587,
+ "frontend/e2e/tests/settings.e2e.js": 1420830886812189435,
+ "venv/lib/python3.13/site-packages/numpy/f2py/__init__.pyi": 3566887042414273892,
+ "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so": 2888939866336522308,
+ "venv/lib/python3.13/site-packages/passlib/handlers/postgres.py": 14162382430051693313,
+ "frontend/src/components/TaskList.svelte": 17511781335293490363,
+ "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE": 10253862887434903467,
+ "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_utils.py": 2329717399120006435,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/yaml/constructor.py": 8731384179016992045,
+ "backend/src/core/auth/config.py": 4868978979228156169,
+ "venv/lib/python3.13/site-packages/_pytest/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_null_file.py": 6885565068723353414,
+ "frontend/src/lib/stores/sidebar.js": 4584261073573678043,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/nested_secrets.py": 15691917061715429369,
+ "venv/lib/python3.13/site-packages/pygments/lexers/html.py": 17288963642862550116,
+ "frontend/build/_app/immutable/nodes/34.xdrxaxTT.js": 17930280376609562318,
+ "backend/src/plugins/translate/orchestrator_sql.py": 15420456250044832567,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/applicator": 6870991911243684132,
+ "backend/tests/test_translate_executor_filter.py": 11717560360659156703,
+ "venv/lib/python3.13/site-packages/numpy/testing/__init__.pyi": 8126257788928282891,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_highlight.py": 7573043358244876807,
+ "venv/lib/python3.13/site-packages/urllib3/_request_methods.py": 13671055114247516883,
+ "venv/lib/python3.13/site-packages/numpy/lib/__init__.py": 12211229657513986410,
+ "venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.2.0": 2635192149914499986,
+ "venv/lib/python3.13/site-packages/PIL/IcnsImagePlugin.py": 1870235606309784691,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_shift.py": 14026124784027171225,
+ "frontend/build/_app/immutable/chunks/Bz99hFgy.js": 2788010001753617987,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/aws.py": 1364297790170663941,
+ "frontend/src/lib/components/assistant/AssistantClarificationCard.svelte": 4264349064103133826,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply_relabeling.py": 5600949862632014700,
+ "backend/git_repos/remote/test-repo.git/description": 15262637409357137373,
+ "backend/src/api/routes/__init__.py": 4671856475376690434,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_duplicates.py": 9830936017197354309,
+ "venv/lib/python3.13/site-packages/fastapi/_compat/main.py": 13016492818231995760,
+ "venv/lib/python3.13/site-packages/pygments/lexers/python.py": 8995519134978505744,
+ "backend/src/services/clean_release/__tests__/test_preparation_service.py": 1135205964675811608,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py": 6712732248328458871,
+ "backend/src/models/dataset_review_pkg/__init__.py": 1796062139548584878,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/executor.py": 2205130934861422769,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_accessor.py": 10074496835594855786,
+ "venv/lib/python3.13/site-packages/pygments/lexers/julia.py": 13516407944275342328,
+ "venv/lib/python3.13/site-packages/numpy/_core/_asarray.pyi": 3940937389249665490,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_join.py": 1364886077926604427,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimes.py": 8863748366184419339,
+ "venv/bin/keyring": 1488968652276547659,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rank.py": 14115215895836854973,
+ "backend/src/api/routes/dataset_review_pkg/_routes.py": 11040245149296528009,
+ "backend/src/plugins/debug.py": 13683182174969777939,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/httpx/_urlparse.py": 8270294590945652412,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_with_comments.f": 3980077223827767077,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_fillna.py": 8802093795040069423,
+ "venv/lib/python3.13/site-packages/websockets/sync/utils.py": 15135020989207191168,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937_regressions.py": 8981142329261965538,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sin.csv": 1443087417808027268,
+ "venv/lib/python3.13/site-packages/pygments/lexers/smithy.py": 10789533877863290582,
+ "backend/git_repos/remote/test-repo.git/objects/5d/9eb555c4cac2d3ffdba84c07682b154fe4180d": 10756202165146702691,
+ "venv/lib/python3.13/site-packages/fastapi/dependencies/models.py": 8626894872248212015,
+ "venv/lib/python3.13/site-packages/greenlet/PyModule.cpp": 3464405102256525511,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npy": 9694707264403109829,
+ "docker/nginx.conf": 14595959129793115016,
+ "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.pyi": 14069586330277925998,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_polynomial.py": 3049262771098624825,
+ "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/licenses/LICENSE": 6808958893921859106,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite.py": 3628609433179387988,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimelike.py": 394614958716301173,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/base.py": 1170652622104554892,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py": 12598431412396627042,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_engines.py": 2790877023773269276,
+ "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/licenses/LICENSE": 6653202620765194772,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict_of_blocks.py": 11646835537993064324,
+ "venv/lib/python3.13/site-packages/httpx/__init__.py": 6383055693166097719,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/__init__.py": 15130871412783076140,
+ "backend/src/api/routes/translate/_job_routes.py": 10128664562563592050,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.h": 16138871162713175599,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_set_name.py": 9094608008538024609,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/engine.py": 2652248727360250985,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpq-9b38f5e3.so.5.17": 9680474575710585826,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/__init__.py": 4014740126161973332,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/__main__.py": 487896753130729554,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.pyf": 10179237442840865225,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/asyncio.py": 11442130378027628520,
+ "venv/lib/python3.13/site-packages/requests/api.py": 12339139862411341381,
+ "venv/lib/python3.13/site-packages/websockets/extensions/permessage_deflate.py": 12957105912018691390,
+ "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.pyi": 10077265709692546934,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py": 2285778903282667561,
+ "venv/lib/python3.13/site-packages/fastapi/types.py": 3867821246650502267,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_stack_saved.py": 7767924647054186572,
+ "venv/lib/python3.13/site-packages/itsdangerous/encoding.py": 205863946173486958,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_refs.hpp": 8525862687669040510,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.py": 15657897994221955882,
+ "venv/lib/python3.13/site-packages/numpy/_core/__init__.py": 14951958843029076911,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/dtype.py": 9342837412280377086,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.cpython-313-x86_64-linux-gnu.so": 13104135217735363438,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arrow_interface.py": 5231449831607036031,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop_duplicates.py": 2397396876872403048,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_writers.py": 103545128256076790,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_first_valid_index.py": 15763400665851423183,
+ "venv/lib/python3.13/site-packages/pillow.libs/libfreetype-ee1c40c4.so.6.20.4": 12301510769231120312,
+ "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/RECORD": 2024211292009381421,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/color_triplet.py": 17264298271771184,
+ "venv/lib/python3.13/site-packages/dateutil/parser/__init__.py": 11377431154251655738,
+ "venv/lib/python3.13/site-packages/httpx/_client.py": 1063593889704982038,
+ "venv/lib/python3.13/site-packages/urllib3/util/proxy.py": 17667887856427739069,
+ "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/RECORD": 12575893084587070195,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_array_utils.py": 14682148205379122638,
+ "venv/lib/python3.13/site-packages/pandas/_testing/contexts.py": 11714205921752896137,
+ "venv/lib/python3.13/site-packages/charset_normalizer/cli/__init__.py": 9702005609966176016,
+ "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.pyi": 14543653817631274394,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/python.py": 17886036670342116501,
+ "venv/lib/python3.13/site-packages/annotated_types/__init__.py": 7367790549779882749,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/memory.py": 9947113720821563254,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/lower_f2py_fortran.f90": 13315882216322269383,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_formats.py": 10263085276270778330,
+ "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/WHEEL": 7145482834744213753,
+ "venv/lib/python3.13/site-packages/packaging/markers.py": 11602308203217831543,
+ "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_impl.py": 12056958946481531279,
+ "venv/bin/uvicorn": 3776670267111625708,
+ "venv/lib/python3.13/site-packages/websockets/extensions/__init__.py": 13067201313921664210,
+ "venv/lib/python3.13/site-packages/idna/package_data.py": 6583909243002417298,
+ "venv/lib/python3.13/site-packages/jsonschema/protocols.py": 847332300543820834,
+ "venv/lib/python3.13/site-packages/pip/_internal/build_env.py": 3614358934066127900,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_timegrouper.py": 276805119790266454,
+ "venv/lib/python3.13/site-packages/_pytest/_io/wcwidth.py": 13515196388826152383,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_api.py": 13739775047493489785,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ufuncobject.h": 5112456258078662871,
+ "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/RECORD": 11788532857617688351,
+ "venv/lib/python3.13/site-packages/pygments/lexers/spice.py": 1376126320935115350,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.pyi": 15864712173815045309,
+ "frontend/src/routes/datasets/__tests__/ColumnsTable.test.js": 15883951776898228284,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_defchararray.py": 15135904718007443306,
+ "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/METADATA": 14543822270526146783,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/content": 16257335642847993866,
+ "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/METADATA": 11419135077900073883,
+ "venv/lib/python3.13/site-packages/gitdb/test/test_util.py": 541144638852210407,
+ "venv/lib/python3.13/site-packages/pandas/io/parsers/arrow_parser_wrapper.py": 11745253171984606573,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_integer.f90": 8308927438994838783,
+ "venv/lib/python3.13/site-packages/PIL/_imagingtk.cpython-313-x86_64-linux-gnu.so": 1708198947135304326,
+ "backend/src/plugins/translate/__tests__/test_sql_generator.py": 7990788832878981127,
+ "frontend/src/lib/ui/Select.svelte": 1377129595022044035,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/events.py": 10224214051422678828,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/concat.py": 14737724508458849795,
+ "venv/lib/python3.13/site-packages/PIL/ImageShow.py": 11437096951764124817,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_linux.h": 4071314837793906998,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_nanops.py": 8709105600366913011,
+ "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/RECORD": 3283324710045856319,
+ "backend/src/plugins/translate/__tests__/test_dictionary.py": 4341966549214032934,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/METADATA": 9041650844081036822,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nep50_promotions.py": 6318578947214302182,
+ "venv/lib/python3.13/site-packages/pandas/tseries/offsets.py": 13750652921710295115,
+ "frontend/src/components/llm/ProviderConfig.svelte": 18108375341352259203,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_string.py": 11422235699126032386,
+ "venv/lib/python3.13/site-packages/numpy/_pytesttester.pyi": 5750506937526308405,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5support-d0bcff84.so.0.1": 16819924515291719993,
+ "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/ext.py": 15699809032725838985,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_export_format.py": 17862222951776199694,
+ "venv/lib/python3.13/site-packages/pandas/_libs/sas.pyi": 873957906443703977,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/RECORD": 18314788057673509075,
+ "venv/lib/python3.13/site-packages/pip/_internal/index/sources.py": 11609272011565024668,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/base.py": 3250660921154829815,
+ "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_linalg.py": 2939739913218718132,
+ "venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py": 13364803556177997526,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/ddl.py": 5006132143435653867,
+ "backend/src/plugins/translate/__tests__/test_scheduler.py": 5715885061128238668,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_unicode.py": 1103608932321322989,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isetitem.py": 14895552405828068177,
+ "venv/lib/python3.13/site-packages/secretstorage/util.py": 1004887530903069622,
+ "venv/lib/python3.13/site-packages/pydantic_core/__init__.py": 10563134104783445328,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/datasource.pyi": 80441145804744162,
+ "venv/lib/python3.13/site-packages/PIL/ImageCms.py": 5610897002957128546,
+ "venv/lib/python3.13/site-packages/sqlalchemy/__init__.py": 9751988289698484530,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/redis.py": 11313520438600819390,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py": 8079219938116542284,
+ "frontend/src/lib/api/translate/datasources.js": 17202165717960970061,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/main_parser.py": 7942770969280622910,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_indexing.py": 546024765756472196,
+ "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/METADATA": 1266134223155266488,
+ "venv/lib/python3.13/site-packages/attr/_compat.py": 4016698632899969390,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/requirements.py": 2362917888844255805,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/constant_time.py": 2499026008403328245,
+ "backend/src/models/dashboard.py": 18145369015035676491,
+ "venv/lib/python3.13/site-packages/cryptography/x509/oid.py": 13909847799728532602,
+ "venv/lib/python3.13/site-packages/numpy/__init__.pxd": 13527602429695748857,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_reindex.py": 15680924058960901067,
+ "venv/lib/python3.13/site-packages/jose/jwt.py": 3405491994268385178,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp2.csv": 10950201682596097452,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkeyutils-dfe70bd6.so.1.5": 9414227432578104677,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/_json.py": 6718137926109998531,
+ "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic/v1/types.py": 10761779263335288559,
+ "venv/lib/python3.13/site-packages/keyring/__main__.py": 14602212239605295451,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate_regression.py": 17425202198134409689,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_interval.py": 2613503970235591726,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_empty.py": 13006241382741353569,
+ "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/RECORD": 6488682447051657004,
+ "venv/lib/python3.13/site-packages/packaging/_musllinux.py": 2568338440457080365,
+ "venv/lib/python3.13/site-packages/jsonschema/exceptions.py": 15651767069704734674,
+ "frontend/build/_app/immutable/chunks/DV17vNYu.js": 5906252992532056558,
+ "venv/lib/python3.13/site-packages/keyring/__init__.py": 991260689223167957,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_typing_extra.py": 14843908493613991959,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/quoted_character/foo.f": 15318083678609435813,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_print.py": 598821365691498702,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_public_api.py": 11741922758622705449,
+ "venv/lib/python3.13/site-packages/pandas/core/frame.py": 2630807744775247533,
+ "backend/src/models/dataset_review_pkg/_filter_models.py": 11282786315414885098,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_ops.py": 3875181889032080505,
+ "backend/src/services/git/_sync.py": 18140332203522670777,
+ "venv/lib/python3.13/site-packages/websockets/sync/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/certifi/core.py": 2300277198409164253,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/comparisons.py": 7327629888601690759,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/base.py": 10205051944814316388,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py": 17106903014205241774,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pxd": 13413785818999584986,
+ "venv/lib/python3.13/site-packages/itsdangerous/__init__.py": 6969210114978365656,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_groupby.py": 12709199432838648700,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_keys.py": 10813898277355150779,
+ "venv/lib/python3.13/site-packages/attr/filters.pyi": 13942974755090135724,
+ "venv/lib/python3.13/site-packages/PIL/WebPImagePlugin.py": 5378349556563611996,
+ "frontend/src/lib/components/reports/reportTypeProfiles.js": 10752964062056890725,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/asyncmy.py": 11808138763443525443,
+ "frontend/src/lib/components/translate/TargetSchemaHint.svelte": 9354096644840520484,
+ "frontend/build/_app/immutable/chunks/1jzJINoE.js": 5138497638450462989,
+ "venv/lib/python3.13/site-packages/pydantic/v1/networks.py": 13262073155118055511,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_shape_base.py": 8837845103338426570,
+ "venv/lib/python3.13/site-packages/pandas/conftest.py": 747626550806435763,
+ "venv/lib/python3.13/site-packages/tzlocal/__init__.py": 11017072814026497364,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/constructors.py": 7587476800569414769,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_arithmetics.py": 16527169124402715210,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/errors.py": 6538052228921426956,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multithreading.py": 12547048606098186681,
+ "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.pyi": 17639497083041129225,
+ "frontend/src/routes/migration/mappings/+page.svelte": 13415361018394803129,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_info.py": 15151894356374015812,
+ "backend/src/api/routes/__tests__/test_assistant_api.py": 14069847490001200210,
+ "venv/lib/python3.13/site-packages/packaging/utils.py": 3469957615920103670,
+ "venv/lib/python3.13/site-packages/psycopg2/errors.py": 10441360078612452560,
+ "backend/src/services/dataset_review/repositories/__tests__/test_session_repository.py": 16488635694638612020,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayscalars.h": 16142050006935459679,
+ "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/tzlocal/unix.py": 995019116408448073,
+ "venv/lib/python3.13/site-packages/keyring/backends/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/devicetree.py": 9820277168995231927,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/memmap.pyi": 15629663272474054909,
+ "venv/lib/python3.13/site-packages/pandas/_libs/ops.pyi": 1192312467209548763,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_comment.py": 5603075924832933306,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dtypes.py": 4985057130807802395,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/_oid.py": 755042927629281577,
+ "venv/lib/python3.13/site-packages/pygments/lexers/boa.py": 14409319610243925864,
+ "venv/lib/python3.13/site-packages/pygments/lexers/graph.py": 10445044822847205061,
+ "frontend/src/routes/translate/history/+page.svelte": 9504117584329454876,
+ "venv/lib/python3.13/site-packages/iniconfig/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_exceptions.py": 12145393002202744314,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp": 8819301638282185623,
+ "backend/src/api/routes/__tests__/test_clean_release_v2_api.py": 17447140422807500877,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslib.pyi": 16170606956605100142,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_size.py": 12449835577388069407,
+ "venv/lib/python3.13/site-packages/yaml/events.py": 745772917931702910,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_extras.py": 16160090335191788104,
+ "venv/lib/python3.13/site-packages/anyio/lowlevel.py": 11919467357746648592,
+ "venv/lib/python3.13/site-packages/attr/_funcs.py": 5302917072419624193,
+ "venv/lib/python3.13/site-packages/keyring/testing/util.py": 11195868112805409554,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/cmdoptions.py": 12107733000019393631,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/manifest.py": 16998683210177680416,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/pretty.py": 2448541115957861214,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/__init__.py": 15130871412783076140,
+ "backend/src/plugins/translate/__tests__/test_target_schema.py": 2950009660172053425,
+ "venv/lib/python3.13/site-packages/authlib/jose/jwk.py": 13560749074922587626,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_lazyloading.py": 17465787495701737655,
+ "venv/lib/python3.13/site-packages/httpx/_transports/__init__.py": 5931944625631942279,
+ "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/zip-safe": 15240312484046875203,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply.py": 12349190935180702377,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_describe.py": 14493300276133670380,
+ "venv/lib/python3.13/site-packages/fastapi/openapi/constants.py": 1111838716953068285,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_comparison.py": 4611207880323503098,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/relationships.py": 8401569216905291119,
+ "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA": 7788873460115135563,
+ "venv/lib/python3.13/site-packages/itsdangerous/exc.py": 11181421963755661477,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_api_info.pyi": 7887489694871300469,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_sort.py": 11941630642630249576,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_markdown.py": 9964642152916165317,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/__init__.py": 15130871412783076140,
+ "backend/src/api/routes/dataset_review_pkg/_dependencies.py": 5445855387226126427,
+ "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/RECORD": 9678861487447993169,
+ "backend/tests/test_maintenance_api.py": 2012388734813578069,
+ "venv/lib/python3.13/site-packages/numpy/ma/testutils.py": 9355402483340137461,
+ "venv/lib/python3.13/site-packages/urllib3/__init__.py": 1854778274753799815,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.py": 6617116180936986481,
+ "venv/lib/python3.13/site-packages/pydantic/v1/_hypothesis_plugin.py": 6383299780629629080,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows.py": 13341168721223961872,
+ "frontend/static/favicon.png": 16740551781088792605,
+ "backend/git_repos/remote/test-repo.git/refs/heads/master": 12485529318667335076,
+ "backend/src/plugins/translate/_llm_http.py": 15686826696693103176,
+ "venv/lib/python3.13/site-packages/PIL/PsdImagePlugin.py": 4347581352716313298,
+ "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/METADATA": 1684451390569121499,
+ "venv/lib/python3.13/site-packages/pip/_internal/wheel_builder.py": 3893922370396791826,
+ "backend/src/app.py": 4335519376703786949,
+ "venv/lib/python3.13/site-packages/cffi/setuptools_ext.py": 30796527302561458,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/challenge.py": 6388445104761482746,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/__init__.py": 9106887608906281686,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_lint_dependency_groups.py": 2609365889369107154,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/__init__.py": 18019562641348687547,
+ "venv/lib/python3.13/site-packages/PIL/_avif.cpython-313-x86_64-linux-gnu.so": 5243449968857258659,
+ "venv/lib/python3.13/site-packages/pyasn1/type/__init__.py": 15728752901274520502,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90": 8048650253889213460,
+ "venv/lib/python3.13/site-packages/pygments/styles/friendly_grayscale.py": 16840106759769837649,
+ "venv/lib/python3.13/site-packages/pygments/lexers/make.py": 5345282370426217663,
+ "backend/src/plugins/llm_analysis/__tests__/test_service.py": 17317408415318686082,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_ops.py": 14420421526781215500,
+ "backend/src/dependencies.py": 13564949183453082453,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/padding.py": 11244071766694094554,
+ "venv/lib/python3.13/site-packages/pillow.libs/libbrotlidec-b57ddf63.so.1.2.0": 10032590058372320813,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray.pyi": 14369009813591437391,
+ "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/revocation.py": 16178499278312777474,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/uts46data.py": 1867240043777383728,
+ "venv/lib/python3.13/site-packages/gitdb/exc.py": 13975852664048821278,
+ "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.pyi": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/future/__init__.py": 17688444679736059779,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_generation_shared.py": 23345689300073549,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/scoping.py": 17216492046645992674,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/RECORD": 10264342250058307301,
+ "venv/lib/python3.13/site-packages/pandas/io/stata.py": 14370692318835340323,
+ "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayobject.py": 13337664596833150958,
+ "venv/lib/python3.13/site-packages/httpx/_exceptions.py": 18399489130669465891,
+ "venv/lib/python3.13/site-packages/pandas/core/arraylike.py": 11439602957100017713,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_comparisons.py": 2764694394636775220,
+ "venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so": 561326734302492859,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_style.tpl": 3352086677417301397,
+ "venv/lib/python3.13/site-packages/pandas/_libs/indexing.cpython-313-x86_64-linux-gnu.so": 13188040757764159731,
+ "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/METADATA": 11557342107649194148,
+ "venv/lib/python3.13/site-packages/keyring/compat/py312.py": 17581691618899404491,
+ "venv/lib/python3.13/site-packages/smmap/__init__.py": 4557520096828426601,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/autocompletion.py": 7651919329635563739,
+ "venv/lib/python3.13/site-packages/cryptography/__about__.py": 10471312538528457144,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh27697.f90": 4990763135487995517,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_totp.py": 9150389741890748343,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_pickle.py": 2910383574326146698,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unique.py": 6234921572794573905,
+ "venv/lib/python3.13/site-packages/pygments/lexers/rnc.py": 9747352274729854620,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/distributions.h": 17162252287980242413,
+ "frontend/build/_app/immutable/nodes/37.CZZV_jk9.js": 7416395561147821738,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_3kcompat.h": 5377305123299457337,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/dtype_api.h": 17040779421165903019,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_stride_tricks.py": 1064774375151677743,
+ "venv/lib/python3.13/site-packages/passlib/handlers/scrypt.py": 10089372287597257402,
+ "venv/lib/python3.13/site-packages/git/index/__init__.py": 7874728461616959441,
+ "venv/lib/python3.13/site-packages/pygments/lexers/fortran.py": 6859638690245583968,
+ "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.hpp": 6366432579621298231,
+ "backend/src/schemas/dataset_review_pkg/_composites.py": 9530969677898630695,
+ "examples/maintenance-api-bash.sh": 674396824183793987,
+ "backend/src/services/git/_gitea.py": 2348444900635153882,
+ "venv/lib/python3.13/site-packages/authlib/jose/util.py": 14843923624043422219,
+ "venv/lib/python3.13/site-packages/git/objects/util.py": 691018806932355307,
+ "frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte": 2668118032578627739,
+ "frontend/src/components/TaskLogViewer.svelte": 15158021998452088463,
+ "venv/lib/python3.13/site-packages/attrs/validators.py": 10346563361083429998,
+ "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.pyi": 15745512451486888537,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/interval.py": 17965911911189276907,
+ "venv/lib/python3.13/site-packages/pandas/tests/interchange/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/__init__.py": 17454177076687312424,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/json.py": 15085143436056608404,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/__init__.py": 12975130533860125272,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/introspection.py": 14645217065508644154,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_extension_array_equal.py": 16119106336497630796,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_na_indexing.py": 8712547126522523899,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_arithmetic.py": 16829312896275893002,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_quarter.py": 6795026338946382805,
+ "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.py": 338595621218646492,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_sample.py": 4641567828238191927,
+ "venv/lib/python3.13/site-packages/pygments/lexers/sieve.py": 15757825442941567629,
+ "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/zip-safe": 15240312484046875203,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/jwt_bearer.py": 6973859422068490274,
+ "venv/lib/python3.13/site-packages/click/decorators.py": 2920877667855377423,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/conftest.py": 2643915042664055969,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_legacy.py": 9226692984248279094,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/core.py": 14576109242055156193,
+ "venv/lib/python3.13/site-packages/httpx/_transports/default.py": 8391302827983907910,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/privatemod.f90": 8999550841368314739,
+ "backend/logs/app.log.1": 1282701464293071456,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/search.py": 8292218231992728142,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/test_round.py": 7912161077874611432,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_halfyear.py": 9376272342364384767,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/_elements_constructors.py": 9279447066034364952,
+ "venv/lib/python3.13/site-packages/itsdangerous/serializer.py": 14271229091461164933,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_parse_dates.py": 5344929031479212951,
+ "backend/src/models/assistant.py": 13943482616669949278,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/_suite.py": 6307666366417438489,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_xlrd.py": 14430937200583666658,
+ "backend/src/services/llm_provider.py": 7079748167598543116,
+ "venv/lib/python3.13/site-packages/PIL/Image.py": 13615925856053031482,
+ "venv/lib/python3.13/site-packages/anyio/streams/text.py": 12507591237176920223,
+ "backend/src/plugins/translate/dictionary.py": 4150581558765697237,
+ "backend/git_repos/remote/test-repo.git/objects/ae/8d2f5dec5d421b2d6cc1eebaad6d2ef901a90d": 15877648001251681939,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/asyncio.py": 2230610508870117058,
+ "venv/lib/python3.13/site-packages/packaging/licenses/_spdx.py": 16440031845441362300,
+ "backend/:memory:test_tasks": 9776368437354383244,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/type_check.pyi": 9177256991985898824,
+ "venv/lib/python3.13/site-packages/numpy/core/numerictypes.py": 5776941405348611027,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_html.py": 7947998260347730581,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/dml.py": 5340326603935367534,
+ "venv/lib/python3.13/site-packages/pip/_internal/distributions/sdist.py": 9490366272695301385,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_known_annotated_metadata.py": 9308620143218174987,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_size.py": 8527839563560550806,
+ "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/RECORD": 9502524172853437600,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/filewrapper.py": 17786759398959482432,
+ "venv/lib/python3.13/site-packages/pydantic/_migration.py": 17982816821930887921,
+ "venv/lib/python3.13/site-packages/pygments/lexers/modula2.py": 6575895980250662093,
+ "frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte": 16168905765241471813,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_indexing.py": 16264430536704066847,
+ "frontend/build/_app/immutable/chunks/Dqq0IY0w.js": 2853802158798956279,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_ctypeslib.py": 9592016432737074765,
+ "venv/lib/python3.13/site-packages/anyio/streams/memory.py": 11762722143503428823,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_crosstab.py": 6631711416347033281,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_algos.py": 5356470832688354593,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/__init__.py": 11009955319062089477,
+ "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/METADATA": 732041908491732594,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get.py": 6509102681661636928,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_throw.py": 4119265751381210399,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/date/array.py": 18073740473413382768,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polyutils.pyi": 3841660741524427413,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_wrap.py": 17083394123203662880,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlrd.py": 9982457234958102003,
+ "venv/lib/python3.13/site-packages/PIL/ImageFilter.py": 10974179993355630141,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_dict.py": 4937173601709369119,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_repr.py": 11737029058271003097,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/providers.py": 7267821734584612032,
+ "venv/lib/python3.13/site-packages/uvicorn/__init__.py": 11517239807926185665,
+ "backend/src/schemas/dataset_review_pkg/_dtos.py": 10114042767789130927,
+ "backend/src/api/routes/translate/_metrics_routes.py": 14203374652620439805,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_asof.py": 18383318159051131669,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cython.py": 14695721638531081573,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_boxplot_method.py": 7635131059308651529,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarmath.py": 9762951701352556447,
+ "venv/lib/python3.13/site-packages/pygments/lexers/inferno.py": 9056274496469409594,
+ "backend/src/api/routes/translate/_helpers.py": 6946167155296110158,
+ "venv/lib/python3.13/site-packages/fastapi/openapi/utils.py": 9058442333718187759,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata.py": 2021612995853910808,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_cpp.py": 10982107081267457286,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_pipe.py": 8255917221095334212,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/wrapper.py": 4633931060151989960,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_loc.py": 2127584756555503873,
+ "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/REQUESTED": 15130871412783076140,
+ "backend/src/services/security_badge_service.py": 18061005101062867126,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_drop_duplicates.py": 12601598844977346213,
+ "backend/git_repos/remote/test-repo.git/objects/a7/49f11fad695dff77faf1708c7320867d0be1df": 4641609158325033031,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/__init__.py": 63497920264089252,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_numba.py": 1548992314517942530,
+ "venv/lib/python3.13/site-packages/PIL/__main__.py": 827665918723937817,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pct_change.py": 18056235438452125034,
+ "backend/src/models/config.py": 17311376253737985673,
+ "venv/lib/python3.13/site-packages/urllib3/util/ssl_.py": 11720964010284185952,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo90.f90": 15981076495193915107,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_np_datetime.py": 18363183516409621205,
+ "venv/lib/python3.13/site-packages/rapidfuzz/process.py": 3870006735299537016,
+ "venv/lib/python3.13/site-packages/_pytest/unraisableexception.py": 4597178803320514675,
+ "venv/lib/python3.13/site-packages/numpy/lib/_version.pyi": 10804755840730584157,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel_py.py": 9112851333217812996,
+ "venv/lib/python3.13/site-packages/numpy/random/_pickle.pyi": 16081120364372391381,
+ "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/iniconfig/exceptions.py": 16501270224069836264,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/base.cpython-313-x86_64-linux-gnu.so": 8335798324308957127,
+ "venv/lib/python3.13/site-packages/_pytest/_py/path.py": 8464061867075119556,
+ "scripts/gen_semantics.py": 11397714264377363083,
+ "venv/lib/python3.13/site-packages/numpy/random/_common.pyi": 5094115692952609118,
+ "venv/lib/python3.13/site-packages/idna/uts46data.py": 5698404064763638591,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_resolution.py": 6076761538303762297,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_numerictypes.py": 8836108334624807647,
+ "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/RECORD": 3205266407680661753,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_dialect.py": 4700488504252803159,
+ "venv/lib/python3.13/site-packages/sqlalchemy/connectors/aioodbc.py": 2018840826888846321,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/json.py": 14738429697319670035,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_windows.py": 9171347078900057357,
+ "venv/lib/python3.13/site-packages/pygments/styles/monokai.py": 12381683616720952636,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py": 5324490103277723813,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_series.py": 16418555817529711079,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tact.py": 1164971357219795420,
+ "venv/lib/python3.13/site-packages/pygments/lexers/yang.py": 7409365668425173823,
+ "venv/lib/python3.13/site-packages/rapidfuzz/utils_cpp.cpython-313-x86_64-linux-gnu.so": 16145829319198889672,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/background.py": 2105814165112049750,
+ "frontend/playwright-report/trace/snapshot.v8KI4P3m.js": 7854911091722310751,
+ "venv/lib/python3.13/site-packages/h11/_headers.py": 7592730288271984585,
+ "frontend/src/lib/components/settings/ApiKeysTab.svelte": 17208249963941978218,
+ "venv/bin/pyrsa-keygen": 8222542582170363672,
+ "frontend/src/components/git/DeploymentModal.svelte": 3761818357348583741,
+ "frontend/build/_app/immutable/chunks/N9kT4r7O.js": 11367070149438687372,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/util.py": 5252158959761945519,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/strings.pyi": 402863478592154500,
+ "venv/lib/python3.13/site-packages/pandas/_config/__init__.py": 3577026529387563519,
+ "venv/lib/python3.13/site-packages/keyring/backend_complete.zsh": 14339032329370660432,
+ "backend/src/api/routes/settings.py": 7176893095762662218,
+ "backend/src/services/__tests__/test_llm_prompt_templates.py": 12364821019604393930,
+ "venv/lib/python3.13/site-packages/numpy/fft/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/ecdsa/errors.py": 11755424742691057760,
+ "venv/lib/python3.13/site-packages/pandas/io/__init__.py": 9767690163638898709,
+ "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/METADATA": 2810323639884879396,
+ "venv/lib/python3.13/site-packages/passlib/tests/sample1c.cfg": 13088198405762342506,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets.py": 4499538899492148499,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/melt.py": 14109947554124551986,
+ "frontend/src/lib/stores/__tests__/test_activity.js": 13851679930048900037,
+ "backend/git_repos/remote/test-repo.git/objects/8c/4ea7958b7a7e140d27e1e7d8d1f9912fdf5992": 5862166356451798197,
+ "venv/lib/python3.13/site-packages/pygments/lexers/nit.py": 18262907536841158657,
+ "backend/src/plugins/translate/orchestrator_run_completion.py": 1246106720048798445,
+ "backend/src/plugins/translate/preview_response_parser.py": 15690759478655959205,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py": 12264234876933578367,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/install/wheel.py": 3531093454660385247,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_get_dummies.py": 14871264482622327003,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_where.py": 14167991754625133668,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_week.py": 5756727157937218128,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/common.py": 13335865314907577354,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/__init__.py": 15340047930888693984,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/xml.py": 12235904458551067063,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ezhil.py": 10294520768762308887,
+ "frontend/e2e/tests/git.e2e.js": 10018194126657448104,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_dict_compat.py": 18196543090455290455,
+ "frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js": 1873684170678703500,
+ "venv/lib/python3.13/site-packages/PIL/ImageChops.py": 16368812693381154921,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/qt.py": 12828696264909048448,
+ "venv/lib/python3.13/site-packages/urllib3/util/retry.py": 17988032431204662756,
+ "venv/lib/python3.13/site-packages/pandas/_libs/parsers.cpython-313-x86_64-linux-gnu.so": 14134106903573638108,
+ "backend/src/api/routes/health.py": 13097980848666987664,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_format.py": 1947585389944838076,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategies.py": 15673926142454922581,
+ "venv/lib/python3.13/site-packages/passlib/handlers/des_crypt.py": 15304795681178011265,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/meson.build": 9642189398934130247,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jws_algs.py": 11920621906391796226,
+ "venv/lib/python3.13/site-packages/numpy/_core/_internal.pyi": 6840742333427164920,
+ "venv/lib/python3.13/site-packages/pandas/core/window/common.py": 17956497339875932377,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/__init__.py": 348469143777130970,
+ "venv/lib/python3.13/site-packages/referencing/retrieval.py": 11921179805977833120,
+ "venv/lib/python3.13/site-packages/pandas/tests/config/test_localization.py": 9524481848419616725,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_arrow_interface.py": 9757086292358759236,
+ "venv/lib/python3.13/site-packages/starlette/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/referencing/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_unix.h": 13709837360414450184,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_quoted_character.py": 2316632434571797367,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_cross.py": 17742712348672218852,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.h": 4516275133897904047,
+ "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/datetimelike.py": 4356700619632833878,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/http2.py": 11167798787131917524,
+ "venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py": 10265081145401348863,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/response.py": 9594165377270752433,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_postgres_builtins.py": 2383906454995727700,
+ "venv/lib/python3.13/site-packages/psycopg2/_ipaddress.py": 12332672835751787869,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_clip.py": 8087139801274517318,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_old_ma.py": 18116460138221458026,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_value_counts.py": 5534713464063604301,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/common.py": 2075178842766962782,
+ "venv/lib/python3.13/site-packages/PIL/ImageGrab.py": 11114379915762058868,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/__init__.py": 5289703478893407762,
+ "venv/lib/python3.13/site-packages/pydantic/errors.py": 3506829204186508192,
+ "venv/lib/python3.13/site-packages/numpy/testing/__init__.py": 2831275254313750978,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_equivalence.py": 17843623343419137458,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/sas/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/_arrow_string_mixins.py": 16862663427780315543,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/types.py": 356973910046950951,
+ "venv/lib/python3.13/site-packages/pandas/io/pytables.py": 17482934215513855928,
+ "venv/lib/python3.13/site-packages/PIL/Jpeg2KImagePlugin.py": 16905402423248975204,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ncl.py": 14838368780033177943,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress.py": 5951745251426856398,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/wsgi.py": 3706578020491442104,
+ "venv/lib/python3.13/site-packages/_pytest/config/argparsing.py": 11156052029258891503,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nditer.pyi": 33523064068376750,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_repeat.py": 11360772447747837958,
+ "venv/bin/Activate.ps1": 1196103427939049710,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_period.py": 3419297908709788013,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/socks.py": 645086578806871685,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_put.py": 8547660958963625817,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/WHEEL": 9131187629260560775,
+ "frontend/src/routes/settings/StorageSettings.svelte": 1953157077500445570,
+ "frontend/src/components/StartupEnvironmentWizard.svelte": 17705330033482916904,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/emscripten_fetch_worker.js": 10530710876604536879,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/base.py": 10200916670889920659,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_dtype.py": 1647214604678171565,
+ "frontend/src/routes/+page.ts": 11160596731849880920,
+ "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.asm": 16630507336149184509,
+ "venv/lib/python3.13/site-packages/pandas/compat/_optional.py": 12714208019736797073,
+ "frontend/build/_app/immutable/chunks/DqW8GI5e.js": 3350755737206734900,
+ "backend/src/plugins/translate/__tests__/test_token_budget.py": 2275341408164077909,
+ "frontend/src/routes/settings/LlmSettings.svelte": 10881646244972773692,
+ "venv/lib/python3.13/site-packages/pydantic/json_schema.py": 15678278224696353978,
+ "venv/lib/python3.13/site-packages/numpy/lib/user_array.py": 14003456655595459585,
+ "venv/lib/python3.13/site-packages/numpy/core/__init__.pyi": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_matmul.py": 9323220618335072725,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/naming.py": 14503932124671438340,
+ "venv/lib/python3.13/site-packages/keyring/backends/Windows.py": 4103830951042463184,
+ "venv/bin/numpy-config": 17104619511899110252,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/cursor.py": 8074527784886981710,
+ "backend/src/core/auth/__tests__/test_auth.py": 6524647391979341734,
+ "venv/lib/python3.13/site-packages/pygments/lexers/asn1.py": 15030988816882821134,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/hash.py": 11824898770873127699,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/assignOnlyModule.f90": 15967199601254912096,
+ "backend/src/core/__init__.py": 8673978627093182792,
+ "backend/git_repos/remote/test-repo.git/objects/52/ec4a78c629329b8b572ec9d5205271c111baac": 18054296544295201561,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_isocalendar.py": 5704842983090753914,
+ "venv/lib/python3.13/site-packages/uvicorn/middleware/message_logger.py": 14825516604555033580,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/common.py": 5369352684655954608,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/completion.py": 4435231315212798769,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.py": 1731362089136926666,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_numba.py": 203614377324678234,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_reindex.py": 15794750188594767026,
+ "venv/lib/python3.13/site-packages/charset_normalizer/api.py": 9172704759115759638,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/adapter.py": 5908944827805063108,
+ "frontend/src/routes/tools/storage/+page.svelte": 8817697925409987305,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_css.py": 17765129030290410902,
+ "backend/tests/core/migration/test_archive_parser.py": 8027202509785909637,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/install/editable_legacy.py": 8145740626773638218,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_categorical.py": 12897027063618569795,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_contextvars.py": 6077482318964702132,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/RECORD": 6187512110158566509,
+ "venv/lib/python3.13/site-packages/passlib/handlers/mssql.py": 2800599582708170195,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_categorical.py": 18254320571347851153,
+ "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/RECORD": 4857922668040624663,
+ "venv/lib/python3.13/site-packages/numpy/lib/_datasource.py": 18136853038949826147,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_dt_accessor.py": 2229616362327032253,
+ "frontend/src/lib/components/reports/ReportDetailPanel.svelte": 5659980083465412500,
+ "venv/lib/python3.13/site-packages/pluggy/__init__.py": 8269188363563356631,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90": 2657057181044959432,
+ "venv/lib/python3.13/site-packages/git/refs/symbolic.py": 14996822770181935589,
+ "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/METADATA": 7214286447912789067,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.pyi": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/pascal.py": 5992422120590352714,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/__init__.py": 15130871412783076140,
+ "frontend/playwright-report/trace/codeMirrorModule.DYBRYzYX.css": 14866915564324637173,
+ "venv/lib/python3.13/site-packages/requests/hooks.py": 9888227370911151341,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_astype.py": 6578539240745332772,
+ "venv/lib/python3.13/site-packages/anyio/_core/_asyncio_selector_thread.py": 1760597191437520000,
+ "venv/lib/python3.13/site-packages/pydantic/alias_generators.py": 5991580234179623842,
+ "venv/lib/python3.13/site-packages/authlib/oidc/registration/__init__.py": 9448552677419908109,
+ "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.pyi": 9291444594181042963,
+ "venv/lib/python3.13/site-packages/attr/_make.py": 2348458829123990579,
+ "venv/lib/python3.13/site-packages/keyring/devpi_client.py": 3445890176686211982,
+ "venv/lib/python3.13/site-packages/numpy/_core/getlimits.py": 7842717073693731093,
+ "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/licenses/LICENSE": 12684353321716745791,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/setitem.py": 9552868454186447925,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_arithmetic.py": 16045758521544316139,
+ "backend/src/services/clean_release/repositories/__init__.py": 10330511711442503831,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_api_info.py": 16491629653122827368,
+ "venv/lib/python3.13/site-packages/pandas/core/window/online.py": 13551140636252302201,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/check.py": 16048939716341154196,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_custom_dtypes.py": 12322100282959605055,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_http_headers.py": 13187746870209705951,
+ "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_at.py": 1029744344133153888,
+ "frontend/src/lib/stores/__tests__/mocks/navigation.js": 16028014574825445651,
+ "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.py": 12771179468704314203,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/__init__.py": 2345997696115514124,
+ "venv/lib/python3.13/site-packages/PIL/ImageFile.py": 15765130658900167517,
+ "frontend/src/components/backups/BackupList.svelte": 7178110735645066783,
+ "backend/tests/services/clean_release/test_candidate_manifest_services.py": 14438251683804094377,
+ "docker/frontend.entrypoint.sh": 11397342350356400663,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpcre-9513aab5.so.1.2.0": 12298861477332583668,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_invalid.py": 2762344062554575805,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsin.csv": 1665171675551692225,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_join.py": 13115782559805895662,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test__version.py": 9037916251087760255,
+ "venv/lib/python3.13/site-packages/PIL/PcdImagePlugin.py": 922809545463280224,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_overrides.py": 92685611709898742,
+ "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD": 173225030102092319,
+ "venv/lib/python3.13/site-packages/authlib/oidc/discovery/__init__.py": 308178910015974550,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/bitwise_ops.pyi": 15598239133239520456,
+ "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/RECORD": 6518517239543344179,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/modules.pyi": 14176187662591164602,
+ "venv/lib/python3.13/site-packages/websockets/legacy/auth.py": 16685128086396181286,
+ "venv/lib/python3.13/site-packages/pygments/formatters/groff.py": 6480830447984073574,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/common.py": 9354442374897565498,
+ "venv/lib/python3.13/site-packages/pygments/styles/emacs.py": 4540417536507245024,
+ "venv/lib/python3.13/site-packages/anyio/_core/_exceptions.py": 11969894261631227715,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_subclass.py": 16342917051908786497,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ooc.py": 14540210212631538007,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/_arrow_utils.py": 17808805047762566525,
+ "venv/lib/python3.13/site-packages/websockets/streams.py": 15786581670248099415,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/sqltypes.py": 2952996080192295188,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_replace.py": 15992095120302643273,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/structs.py": 4479429145468072604,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/common.py": 17314999825118928100,
+ "frontend/src/routes/datasets/DatasetList.svelte": 12931773180198281284,
+ "venv/lib/python3.13/site-packages/_pytest/monkeypatch.py": 2635774457434545573,
+ "venv/lib/python3.13/site-packages/ecdsa/test_numbertheory.py": 2117130219401053225,
+ "frontend/src/components/git/GitOperationsPanel.svelte": 5140779139910068800,
+ "frontend/build/_app/immutable/chunks/aniH9ONl.js": 11297774342683903539,
+ "venv/lib/python3.13/site-packages/requests/__version__.py": 6677532709758546816,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/jws_eddsa.py": 833927568269372333,
+ "frontend/build/_app/immutable/chunks/DWg3slHj.js": 16432655720744147297,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_formats.py": 13752366280743004410,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_asymmetric.py": 6903778603779934572,
+ "backend/src/scripts/create_admin.py": 12963729348700590154,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/scalars.pyi": 3130685119595923378,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_frame_equal.py": 12459816298158655274,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_indexing.py": 11572911419313573163,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_reflection.py": 10520778598547003532,
+ "venv/lib/python3.13/site-packages/fastapi/openapi/docs.py": 16735218221639179927,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/test_isfile.py": 14544060093268573418,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_astype.py": 4023134352880775277,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/array.py": 3517673819082574078,
+ "venv/lib/python3.13/site-packages/pip/_internal/vcs/__init__.py": 1197579313959289096,
+ "venv/lib/python3.13/site-packages/pygments/lexers/phix.py": 16775285097768256238,
+ "venv/lib/python3.13/site-packages/numpy.libs/libquadmath-96973f99-934c22de.so.0.0.0": 5098713761946118139,
+ "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pygments/lexers/lilypond.py": 1088755646568511197,
+ "frontend/playwright-report/trace/uiMode.html": 2646979321132705707,
+ "frontend/src/lib/api/validation.js": 10650815174196870103,
+ "venv/lib/python3.13/site-packages/pytest_asyncio/__init__.py": 8162213292669110211,
+ "backend/src/core/timezone.py": 15725829269123183582,
+ "venv/lib/python3.13/site-packages/pandas/compat/_constants.py": 3909166275649444824,
+ "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.py": 9409852116555866847,
+ "venv/lib/python3.13/site-packages/pygments/styles/gruvbox.py": 9489017112545247388,
+ "backend/tests/scripts/test_clean_release_tui_v2.py": 5872535102885848729,
+ "backend/tests/test_dashboards_api.py": 15709552949816760924,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/pubprivmod.f90": 8680230823849248800,
+ "venv/lib/python3.13/site-packages/pip/_internal/index/collector.py": 7454652626329467900,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress_bar.py": 15595912766961891283,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_errors.py": 3301889847545579393,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/mock.py": 14010776046610111182,
+ "venv/lib/python3.13/site-packages/rapidfuzz/process_py.py": 17563673072076876125,
+ "venv/lib/python3.13/site-packages/greenlet/TExceptionState.cpp": 17617354576371846109,
+ "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/RECORD": 963865046004908868,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape.pyi": 2188930129299348535,
+ "venv/lib/python3.13/site-packages/pandas/tseries/__init__.py": 2648641118117738895,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_regression.py": 6742646011852052645,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_append.py": 17016125916761365423,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_indexing.py": 4063662953863959087,
+ "venv/lib/python3.13/site-packages/git/cmd.py": 8854786163152637148,
+ "venv/lib/python3.13/site-packages/git/objects/commit.py": 12317865358846331802,
+ "venv/lib/python3.13/site-packages/pycparser/c_generator.py": 14922277346364091122,
+ "venv/lib/python3.13/site-packages/websockets/client.py": 5229500079651465772,
+ "venv/lib/python3.13/site-packages/idna/intranges.py": 12536174834761591006,
+ "venv/lib/python3.13/site-packages/sqlalchemy/connectors/pyodbc.py": 4146960201984489604,
+ "venv/lib/python3.13/site-packages/numpy/_utils/__init__.pyi": 13530522898409268883,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/__init__.py": 697601512486720554,
+ "frontend/playwright-report/data/fe71864b4cbf83c1ddaa5774098c6fa987f91ff9.webm": 9945873951473992150,
+ "frontend/src/lib/stores/__tests__/test_taskDrawer.js": 14849615218402542643,
+ "venv/lib/python3.13/site-packages/psycopg2/extensions.py": 14197445323992851566,
+ "backend/tests/test_task_manager.py": 4305202721942095979,
+ "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/tokens_mixins.py": 9923721909178724437,
+ "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/licenses/LICENSE": 7959949171752474553,
+ "venv/lib/python3.13/site-packages/pandas/tests/internals/test_api.py": 11217428888457119601,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/__init__.py": 15728752901274520502,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/__init__.py": 4752355175318979033,
+ "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/LICENSE": 8423899413955829149,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/rsa.py": 5392922995791487437,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_codes.py": 13901854719435716195,
+ "venv/lib/python3.13/site-packages/pandas/core/api.py": 3390809109543982410,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli/py.typed": 9796674040111366709,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/__init__.py": 2397613800206300456,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_stata.py": 3030675968330529905,
+ "venv/lib/python3.13/site-packages/secretstorage/dhcrypto.py": 8860116996905452758,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/_color_data.py": 15614976586613738953,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_getitem.py": 18202683049446557047,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/array.py": 13840510238256626632,
+ "venv/lib/python3.13/site-packages/PIL/PdfImagePlugin.py": 16082854250442815862,
+ "backend/src/plugins/translate/_llm_call.py": 12276699540223140419,
+ "backend/src/plugins/translate/orchestrator_runner.py": 6903994426268521649,
+ "backend/src/services/mapping_service.py": 14740129302452546978,
+ "venv/lib/python3.13/site-packages/numpy/random/_generator.pyi": 17167649524261942483,
+ "venv/lib/python3.13/site-packages/tzlocal/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_win32.py": 13932956220195912963,
+ "venv/lib/python3.13/site-packages/pandas/core/util/hashing.py": 13106575357604888913,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_fillna.py": 7244491410004453166,
+ "venv/lib/python3.13/site-packages/httpx/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_astype.py": 563689238486630866,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayterator.pyi": 15722265241660279277,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_observance.py": 18178414966262524534,
+ "venv/lib/python3.13/site-packages/typing_inspection/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/httpx/_models.py": 6516278895118988231,
+ "venv/lib/python3.13/site-packages/PIL/__init__.py": 10393984345353752724,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_logical.py": 6242457515917145500,
+ "venv/lib/python3.13/site-packages/pycparser/ply/cpp.py": 1665654017894222868,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asof.py": 17616601748321325187,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_mrecords.py": 15952147778503828707,
+ "venv/lib/python3.13/site-packages/pygments/lexers/bqn.py": 11823648528816858738,
+ "frontend/build/_app/immutable/nodes/5.WMl_CdkR.js": 10177272070910457308,
+ "venv/lib/python3.13/site-packages/passlib/utils/decor.py": 21351391767102899,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polyutils.py": 675639791972685455,
+ "venv/lib/python3.13/site-packages/pygments/styles/abap.py": 11543320440974964547,
+ "backend/src/schemas/auth.py": 2548857752520407876,
+ "venv/lib/python3.13/site-packages/git/types.py": 13960696584646279283,
+ "venv/lib/python3.13/site-packages/websockets/extensions/base.py": 2457233337788783873,
+ "venv/lib/python3.13/site-packages/more_itertools/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_libfrequencies.py": 16302676625743291594,
+ "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/WHEEL": 691462085217888236,
+ "backend/src/plugins/translate/orchestrator_planner.py": 16598342286617456459,
+ "venv/lib/python3.13/site-packages/starlette/applications.py": 13591448461234020757,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply_relabeling.py": 3930092097678339743,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/diagnose.py": 17275977405061138181,
+ "venv/lib/python3.13/site-packages/pandas/_libs/lib.pyi": 3049004444338566197,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_where.py": 16584772339591698754,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_iterrows.py": 3791886201566670087,
+ "venv/lib/python3.13/site-packages/pygments/styles/vs.py": 4188729978573652106,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_symbol.py": 10792387279408528886,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/multi.py": 9115751979327393200,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c": 17333399794446198412,
+ "venv/lib/python3.13/site-packages/packaging/_structures.py": 13086687542872305890,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi": 11455144434558323236,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_arithmetic.py": 976970179757115407,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/metadata.py": 7204343250279221076,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/_locales.py": 18178500267053825979,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix_py.py": 6653895521961110080,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_convert_dtypes.py": 13612212066710266457,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_openid.py": 8708980645667847439,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_legacy.py": 12735901522735836481,
+ "venv/lib/python3.13/site-packages/rsa/pem.py": 3118524021576082054,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/scanner.py": 5640381644804445932,
+ "venv/lib/python3.13/site-packages/pandas/core/indexing.py": 15507869313676722071,
+ "venv/lib/python3.13/site-packages/pandas/util/_print_versions.py": 15326663505771588740,
+ "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/AUTHORS": 2987771679926243782,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/queue.py": 1289234691048379395,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/__init__.py": 12290228927283601067,
+ "venv/lib/python3.13/site-packages/charset_normalizer/md.cpython-313-x86_64-linux-gnu.so": 1835299664481804968,
+ "venv/lib/python3.13/site-packages/pygments/styles/manni.py": 11853576691280294949,
+ "frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js": 17228280298558782730,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_thread_support.hpp": 7773996382104849037,
+ "venv/lib/python3.13/site-packages/gitdb/test/lib.py": 13294941660283059872,
+ "venv/lib/python3.13/site-packages/pip/_internal/distributions/wheel.py": 13979536782410081712,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/target_python.py": 422323125651848065,
+ "frontend/src/components/git/GitWorkspacePanel.svelte": 4516972512005887443,
+ "venv/lib/python3.13/site-packages/_pytest/unittest.py": 10848803633530338204,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arccos.csv": 3026156288992132911,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24662.f90": 4241310200087270990,
+ "backend/src/services/notifications/service.py": 3120728755335117444,
+ "venv/lib/python3.13/site-packages/numpy/core/_multiarray_umath.py": 10973016138581934035,
+ "backend/src/services/clean_release/stages/internal_sources_only.py": 6150576100887638944,
+ "backend/tests/test_storage_audit_fixes.py": 6119862973635892572,
+ "venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0": 7322566017497612912,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.cpython-313-x86_64-linux-gnu.so": 7840846965295537844,
+ "backend/tests/services/clean_release/test_report_audit_immutability.py": 4795829940402801626,
+ "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/WHEEL": 7454950858448014158,
+ "venv/lib/python3.13/site-packages/multipart/__init__.py": 6496114190873890851,
+ "venv/lib/python3.13/site-packages/numpy/lib/_iotools.pyi": 12873243737872788349,
+ "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/METADATA": 3044554568188160018,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90": 15012692484070385863,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/getlimits.pyi": 93747984191461691,
+ "backend/_batch_convert_defs.py": 2671571251303777016,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_alpha_unix.h": 2759424570606117942,
+ "frontend/src/lib/utils/debounce.js": 11611676161433422398,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_map.py": 4761668276463940924,
+ "backend/src/plugins/__init__.py": 17194112070692432889,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_npfuncs.py": 8238385897366878558,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_reductions.py": 17810094294132819208,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py": 6152202474302791232,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_analytics.py": 8155550493311083506,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/claims.py": 11853156183819186599,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/api.py": 16364136812252343076,
+ "venv/lib/python3.13/site-packages/h11/_receivebuffer.py": 4631433251046338381,
+ "venv/lib/python3.13/site-packages/pygments/lexers/__init__.py": 4627540245914849670,
+ "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/METADATA": 3179724236887811680,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssltransport.py": 8148652555908329980,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cosh.csv": 9287774220881887502,
+ "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/parser.py": 1064209424435927674,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/datonly.f90": 10495925225338237742,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/mypy.ini": 4763385838822685881,
+ "frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js": 17821671753127603158,
+ "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.pyi": 3661113433078225952,
+ "venv/lib/python3.13/site-packages/pandas/io/json/_table_schema.py": 3103776773020058805,
+ "venv/lib/python3.13/site-packages/pycparser/ply/yacc.py": 4218889705926129841,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_errstate.py": 10788459171326750780,
+ "venv/lib/python3.13/site-packages/packaging/py.typed": 15130871412783076140,
+ "frontend/src/lib/api/translate.js": 18140498250896378509,
+ "frontend/src/routes/datasets/+page.svelte": 4090458050277453670,
+ "backend/tests/services/clean_release/test_compliance_task_integration.py": 1554378264976811661,
+ "venv/lib/python3.13/site-packages/websockets/utils.py": 17624459810483092475,
+ "backend/src/plugins/translate/preview_constants.py": 12447768695944862994,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/theme.py": 14225878259183479398,
+ "venv/lib/python3.13/site-packages/numpy/random/_sfc64.pyi": 3536657185495782642,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_unary.py": 2573825678342936734,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_formats.py": 9738552308554950419,
+ "venv/lib/python3.13/site-packages/pyasn1/type/opentype.py": 340146737126677655,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_ufunclike.py": 13752381070039804384,
+ "venv/lib/python3.13/site-packages/pandas/_libs/join.pyi": 369262334342439364,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_c_parser_only.py": 3038797485572319804,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/scalars.py": 3468820466230647963,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/http/auto.py": 15947958974558543657,
+ "venv/lib/python3.13/site-packages/pygments/styles/trac.py": 13968346768164381833,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_overlaps.py": 8287716909793575347,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/models.py": 15928924478695638423,
+ "venv/lib/python3.13/site-packages/PIL/ImageTk.py": 17063969714816564357,
+ "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/licenses/LICENSE": 2345070715845618109,
+ "venv/lib/python3.13/site-packages/pygments/lexers/robotframework.py": 11507713622179102496,
+ "venv/lib/python3.13/site-packages/_pytest/fixtures.py": 1442767529726551116,
+ "venv/lib/python3.13/site-packages/jaraco/functools/__init__.py": 15334412919279565528,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/RECORD": 3617343778671172258,
+ "venv/lib/python3.13/site-packages/pygments/styles/vim.py": 2621036947954523349,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/errors.py": 12777931960088171310,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.pyi": 8916922961301555974,
+ "frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js": 10735454478982675155,
+ "venv/lib/python3.13/site-packages/pandas/_libs/window/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/casting.py": 12226803454582253097,
+ "venv/lib/python3.13/site-packages/pillow.libs/liblzma-61b1002e.so.5.8.2": 11405063484938458842,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/apply.py": 3906017176873949738,
+ "frontend/build/_app/immutable/chunks/BtMNxLZr.js": 5550630982455761657,
+ "backend/src/core/__tests__/test_superset_profile_lookup.py": 12374214375171590188,
+ "venv/lib/python3.13/site-packages/numpy/random/mtrand.pyi": 17144590106028661128,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.APACHE": 8359973023624924624,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_util.py": 16908393806993809474,
+ "backend/src/plugins/translate/preview_session_ops.py": 2497494071534748391,
+ "venv/lib/python3.13/site-packages/rsa/core.py": 13203947234024924497,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_validate_call.py": 4078236486720616395,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending_distributions.py": 209769687436320665,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_localize.py": 14495969595744172955,
+ "backend/alembic/versions/f0e9d8c7b6a5_cascade_ondelete_all_env_fks.py": 18274103435952144919,
+ "venv/lib/python3.13/site-packages/PIL/DcxImagePlugin.py": 11767274218348117481,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_toml_compat.py": 10196543528439925412,
+ "venv/lib/python3.13/site-packages/jeepney/tests/secrets_introspect.xml": 10717038359151125278,
+ "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hmac.py": 18132740541139891824,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/request.py": 17642741955458391050,
+ "venv/lib/python3.13/site-packages/ecdsa/ssh.py": 17010933326090778158,
+ "venv/lib/python3.13/site-packages/cffi/lock.py": 13507686939203117974,
+ "venv/lib/python3.13/site-packages/jaraco/classes/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/screen.py": 6933591906297023845,
+ "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.py": 1644743742545329282,
+ "venv/lib/python3.13/site-packages/pandas/core/window/__init__.py": 15180240812077877933,
+ "venv/lib/python3.13/site-packages/PIL/BmpImagePlugin.py": 16682567630621529903,
+ "venv/lib/python3.13/site-packages/pygments/lexers/actionscript.py": 8829560731160428621,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.pyi": 8195943561787777127,
+ "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL": 7127684561765977531,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_replace.py": 18039668944453454689,
+ "venv/lib/python3.13/site-packages/pip/_internal/__init__.py": 7060345458485901709,
+ "venv/lib/python3.13/site-packages/urllib3/http2/__init__.py": 62108352209996836,
+ "venv/lib/python3.13/site-packages/charset_normalizer/md__mypyc.cpython-313-x86_64-linux-gnu.so": 12629680116730190225,
+ "venv/lib/python3.13/site-packages/pygments/lexers/urbi.py": 1611762607688882372,
+ "venv/lib/python3.13/site-packages/websockets/headers.py": 13587146967490088657,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/datasource.pyi": 16752667877866430577,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_is_monotonic.py": 12899848089975919515,
+ "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/WHEEL": 16784970174376303810,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_box_unbox.py": 7579587620530953711,
+ "venv/lib/python3.13/site-packages/_pytest/pytester_assertions.py": 1899505062406979663,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexer.py": 14400766876373764268,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_pandas.py": 10894229569442891394,
+ "frontend/src/lib/components/reports/__tests__/fixtures/reports.fixtures.js": 9590309593907049070,
+ "backend/src/services/clean_release/policy_resolution_service.py": 1025435122296379201,
+ "venv/lib/python3.13/site-packages/pandas/_libs/algos.pyi": 22405377601029952,
+ "venv/bin/py.test": 2593802493707545818,
+ "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/REQUESTED": 15130871412783076140,
+ "frontend/build/_app/immutable/chunks/CuzmfnQu.js": 4320326097426684598,
+ "backend/src/__init__.py": 11250920420388310655,
+ "frontend/build/_app/immutable/chunks/C9YJaesY.js": 17698859127816820470,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_subclass.py": 5540948578269213810,
+ "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.cpython-313-x86_64-linux-gnu.so": 16327106317503267067,
+ "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.py": 11393954913234866059,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth1_session.py": 1911069558956893789,
+ "venv/lib/python3.13/site-packages/cryptography/x509/base.py": 9124948989225782039,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_multilevel.py": 10500316376521962061,
+ "venv/lib/python3.13/site-packages/pygments/formatters/terminal256.py": 11473927781167132440,
+ "venv/lib/python3.13/site-packages/pygments/regexopt.py": 16073437303824961930,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_dtype_like.py": 1598511035344858524,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_arithmetic.py": 13320788210970132239,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/req_install.py": 7181005402818830655,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/mod.pyi": 10591120373577657317,
+ "venv/lib/python3.13/site-packages/numpy/_core/defchararray.pyi": 2277933368373498515,
+ "backend/src/plugins/translate/sql_generator.py": 14497259013250233663,
+ "venv/lib/python3.13/site-packages/click/formatting.py": 6694583529073729642,
+ "backend/src/schemas/validation.py": 17282689016900793292,
+ "venv/lib/python3.13/site-packages/psycopg2/__init__.py": 15798412693009721199,
+ "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/RECORD": 18294169019244826301,
+ "venv/lib/python3.13/site-packages/requests/models.py": 9104898985870652256,
+ "venv/lib/python3.13/site-packages/_pytest/_io/pprint.py": 11202117031437223527,
+ "venv/lib/python3.13/site-packages/passlib/ext/django/utils.py": 8118896525895185626,
+ "backend/src/api/routes/dashboards/_router.py": 8641007051243802224,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_builtin_md4.py": 16840174243259839994,
+ "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.pyi": 5879290708972838025,
+ "venv/lib/python3.13/site-packages/pandas/util/_validators.py": 10201915528715968165,
+ "venv/lib/python3.13/site-packages/ecdsa/test_sha3.py": 12459459298663975730,
+ "venv/lib/python3.13/site-packages/pygments/formatters/pangomarkup.py": 17135620955205945255,
+ "venv/lib/python3.13/site-packages/websockets/legacy/__init__.py": 12332512329533591682,
+ "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.py": 1262543237476191714,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_row.py": 918740441973901148,
+ "venv/lib/python3.13/site-packages/pygments/lexers/teraterm.py": 16132676290138105984,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pyodbc.py": 8175468565413744516,
+ "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/licenses/LICENSE": 1424673738228762254,
+ "venv/lib/python3.13/site-packages/starlette/requests.py": 4582424111350387010,
+ "venv/lib/python3.13/site-packages/attr/converters.py": 5179615793507170642,
+ "venv/lib/python3.13/site-packages/greenlet/TThreadStateDestroy.cpp": 13749797532421836328,
+ "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/METADATA": 3390257212824996989,
+ "venv/lib/python3.13/site-packages/pygments/lexers/pointless.py": 17552020039609007881,
+ "frontend/build/index.html": 5356277431790124133,
+ "backend/src/plugins/translate/_batch_proc.py": 5830558923416766212,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape.pyi": 17197248408326188931,
+ "venv/lib/python3.13/site-packages/pygments/styles/stata_dark.py": 324072437809944751,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_unsupported.py": 9115440166074553860,
+ "venv/lib/python3.13/site-packages/keyring/backends/SecretService.py": 17482492072907438453,
+ "backend/src/services/clean_release/repositories/candidate_repository.py": 1901083195512401226,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_cat_accessor.py": 4304062895283374927,
+ "venv/lib/python3.13/site-packages/_pytest/_py/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/WHEEL": 5160964596297665692,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_formats.py": 3525283725314253763,
+ "frontend/src/lib/components/layout/Breadcrumbs.svelte": 8720668241659707399,
+ "frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js": 7400069550465334990,
+ "venv/lib/python3.13/site-packages/websockets/sync/server.py": 7966978001578584901,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/help.py": 3124654001287175629,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/conftest.py": 16886862391161243448,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_timedeltas.py": 4118671843063545221,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_delete.py": 5958440386632506587,
+ "venv/lib/python3.13/site-packages/fastapi/encoders.py": 1914192268055730299,
+ "venv/lib/python3.13/site-packages/pygments/formatters/terminal.py": 14380579279194052030,
+ "backend/src/api/routes/validation/__tests__/test_validation_api.py": 3854767876193048673,
+ "venv/lib/python3.13/site-packages/pygments/scanner.py": 5640381644804445932,
+ "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js": 18445680453131807754,
+ "venv/lib/python3.13/site-packages/pygments/lexers/iolang.py": 10997512999728724130,
+ "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/METADATA": 11759004913807981650,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.pyi": 3151453262733619734,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_datetime.py": 11417836378782978454,
+ "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_fillna.py": 16297834601116528166,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/json/test_json.py": 12422315190455428620,
+ "venv/lib/python3.13/site-packages/pygments/styles/autumn.py": 8750937312198920971,
+ "venv/lib/python3.13/site-packages/attr/_next_gen.py": 16353246941851015420,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/base_command.py": 10660882478126415399,
+ "backend/src/models/filter_state.py": 9299838116029912439,
+ "backend/tests/test_task_persistence.py": 14626604091774325821,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi": 13016654355866474644,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_indexing.py": 5910217172351020811,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_semicolon_split.py": 8153770165829451525,
+ "venv/lib/python3.13/site-packages/pygments/lexers/resource.py": 8057351545636349791,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/candidate.py": 3099785363867247334,
+ "venv/lib/python3.13/site-packages/greenlet/TBrokenGreenlet.cpp": 10822436772777706192,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/authorization_server.py": 724388765673082720,
+ "venv/lib/python3.13/site-packages/numpy/_pytesttester.py": 17737911110576747508,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_interpolate.py": 7354685880215444946,
+ "backend/tests/services/dataset_review/test_superset_matrix.py": 3788494235626090289,
+ "venv/lib/python3.13/site-packages/PIL/_imagingmath.cpython-313-x86_64-linux-gnu.so": 77725273398858074,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asfreq.py": 2701081989348180239,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_errors.py": 10116716310156374885,
+ "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/LICENSE": 8177430849046795595,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_to_xml.py": 8477770807916990981,
+ "venv/lib/python3.13/site-packages/pandas/util/_tester.py": 1033951890304257539,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/fromnumeric.pyi": 6708743411405679061,
+ "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py": 6509914623926583629,
+ "venv/bin/pyrsa-sign": 15564653706771700451,
+ "venv/lib/python3.13/site-packages/pygments/lexers/shell.py": 3842338968014057744,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/cache.py": 3177663126928467950,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_common.py": 10797243274520625867,
+ "backend/src/plugins/translate/_utils.py": 7134223868160185578,
+ "venv/lib/python3.13/site-packages/starlette/types.py": 6372850128669191435,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_file_handling.py": 732772718210067599,
+ "venv/lib/python3.13/site-packages/referencing/tests/test_exceptions.py": 10846225989746274213,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.pyx": 5760108632332714287,
+ "frontend/src/lib/stores/translationRun.js": 10005138082029605368,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filter.py": 16846063190466267618,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.py": 183817263146423033,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__main__.py": 111505188798650285,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/wrapper.py": 14599195010683170123,
+ "venv/lib/python3.13/site-packages/pygments/style.py": 17393199235575070210,
+ "scripts/generate_financial_arrears_data.py": 15989529185799374517,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/native/decoder.py": 15336592439379775543,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.py": 151202984060101867,
+ "venv/lib/python3.13/site-packages/ecdsa/__init__.py": 6237633580090653788,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_cov_corr.py": 8117511855230249212,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/conftest.py": 11143177766735481660,
+ "backend/src/core/utils/superset_compilation_adapter.py": 13895835815393226662,
+ "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.pyi": 18253950285509265097,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_timedeltaindex.py": 2359681317403710563,
+ "backend/src/plugins/llm_analysis/models.py": 7637744212927477541,
+ "venv/lib/python3.13/site-packages/requests/certs.py": 16052880877156864882,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/METADATA": 9458019064618635438,
+ "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth2_session.py": 7076806577412682835,
+ "venv/bin/pyrsa-priv2pub": 16766314338551408621,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/resolver.py": 2492962412506082234,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/operators.py": 5584982192355398255,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_deprecations.py": 8310244516175542839,
+ "backend/src/core/task_manager/graph.py": 3769962371015813191,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/well_known.py": 7183795183137931709,
+ "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.py": 738588649412338185,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_reductions.py": 8258332365408303156,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/scheme.py": 4101322315594430874,
+ "venv/lib/python3.13/site-packages/rapidfuzz/__init__.py": 12462153783886855740,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.cpython-313-x86_64-linux-gnu.so": 9014806524727977333,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/provision.py": 7362363963464621570,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_swaplevel.py": 3584770792383216626,
+ "frontend/src/services/adminService.js": 5974657342670197690,
+ "backend/alembic/versions/9f8e7d6c5b4a_add_is_multimodal_to_llm_providers.py": 11090205342799426943,
+ "frontend/build/_app/immutable/nodes/28.CFr4yuZi.js": 11507888823107806454,
+ "frontend/build/_app/immutable/chunks/C20922N0.js": 14681700380768364777,
+ "venv/lib/python3.13/site-packages/pandas/_libs/missing.cpython-313-x86_64-linux-gnu.so": 1990755879067132155,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/wheel.py": 828222664427570058,
+ "venv/lib/python3.13/site-packages/pydantic_core/core_schema.py": 8106298745123589494,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/nditer.py": 10038360623032425884,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_lasso_builtins.py": 4006621424665751347,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_replace.py": 4953527309376861139,
+ "backend/tests/scripts/test_clean_release_tui.py": 17813178142456308266,
+ "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/client_mixin.py": 17980753662107479779,
+ "venv/lib/python3.13/site-packages/pyasn1/compat/integer.py": 7365270971777550573,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/information_schema.py": 8551227132710897346,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_inference.py": 5741637509343419942,
+ "venv/lib/python3.13/site-packages/keyring/compat/__init__.py": 7578020229796085753,
+ "venv/lib/python3.13/site-packages/PIL/_version.py": 3025206805667405876,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/base.py": 664515424699746697,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_partial_slicing.py": 15567512240469921599,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_count.py": 16947194157984708529,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_repr.py": 5577699046802107144,
+ "venv/lib/python3.13/site-packages/cffi/ffiplatform.py": 6782148110863549472,
+ "venv/lib/python3.13/site-packages/numpy/_core/_methods.py": 16805668769357938792,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_misc.py": 10202078355301731720,
+ "venv/lib/python3.13/site-packages/gitdb/utils/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/__init__.py": 1948986914452928735,
+ "venv/lib/python3.13/site-packages/pluggy/_manager.py": 18202550145040079612,
+ "frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js": 13812015120538720344,
+ "venv/lib/python3.13/site-packages/fastapi/exceptions.py": 12665775976182239091,
+ "venv/lib/python3.13/site-packages/click/utils.py": 13475604420010022458,
+ "venv/lib/python3.13/site-packages/pydantic/fields.py": 4142211199816898047,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayterator.py": 3076316311545674897,
+ "venv/lib/python3.13/site-packages/_pytest/cacheprovider.py": 5114545353355728201,
+ "venv/lib/python3.13/site-packages/PIL/FpxImagePlugin.py": 18245056799205041866,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/reshaping.py": 18085648077811502689,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/queue.py": 7820997545569991670,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_arrayobject.py": 9578555381494297966,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/bootstrap.py": 3865947239497500815,
+ "frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte": 13452471817010485891,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/scope.py": 4096190764836489091,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/__init__.py": 15130871412783076140,
+ "backend/src/core/migration/archive_parser.py": 16510017196974398795,
+ "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/authorization_server.py": 2491654903543600678,
+ "venv/lib/python3.13/site-packages/pyasn1/type/base.py": 6801504886392649787,
+ "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 12574929384355254457,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/errors.py": 4817746830102488448,
+ "venv/lib/python3.13/site-packages/passlib/handlers/windows.py": 8969739861295277439,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE": 17284252174641192866,
+ "venv/lib/python3.13/site-packages/numpy/char/__init__.pyi": 12214207343146244743,
+ "venv/lib/python3.13/site-packages/git/objects/submodule/base.py": 10140490301897269395,
+ "backend/src/models/dataset_review_pkg/_profile_models.py": 16323179255423210120,
+ "venv/lib/python3.13/site-packages/anyio/streams/file.py": 15232345967545920863,
+ "venv/lib/python3.13/site-packages/fastapi/security/http.py": 8465565118555441408,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-1.csv": 16349400027062875699,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_callback.py": 1689177048527329209,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/_orm_types.py": 5508682532707462217,
+ "venv/lib/python3.13/site-packages/cryptography/x509/ocsp.py": 17973800752927680404,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_holiday.py": 8541197358003711845,
+ "backend/src/plugins/translate/orchestrator_sql_rows.py": 13887342178846174274,
+ "backend/tests/services/clean_release/test_policy_resolution_service.py": 684362936473488668,
+ "backend/tests/test_log_persistence.py": 14027169507280030218,
+ "venv/lib/python3.13/site-packages/pygments/lexers/codeql.py": 4254046699692048717,
+ "venv/lib/python3.13/site-packages/websockets/legacy/handshake.py": 376095144657994920,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunc_config.py": 14728417910466146460,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_strings.py": 7168544888340296373,
+ "venv/lib/python3.13/site-packages/pandas/_libs/writers.cpython-313-x86_64-linux-gnu.so": 6878855127769203372,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/test_from_records.py": 12217508428903265797,
+ "venv/lib/python3.13/site-packages/git/index/util.py": 5022401275553420722,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/typing/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.py": 14446508217220482719,
+ "venv/lib/python3.13/site-packages/numpy/testing/overrides.pyi": 17408923209056015964,
+ "venv/lib/python3.13/site-packages/dotenv/main.py": 7408889670575271484,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py3-objarr.npy": 17303060773267383537,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dot.py": 16876560325283070437,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/__init__.py": 6662687963241471393,
+ "venv/lib/python3.13/site-packages/pygments/lexers/savi.py": 95400050302239274,
+ "backend/git_repos/remote/test-repo.git/objects/aa/ea042a37c6f7bd010d91db93951328da7f01cc": 11936716919619613939,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/syntax.py": 18070449217682341495,
+ "venv/lib/python3.13/site-packages/numpy/tests/test__all__.py": 10689265249302359388,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/timedeltas.py": 13653393430363556843,
+ "venv/lib/python3.13/site-packages/pip/py.typed": 10243553515949422671,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/exclusions.py": 15852672500377116297,
+ "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/METADATA": 3786116428839780263,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/version.py": 5000350193835202949,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odf.py": 15484940480924122966,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_free.f90": 10939657740734987454,
+ "venv/lib/python3.13/site-packages/numpy/_core/memmap.pyi": 14124415711399771715,
+ "venv/lib/python3.13/site-packages/pygments/lexers/freefem.py": 9851243865301700231,
+ "venv/lib/python3.13/site-packages/pandas/core/tools/times.py": 6560679305255812809,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_raises.py": 9678418010293693275,
+ "venv/lib/python3.13/site-packages/fastapi/security/base.py": 15674297568104917749,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_util.py": 13997184496924925110,
+ "venv/lib/python3.13/site-packages/pydantic/functional_serializers.py": 15285359935059345032,
+ "venv/lib/python3.13/site-packages/h11/py.typed": 12358286306858197118,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/np_datetime.pyi": 2884703536776830012,
+ "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/WHEEL": 16097436423493754389,
+ "backend/src/core/database.py": 7373636721634813170,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.py": 15511055314565873928,
+ "backend/src/core/superset_client/_datasets.py": 10922216252382553392,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/auth.py": 6159841209618753296,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_django.py": 8455054295577203929,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_resolution.py": 18198858926948468112,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/_config/display.py": 433650013567734821,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/__init__.py": 4781700006554860887,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_git.py": 8760779092674434712,
+ "venv/lib/python3.13/site-packages/ecdsa/eddsa.py": 15966858338456571506,
+ "venv/lib/python3.13/site-packages/pygments/lexers/cplint.py": 13990118342267278047,
+ "venv/lib/python3.13/site-packages/pandas/_libs/pandas_parser.cpython-313-x86_64-linux-gnu.so": 18056339336364727359,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/identity.py": 326059526167697655,
+ "frontend/src/routes/login/+page.svelte": 2655837067927461296,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_core.py": 6766059152026241747,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/__init__.py": 15991623390785635773,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/index.py": 15694995431926521471,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_indexing.py": 6539365174681852769,
+ "venv/lib/python3.13/site-packages/pandas/_libs/interval.pyi": 15698173755300703836,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/__init__.py": 16434403703599680307,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/jupyter.py": 4446535289156468239,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_encoding.py": 6622474614967398246,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/windows.py": 16452996247375488034,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/req_file.py": 5180401483285462901,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_doc.py": 7865575374100528149,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/markers.py": 5247208668583898949,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_map.py": 32086858815359344,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_npfuncs.py": 6132674295193898715,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/registry.py": 13306388361671753373,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_drop.py": 11341278355685583133,
+ "frontend/src/components/PasswordPrompt.svelte": 2098675312823151283,
+ "backend/src/core/plugin_loader.py": 8193009851819399597,
+ "backend/src/core/superset_client/_charts.py": 15609724925814918066,
+ "venv/lib/python3.13/site-packages/psycopg2/sql.py": 18041240927130590808,
+ "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.h": 5980733638838895780,
+ "venv/lib/python3.13/site-packages/pandas/_config/config.py": 1494288055210911451,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_functions.py": 16376319335326812580,
+ "venv/lib/python3.13/site-packages/pygments/lexers/wgsl.py": 9718384325049172855,
+ "backend/src/services/clean_release/compliance_execution_service.py": 11572933296960110695,
+ "backend/src/api/routes/reports.py": 11259252279199691691,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/unpacking.py": 106471890743211548,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_ndarray.py": 6863874753941288585,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api2.pyx": 15936470837420356071,
+ "venv/lib/python3.13/site-packages/jose/constants.py": 10880650415673457194,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/progress_bars.py": 7584699216537478969,
+ "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpp": 4590574206187223887,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/adapters.py": 2224938661429637508,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_sh_gcc.h": 3574353221233465215,
+ "venv/lib/python3.13/site-packages/numpy/ma/README.rst": 13203411621071845216,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/content": 12465123883296161860,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/string.f": 17328443345813567449,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_internals.py": 10472508540875131797,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex.py": 16348619731902304844,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_misc.py": 16393451200513733144,
+ "venv/lib/python3.13/site-packages/fastapi/_compat/v1.py": 9776181748061371513,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_fillna.py": 13675584998644907265,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_tools.py": 13994164937603424236,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py": 1359143503575245224,
+ "venv/lib/python3.13/site-packages/PIL/ImageMath.py": 7395449734007598797,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.pyf": 1361426175133186231,
+ "venv/lib/python3.13/site-packages/referencing/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_extension.py": 4831602527247293866,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/npyio.pyi": 14147712281086095231,
+ "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.py": 10803011906582324302,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reshape.py": 10576230966727810832,
+ "venv/lib/python3.13/site-packages/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz": 17626265752554406355,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py": 17221368219485351394,
+ "frontend/e2e/fixtures/auth.fixture.js": 13628564118439575126,
+ "venv/lib/python3.13/site-packages/numpy/core/_utils.py": 14108063453670701289,
+ "frontend/src/components/git/GitMergeDialog.svelte": 10276431474456171235,
+ "venv/lib/python3.13/site-packages/attr/validators.py": 4453080662115911998,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/test_blocking.py": 6312017389529916004,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/bitwise_ops.py": 14350609278188982939,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reindex_like.py": 1407890639206728014,
+ "venv/lib/python3.13/site-packages/urllib3/util/ssltransport.py": 1175688460659745788,
+ "backend/test.db": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/_libs/reshape.pyi": 88721900806893992,
+ "backend/git_repos/remote/test-repo.git/objects/71/47ad0836409b35c1650dddf5fa6329ba61a824": 16601919569600972016,
+ "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/RECORD": 14375680579341422646,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py": 6067836157632573182,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_digest.py": 7988469818593853943,
+ "venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py": 9026788710898138090,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/abstract.py": 14216912708889351810,
+ "frontend/src/routes/datasets/review/useReviewSession.js": 2360677870127730232,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_allocator.hpp": 11041111583319491309,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_cocoa_builtins.py": 15468347167912293394,
+ "frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js": 11794595959206318249,
+ "venv/lib/python3.13/site-packages/ecdsa/test_keys.py": 17117188373419689467,
+ "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/METADATA": 6502714564886871819,
+ "venv/lib/python3.13/site-packages/apscheduler/__init__.py": 8652514118183227412,
+ "venv/lib/python3.13/site-packages/starlette/__init__.py": 3252794766897205870,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py": 9623344347519683527,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/matrix.pyi": 15667024840812783911,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlsxwriter.py": 8445547874832015203,
+ "venv/lib/python3.13/site-packages/git/config.py": 1724894144987553201,
+ "venv/lib/python3.13/site-packages/dateutil/parser/_parser.py": 9443336890192151397,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resampler_grouper.py": 8388490036390951341,
+ "backend/src/services/clean_release/__tests__/test_audit_service.py": 10901982516436251314,
+ "backend/git_repos/remote/test-repo.git/hooks/pre-commit.sample": 102291230237676317,
+ "venv/lib/python3.13/site-packages/numpy/_core/__init__.pyi": 2783897020308040960,
+ "venv/lib/python3.13/site-packages/h11/_connection.py": 6971907312737339559,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/evaluator.py": 6348022789899831255,
+ "venv/lib/python3.13/site-packages/jsonschema/_format.py": 8987698648383779883,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/check.py": 6937252393012787214,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_hosts.py": 8284535274820610802,
+ "docker/backend.Dockerfile": 3370913626880503214,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/hooks.py": 9888227370911151341,
+ "venv/lib/python3.13/site-packages/_pytest/stash.py": 14430252294763173610,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_groupby_shift_diff.py": 1210657479716368827,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_index_as_string.py": 292438690259156869,
+ "venv/lib/python3.13/site-packages/pydantic_settings/__init__.py": 4374954204580208673,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/fields.py": 8923326131649837922,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_insert.py": 11635164392966270621,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_xs.py": 11073752361562791165,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_slice.py": 9936085512921529417,
+ "backend/src/api/routes/translate/__init__.py": 6357999798616465776,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arrayprint.py": 5912583751693302370,
+ "venv/lib/python3.13/site-packages/uvicorn/supervisors/multiprocess.py": 10047012560534876149,
+ "venv/bin/normalizer": 10972303485259566838,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_sourcemod_builtins.py": 11809503654078535014,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_add_prefix_suffix.py": 8367793476246001244,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py": 7852235015155694076,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/licenses/LICENSE": 9235234428907927646,
+ "venv/lib/python3.13/site-packages/multipart/multipart.py": 26386459953377432,
+ "venv/lib/python3.13/site-packages/pygments/lexers/business.py": 10410439210806697214,
+ "venv/lib/python3.13/site-packages/gitdb/utils/encoding.py": 1668793658272579497,
+ "venv/lib/python3.13/site-packages/gitdb/base.py": 7927279446353696534,
+ "venv/lib/python3.13/site-packages/starlette/_exception_handler.py": 9892172656847200124,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_mixins.py": 12351373879926460719,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_cisco.py": 1786475632318043669,
+ "venv/lib/python3.13/site-packages/passlib/registry.py": 5050675058011850564,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/azure.py": 13529763490186254462,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/transforms.py": 3773159138960141434,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_get_numeric_data.py": 5896318696417090902,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_show_versions.py": 10577134135855180356,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/html.py": 11849941990375030601,
+ "frontend/src/lib/components/layout/TaskDrawer.svelte": 1108434227611806299,
+ "frontend/build/_app/immutable/nodes/6.AvrfqyFP.js": 13563727048315099924,
+ "venv/lib/python3.13/site-packages/websockets/imports.py": 1995356703044158461,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_set_index.py": 10971093361190283675,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_select.py": 7083040959665006634,
+ "venv/lib/python3.13/site-packages/gitdb/db/git.py": 13552203494737962026,
+ "venv/lib/python3.13/site-packages/pip/_vendor/typing_extensions.py": 10158933506062403688,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/_mapping.py": 13335227913146542481,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_numeric.py": 17391095502314929042,
+ "venv/lib/python3.13/site-packages/pandas/core/util/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_online.py": 11850497659869773510,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/__init__.py": 11283047029180207588,
+ "venv/lib/python3.13/site-packages/fastapi/temp_pydantic_v1_params.py": 9436036880518047720,
+ "venv/lib/python3.13/site-packages/itsdangerous/_json.py": 4872267972688724005,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/list.py": 13035925292530461722,
+ "venv/lib/python3.13/site-packages/passlib/__init__.py": 6987142392711441525,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_add_docstring.py": 14657346268890680694,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pillow.libs/libXau-154567c4.so.6.0.0": 4340972632724893052,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/strings.pyi": 15361498560917514616,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/_jaraco_text.py": 9046755357011730699,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dropna.py": 3168969662216766293,
+ "venv/lib/python3.13/site-packages/pandas/tests/libs/test_join.py": 5982692266872978444,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling.py": 18221459425751198218,
+ "venv/lib/python3.13/site-packages/cryptography/__init__.py": 641702726372647770,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_timezones.py": 4771674179164304731,
+ "venv/lib/python3.13/site-packages/pygments/lexers/wren.py": 6259586056260713984,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_date_range.py": 16128552513324017349,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_antijoin.py": 14435396877404907826,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/base.py": 1980520974511822101,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/legendre.pyi": 2029639875417260268,
+ "venv/lib/python3.13/site-packages/packaging/specifiers.py": 2800449842990194437,
+ "venv/lib/python3.13/site-packages/pygments/lexers/elpi.py": 5736689911777977822,
+ "venv/lib/python3.13/site-packages/numpy/lib/_user_array_impl.py": 13115032674230220791,
+ "venv/lib/python3.13/site-packages/numpy/_core/_multiarray_tests.cpython-313-x86_64-linux-gnu.so": 442168371609469538,
+ "venv/lib/python3.13/site-packages/numpy/_core/_dtype.py": 7796703383405149774,
+ "frontend/src/lib/stores/__tests__/test_sidebar.js": 2607679830387722396,
+ "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/assertion_client.py": 4261295109880943573,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/basic.py": 12723021007042054402,
+ "venv/lib/python3.13/site-packages/websockets/server.py": 16599051743322571790,
+ "venv/lib/python3.13/site-packages/charset_normalizer/version.py": 9948878594498587774,
+ "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/fastapi/applications.py": 4975013401500183420,
+ "venv/lib/python3.13/site-packages/authlib/jose/drafts/__init__.py": 4770885427721822507,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/core": 6622984507059115517,
+ "venv/lib/python3.13/site-packages/pandas/core/methods/selectn.py": 13552176539021625776,
+ "venv/lib/python3.13/site-packages/anyio/functools.py": 4300781896135050327,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rank.py": 5817408252050193538,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop_duplicates.py": 5874427993953991216,
+ "venv/lib/python3.13/site-packages/pygments/lexers/eiffel.py": 8964563077187051946,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_stan_builtins.py": 1961875544235948177,
+ "backend/src/core/utils/dataset_mapper.py": 3978140070131451501,
+ "backend/src/core/middleware/trace.py": 132582224686397900,
+ "backend/src/plugins/translate/orchestrator_query.py": 4760681990145471312,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi": 13850254283540522444,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/decorator.py": 8609500261161560793,
+ "frontend/src/lib/components/DashboardMaintenanceBadge.svelte": 9085495636438661604,
+ "venv/lib/python3.13/site-packages/pandas/core/window/ewm.py": 12143982379243011357,
+ "frontend/build/_app/immutable/chunks/aNI39KyB.js": 1756469162576383723,
+ "backend/src/core/middleware/__init__.py": 13917394130915533209,
+ "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/METADATA": 1862765380818895200,
+ "venv/lib/python3.13/site-packages/pygments/formatters/img.py": 18230180171537565208,
+ "backend/tests/test_api_key_routes.py": 8620555141760963281,
+ "backend/src/schemas/__tests__/test_settings_and_health_schemas.py": 17933166680828315099,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_shape_base.py": 4117141349022217163,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_aggregate.py": 15038915958422670700,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/mapped_collection.py": 11377280960650304531,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/__init__.py": 2436195108273216959,
+ "venv/lib/python3.13/site-packages/PIL/TiffImagePlugin.py": 6845043550424565106,
+ "backend/src/api/routes/dashboards/__init__.py": 14480706693953038818,
+ "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_interval_array_equal.py": 15654625365223535344,
+ "backend/git_repos/remote/test-repo.git/objects/6f/85e20ce3ef98cf07a2f102498b71b9462552c5": 3012017807908986452,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/numpyconfig.h": 13339221870252345205,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isna.py": 18394053826166267096,
+ "venv/lib/python3.13/site-packages/pip/_internal/locations/base.py": 7966628150470073365,
+ "venv/lib/python3.13/site-packages/passlib/totp.py": 14590474309565233318,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_array.py": 12514884344165043136,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/cast.py": 342228968652072052,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_normalize.py": 11373923576259976755,
+ "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/licenses/LICENSE": 1126906383149772681,
+ "venv/lib/python3.13/site-packages/jsonschema/_keywords.py": 949562792260528762,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py": 15644105878811738516,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.pyi": 15114028503984522176,
+ "frontend/build/_app/immutable/chunks/Cn56Obuw.js": 9774722709007984298,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_context.py": 15195609282700801214,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_generic.py": 1098361087956787007,
+ "venv/lib/python3.13/site-packages/smmap/util.py": 13276170835044840023,
+ "venv/lib/python3.13/site-packages/starlette/middleware/errors.py": 1337979724602864440,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/cells.py": 8299309127027168194,
+ "venv/lib/python3.13/site-packages/smmap/test/test_util.py": 5634593621291240094,
+ "venv/lib/python3.13/site-packages/pydantic/v1/mypy.py": 17076910404409672245,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_ewm.py": 12153690217678546798,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/__init__.py": 16123561007855424016,
+ "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.pyi": 17825266810219495672,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__multiarray_api.c": 9134176670140958459,
+ "frontend/src/routes/profile/+page.svelte": 13080303244628934788,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test__exceptions.py": 12099001631178696189,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufuncs.pyi": 1808147181379894521,
+ "frontend/build/_app/immutable/chunks/CrLU7zQO.js": 14265962769345069959,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_cpython_compat.hpp": 8396413256279803400,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_unittests.py": 18157503533859249155,
+ "backend/src/api/routes/maintenance/__init__.py": 8921716690761316245,
+ "venv/lib/python3.13/site-packages/pydantic/color.py": 1007422551673129827,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_integer.py": 16102640589300356639,
+ "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_stat_reductions.py": 11569525436540769152,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/help.py": 4175797322922912326,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_packbits.py": 7592956764084658562,
+ "backend/src/plugins/translate/dictionary_entries.py": 11394786590056973146,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/RECORD": 8104089156015954779,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_formats.py": 1265319125235346745,
+ "backend/alembic/versions/e5f4d3c2b1a_add_policy_id_to_validation_results.py": 11168047633691803786,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_regression.py": 16293647824734937323,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/errors.py": 14634768861119075506,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs12.pyi": 7801211423226951223,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_duplicated.py": 14676058112867601208,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.cpython-313-x86_64-linux-gnu.so": 12776951671822017500,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/connection.py": 15405047955974108860,
+ "backend/src/core/superset_profile_lookup.py": 7466572583388472449,
+ "venv/lib/python3.13/site-packages/rsa/cli.py": 1753949198467694190,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/__init__.py": 6654484356035994666,
+ "frontend/src/routes/storage/+page.svelte": 5003283673039328108,
+ "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE": 16499431172938528491,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayprint.pyi": 2053388407376896377,
+ "venv/lib/python3.13/site-packages/starlette/middleware/gzip.py": 4321371046149637632,
+ "venv/lib/python3.13/site-packages/_pytest/compat.py": 10046464101087327473,
+ "venv/lib/python3.13/site-packages/numpy/_array_api_info.py": 9709101823494959741,
+ "venv/lib/python3.13/site-packages/pandas/_libs/groupby.cpython-313-x86_64-linux-gnu.so": 14931394220112658268,
+ "frontend/playwright-report/trace/assets/codeMirrorModule-Ds_H_9Yq.js": 1369559823166915102,
+ "backend/tests/test_models.py": 14571471179954305607,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_take.py": 14969455660160053080,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_tz_convert.py": 13349243029437881949,
+ "venv/lib/python3.13/site-packages/greenlet/platform/setup_switch_x64_masm.cmd": 8473866644286785815,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unstack.py": 11834917665446437163,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/conftest.py": 1643522609234951699,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_xlsxwriter.py": 16873939324418752965,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/core.py": 2199607970842512780,
+ "venv/lib/python3.13/site-packages/PIL/EpsImagePlugin.py": 1824020964179364491,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh18335.f90": 1126438609189294255,
+ "venv/lib/python3.13/site-packages/pygments/lexers/haxe.py": 1915270891525929751,
+ "venv/lib/python3.13/site-packages/_pytest/_io/__init__.py": 1510478951261938348,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_latex.py": 15077617224435782028,
+ "venv/lib/python3.13/site-packages/charset_normalizer/py.typed": 15130871412783076140,
+ "frontend/src/lib/auth/permissions.js": 7186663483939824478,
+ "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.pyi": 18193727720492050602,
+ "venv/lib/python3.13/site-packages/jose/__init__.py": 15575670403380555945,
"venv/lib/python3.13/site-packages/pygments/lexers/agile.py": 5686162551416231457,
"venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/INSTALLER": 17282701611721059870,
- "frontend/e2e/fixtures/auth.fixture.js": 13628564118439575126,
- "frontend/tests/maintenance-api.test.ts": 10196278218740408254,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_validators.py": 14178329676643700151,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_delete.py": 5958440386632506587,
- "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.pyi": 6546751036506752550,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__main__.py": 11917862648584782420,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/rsa.pyi": 13850254283540522444,
- "venv/lib/python3.13/site-packages/pandas/_libs/missing.pyi": 13543139288840944411,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/groupby.py": 5536922766239875007,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_explode.py": 18263694040596159591,
- "venv/lib/python3.13/site-packages/pygments/lexers/rust.py": 8605690716125176329,
- "frontend/build/_app/immutable/chunks/DV17vNYu.js": 5906252992532056558,
- "backend/src/core/utils/superset_compilation_adapter.py": 13895835815393226662,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/__init__.py": 10920760520224795596,
- "backend/src/api/routes/git/_merge_routes.py": 12751818588668193353,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_encoding.py": 6622474614967398246,
- "frontend/src/lib/utils/debounce.js": 11611676161433422398,
- "backend/src/services/clean_release/__tests__/test_manifest_builder.py": 4923613189073397440,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlrd.py": 9982457234958102003,
- "venv/lib/python3.13/site-packages/websockets/headers.py": 13587146967490088657,
- "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.py": 5564496700647900501,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_join.py": 17874591841487372992,
- "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_time.py": 10463741033950978270,
- "venv/lib/python3.13/site-packages/pygments/lexers/snobol.py": 414946539602526513,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/containers.py": 5969831151685016772,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh17797.f90": 17319074662077763768,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/argon2.py": 15389474901714096890,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api2.pyx": 15936470837420356071,
- "venv/lib/python3.13/site-packages/pandas/core/ops/docstrings.py": 3721650738518391256,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_datetime64.py": 16272266806084058743,
- "frontend/build/index.html": 9441612921158753253,
- "backend/src/core/task_manager/task_logger.py": 6134165406387688582,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_astype.py": 563689238486630866,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dim2.py": 5767600151459095125,
- "venv/lib/python3.13/site-packages/pandas/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arithmetic.py": 14858832264660410908,
- "backend/src/services/dataset_review/repositories/session_repository.py": 4897386456198762089,
- "venv/lib/python3.13/site-packages/pandas/io/excel/__init__.py": 6662687963241471393,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/jwt_bearer.py": 6973859422068490274,
- "venv/lib/python3.13/site-packages/fastapi/routing.py": 466387159689567541,
- "venv/lib/python3.13/site-packages/fastapi/middleware/httpsredirect.py": 5775982317459922443,
- "venv/lib/python3.13/site-packages/secretstorage/collection.py": 17903258621904912493,
- "venv/lib/python3.13/site-packages/dotenv/cli.py": 7952654621986067973,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_einsum.py": 17286384318722237180,
- "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/assertion_client.py": 4261295109880943573,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py": 2285778903282667561,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_nanfunctions.py": 2356468092336024365,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_apply_relabeling.py": 3930092097678339743,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_indexing.py": 3841182456456779012,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_extract.py": 14547819021277949280,
- "backend/src/services/git/_status.py": 13381104725964137243,
- "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_copy_deprecation.py": 16045426957636349035,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/lambdas.py": 13377298868598623228,
- "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.pyi": 12566839271245057531,
- "venv/lib/python3.13/site-packages/urllib3/util/connection.py": 15511685694589961094,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/__init__.py": 11283047029180207588,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pluggy/_tracing.py": 7276210024011809655,
- "venv/lib/python3.13/site-packages/passlib/tests/test_utils_handlers.py": 556092537518149789,
- "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/WHEEL": 7314207500206292683,
- "venv/lib/python3.13/site-packages/pygments/lexers/varnish.py": 3608370156692616959,
- "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/zip-safe": 15240312484046875203,
- "frontend/src/routes/admin/settings/+page.svelte": 9726389419291634649,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/numpy_.py": 16641729409992576358,
- "frontend/src/components/git/GitMergeDialog.svelte": 10276431474456171235,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_repr.py": 7552782621374439569,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/setitem.py": 9552868454186447925,
- "venv/lib/python3.13/site-packages/uvicorn/loops/__init__.py": 15130871412783076140,
- "backend/tests/core/test_defensive_guards.py": 12897956916491464449,
- "venv/lib/python3.13/site-packages/rapidfuzz/process.py": 3870006735299537016,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/utils.py": 3710235316419562274,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_deprecations.py": 6015734648984591027,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_version.py": 15336513445621042105,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi": 13061638961405460334,
- "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arrayterator.py": 1646530870049791291,
- "venv/lib/python3.13/site-packages/pandas/tests/computation/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py": 11425629729736599320,
- "venv/lib/python3.13/site-packages/packaging/_structures.py": 13086687542872305890,
- "venv/lib/python3.13/site-packages/packaging/metadata.py": 9168255069163141470,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraysetops.py": 10588903945244480732,
- "frontend/src/lib/components/reports/reportTypeProfiles.js": 10752964062056890725,
- "backend/git_repos/remote/test-repo.git/refs/heads/feature/e2e-update": 9577764946931187657,
- "backend/src/plugins/translate/orchestrator.py": 6762154654706349158,
- "backend/src/plugins/translate/_utils.py": 7134223868160185578,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/compat.py": 17520043776344667309,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh26681.f90": 1515497186927052106,
- "backend/src/core/task_manager/lifecycle.py": 1696300129247014205,
- "backend/tests/test_storage_config.py": 14773544217703363468,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/response.py": 353446217435156470,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/string_.py": 14865733321317939478,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/comparisons.py": 7327629888601690759,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_week.py": 5756727157937218128,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/mod_derived_types.f90": 2556756676983488922,
- "venv/lib/python3.13/site-packages/pygments/lexers/erlang.py": 11757064262773184741,
- "backend/src/api/routes/assistant/_schemas.py": 4857414465150735071,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_iterrows.py": 3791886201566670087,
- "venv/lib/python3.13/site-packages/attr/setters.py": 12467854389745942025,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/cursor.py": 8074527784886981710,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/__init__.py": 18019562641348687547,
- "venv/lib/python3.13/site-packages/rsa/pkcs1_v2.py": 3533398238491175229,
- "venv/lib/python3.13/site-packages/pygments/console.py": 3540660073442483692,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/token.py": 11655733747403312358,
- "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.pyi": 6723628093359375823,
- "backend/src/core/logger.py": 14032769626660616831,
- "backend/src/plugins/translate/preview_prompt_helpers.py": 14303328860208074708,
- "venv/lib/python3.13/site-packages/urllib3-2.6.2.dist-info/METADATA": 2624107638694809013,
- "backend/src/api/routes/git/_helpers.py": 17217408354237437064,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_cov_corr.py": 8117511855230249212,
- "venv/lib/python3.13/site-packages/fastapi/security/oauth2.py": 1925394177931547776,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_asymmetric.py": 6903778603779934572,
- "venv/lib/python3.13/site-packages/dotenv/ipython.py": 15904966766060247908,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_union_categoricals.py": 6843679254735807,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/__init__.py": 14522970260621605208,
- "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.abi3.so": 8691731321358529264,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape.pyi": 17197248408326188931,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/palette.py": 17383863392192572184,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cbrt.csv": 8929553891827331780,
- "venv/lib/python3.13/site-packages/PIL/ContainerIO.py": 7551929914241379005,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/json.py": 17692639396786690144,
- "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.cpython-313-x86_64-linux-gnu.so": 17856848989827220388,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py": 6712732248328458871,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_like.py": 2778905818573625118,
- "venv/lib/python3.13/site-packages/pyasn1/codec/ber/eoo.py": 5126566925877730303,
- "venv/lib/python3.13/site-packages/pydantic/errors.py": 3506829204186508192,
- "venv/lib/python3.13/site-packages/authlib/common/errors.py": 16082974228565515177,
- "venv/lib/python3.13/site-packages/pip/_internal/network/download.py": 5256731341219268693,
- "venv/lib/python3.13/site-packages/smmap/__init__.py": 4557520096828426601,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending_distributions.py": 209769687436320665,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/array.py": 1919242530821725197,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_style.tpl": 3352086677417301397,
- "venv/lib/python3.13/site-packages/pandas/_testing/asserters.py": 272063856832951430,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/cache.py": 1892313355296776523,
- "venv/lib/python3.13/site-packages/cryptography/__about__.py": 10471312538528457144,
- "venv/lib/python3.13/site-packages/websockets/asyncio/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/git/config.py": 1724894144987553201,
- "venv/lib/python3.13/site-packages/fastapi/middleware/__init__.py": 5289703478893407762,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_indexing.py": 13703573544185051910,
- "venv/lib/python3.13/site-packages/dateutil/easter.py": 14631233890122048084,
- "venv/lib/python3.13/site-packages/pycparser/lextab.py": 16045770806700381661,
- "frontend/e2e/tests/settings.e2e.js": 1420830886812189435,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_api.py": 16743710460729009914,
- "frontend/src/services/taskService.js": 11368052191249479533,
- "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.py": 17192211156810267818,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/writeonly.py": 14213960431308620600,
- "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate.py": 11205714006000849926,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_unique.py": 3989602816674881215,
- "venv/lib/python3.13/site-packages/numpy/random/_mt19937.cpython-313-x86_64-linux-gnu.so": 85866616759631810,
- "backend/src/services/clean_release/stages/internal_sources_only.py": 6150576100887638944,
- "venv/lib/python3.13/site-packages/pandas/io/sas/__init__.py": 8095743504390517992,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/type_api.py": 10299750173867399533,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/panel.py": 17832701246248000383,
- "venv/lib/python3.13/site-packages/uvicorn/middleware/message_logger.py": 14825516604555033580,
- "backend/git_repos/remote/test-repo.git/hooks/pre-commit.sample": 102291230237676317,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_header.py": 3564391095263545879,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/requests.py": 1102963893193914979,
- "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py": 14824388798676578409,
- "venv/lib/python3.13/site-packages/_pytest/terminal.py": 885450969703476729,
- "venv/lib/python3.13/site-packages/referencing/tests/test_retrieval.py": 10782087416909177703,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/__init__.py": 3577295959173028042,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/__init__.py": 14481526616887213120,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename_axis.py": 13193478481758930128,
- "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/METADATA": 14543822270526146783,
- "venv/lib/python3.13/site-packages/numpy/ma/mrecords.py": 687170905107114309,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_tzconversion.py": 7205566353454584259,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_base_indexer.py": 3129123098288498633,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_join.py": 4213933887062089605,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string.py": 3834067244989779682,
- "venv/lib/python3.13/site-packages/passlib/handlers/windows.py": 8969739861295277439,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_sorting.py": 8944017570338511677,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aiosqlite.py": 9888795404090331319,
- "venv/lib/python3.13/site-packages/uvicorn/_types.py": 3339389597716220585,
- "venv/lib/python3.13/site-packages/PIL/report.py": 9428754440615681790,
- "venv/lib/python3.13/site-packages/pygments/lexers/jsx.py": 13855228003748707341,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/pytestplugin.py": 1591034895268415944,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/errors.py": 4817746830102488448,
- "venv/lib/python3.13/site-packages/pygments/lexers/compiled.py": 8215290039991205531,
- "frontend/src/routes/settings/+page.svelte": 13008569925433466788,
- "venv/lib/python3.13/site-packages/pygments/lexers/parsers.py": 12372594608244797844,
- "backend/src/core/scheduler.py": 8479779689131957613,
- "backend/git_repos/remote/test-repo.git/objects/52/ec4a78c629329b8b572ec9d5205271c111baac": 18054296544295201561,
- "venv/lib/python3.13/site-packages/rsa/pem.py": 3118524021576082054,
- "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__main__.py": 8412594868333244844,
- "backend/src/core/task_manager/graph.py": 3769962371015813191,
- "venv/lib/python3.13/site-packages/uvicorn/supervisors/__init__.py": 15971002342788501945,
- "venv/lib/python3.13/site-packages/pyasn1/codec/der/decoder.py": 11876648884087997745,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_export_format.py": 17862222951776199694,
- "venv/lib/python3.13/site-packages/pandas/tests/api/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/PIL/PixarImagePlugin.py": 12061717157676819554,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py": 14571251344510763303,
- "venv/lib/python3.13/site-packages/passlib/tests/tox_support.py": 9200774792427691602,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/cache.py": 3177663126928467950,
- "venv/lib/python3.13/site-packages/numpy/testing/__init__.py": 2831275254313750978,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py": 7301817934902711510,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/fixed_string.f90": 8654788371538544793,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/locators.py": 7638945613579396718,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/status_codes.py": 9143625681947330756,
- "venv/lib/python3.13/site-packages/pip/_vendor/distro/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/rsa/py.typed": 11041940105507257053,
- "venv/lib/python3.13/site-packages/passlib/handlers/md5_crypt.py": 7669328623914474137,
- "venv/lib/python3.13/site-packages/numpy.libs/libquadmath-96973f99-934c22de.so.0.0.0": 5098713761946118139,
- "venv/lib/python3.13/site-packages/pandas/tests/interchange/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_equals.py": 9903250467264848187,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_autocorr.py": 1092316868398391792,
- "venv/lib/python3.13/site-packages/passlib/utils/decor.py": 21351391767102899,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_indexing.py": 14461606056665485421,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_eng_formatting.py": 14768815444701392013,
- "frontend/src/routes/datasets/__tests__/StatsBar.test.js": 16218511958634350787,
- "frontend/build/_app/immutable/nodes/27.DBoSQFdP.js": 3996839526740186087,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel_py.py": 9112851333217812996,
- "venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-0692f733.so.0.61230.0": 23110287346167671,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/bootstrap.py": 3865947239497500815,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/__init__.py": 348469143777130970,
- "venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py": 10408538054406276433,
- "venv/lib/python3.13/site-packages/typing_inspection/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/passlib/handlers/sun_md5_crypt.py": 1949993216707182407,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_arithmetic.py": 16045758521544316139,
- "venv/lib/python3.13/site-packages/numpy/testing/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unique.py": 6234921572794573905,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/result.py": 12262298207886620908,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_index_new.py": 796607958391882182,
- "venv/lib/python3.13/site-packages/pygments/lexers/mips.py": 2078929831513352031,
- "frontend/src/lib/auth/store.ts": 5831215136783173107,
- "frontend/src/lib/api/translate/jobs.js": 9613844538417291513,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_astype.py": 4975959187621745360,
- "backend/src/api/routes/__tests__/test_assistant_authz.py": 3835028453926095879,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_datetime.py": 7862725028865965163,
- "venv/lib/python3.13/site-packages/passlib/handlers/mysql.py": 11165762635383041460,
- "venv/lib/python3.13/site-packages/more_itertools/more.pyi": 4844596605492825806,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_features.py": 955759654189150497,
- "backend/tests/test_api_key_auth.py": 15854247672009604904,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_longtable.tpl": 12723621983797415444,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.cpython-313-x86_64-linux-gnu.so": 6157288238855118017,
- "venv/lib/python3.13/site-packages/click/shell_completion.py": 5858110451169927373,
- "venv/lib/python3.13/site-packages/yaml/__init__.py": 11044333164208875121,
- "frontend/build/_app/immutable/chunks/aniH9ONl.js": 11297774342683903539,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_version.pyi": 3636944488233043883,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/simple.py": 11050636051019777317,
- "frontend/src/routes/dashboards/+page.svelte": 5522148689707175338,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_replace.py": 18039668944453454689,
- "frontend/build/_app/immutable/chunks/C2DipQLT.js": 333538434576244034,
- "venv/lib/python3.13/site-packages/pydantic/networks.py": 15767095796055034509,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/nditer.py": 10038360623032425884,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/array.py": 3517673819082574078,
- "backend/src/api/routes/admin.py": 14496518311272057274,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_count.py": 16947194157984708529,
- "venv/lib/python3.13/site-packages/pandas/io/sas/sas_xport.py": 16525568795475918874,
- "backend/src/core/database.py": 7373636721634813170,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/spinner.py": 5564789578696016201,
- "venv/lib/python3.13/site-packages/pandas/core/tools/timedeltas.py": 7221393731712061943,
- "backend/src/schemas/settings.py": 18238532620797946210,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply_relabeling.py": 5600949862632014700,
- "venv/lib/python3.13/site-packages/numpy/core/_internal.py": 14816989375912210674,
- "venv/lib/python3.13/site-packages/numpy/_core/_simd.cpython-313-x86_64-linux-gnu.so": 12609666221355091416,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_missing.py": 7034102519042351965,
- "venv/lib/python3.13/site-packages/httpcore/_api.py": 16499985295426060327,
- "venv/lib/python3.13/site-packages/requests/cookies.py": 4997226307650350876,
- "venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py": 11981127094916412794,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_refs.hpp": 8525862687669040510,
- "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/LICENSE": 16174281248426886206,
- "venv/lib/python3.13/site-packages/numpy/polynomial/_polytypes.pyi": 7528777458251688517,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssltransport.py": 8148652555908329980,
- "venv/lib/python3.13/site-packages/jose/constants.py": 10880650415673457194,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_mask.py": 5451866071307236899,
- "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe": 15240312484046875203,
- "backend/tests/services/clean_release/test_compliance_task_integration.py": 1554378264976811661,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_ccalendar.py": 8819357623337533489,
- "backend/git_repos/remote/test-repo.git/objects/59/3a37acec7d2bddce10df90ab17bc9ede52e523": 1117161574576783985,
- "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/WHEEL": 16784970174376303810,
- "venv/lib/python3.13/site-packages/fastapi/openapi/constants.py": 1111838716953068285,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_table.tpl": 17198355067645888735,
- "venv/lib/python3.13/site-packages/idna/codec.py": 4260241549062101779,
- "frontend/src/lib/ui/Icon.svelte": 18238812161544525261,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py": 9623344347519683527,
- "venv/lib/python3.13/site-packages/pip/_internal/models/link.py": 7172346414535657925,
- "venv/lib/python3.13/site-packages/passlib/crypto/__init__.py": 16409196868630049365,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_dtypes.py": 2313400030798822026,
- "venv/lib/python3.13/site-packages/anyio/_core/_signals.py": 1204322949639513552,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufuncs.py": 12732599294816239111,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_setops.py": 8622608042929141013,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_astype.py": 11386658862732393123,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_encs.py": 9703572751543253904,
- "venv/lib/python3.13/site-packages/pyasn1/codec/native/decoder.py": 15336592439379775543,
- "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/charset_normalizer/md__mypyc.cpython-313-x86_64-linux-gnu.so": 12629680116730190225,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/size/foo.f90": 18067977329435720684,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/claims.py": 14794441479740527265,
- "venv/lib/python3.13/site-packages/pygments/lexers/r.py": 14263133575134645005,
- "frontend/src/lib/api/translate/schedules.js": 8616345664085016472,
- "frontend/src/routes/reports/llm/[taskId]/+page.svelte": 809594987288256163,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_function.py": 7048185308307653546,
- "venv/lib/python3.13/site-packages/pandas/_libs/sparse.pyi": 12526865400413362140,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/RECORD": 17545477863793260029,
- "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.pyi": 3573629536236108391,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/missing.py": 11241703105777668183,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_astype.py": 4854809596041987380,
- "backend/src/core/__tests__/test_config_manager_compat.py": 16202699597948342431,
- "venv/lib/python3.13/site-packages/jsonschema/_types.py": 9250091433305395923,
- "venv/lib/python3.13/site-packages/fastapi/_compat/main.py": 13016492818231995760,
- "backend/git_repos/remote/test-repo.git/refs/heads/main": 7667767390913789840,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/class_validators.py": 2200511838255373813,
- "venv/lib/python3.13/site-packages/attrs/py.typed": 15130871412783076140,
- "frontend/build/_app/immutable/chunks/KxePT7Ip.js": 8106111085962356816,
- "venv/lib/python3.13/site-packages/numpy/lib/npyio.py": 6782361985454523908,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/constants.pyi": 4415188581374004936,
- "venv/lib/python3.13/site-packages/pandas/core/window/numba_.py": 1444123360986509769,
- "venv/lib/python3.13/site-packages/authlib/oauth1/client.py": 7314311571224771,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_constructors.py": 3440572832185940666,
- "venv/lib/python3.13/site-packages/httpcore/_sync/__init__.py": 7676937747094511752,
- "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/random/_sfc64.pyi": 3536657185495782642,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_kwarg.py": 10417724544218303733,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/base.py": 7855217087916771270,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_pydatetime.py": 1129954411080617001,
- "venv/lib/python3.13/site-packages/pandas/tests/computation/test_compat.py": 11655000938111420543,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_csky_gcc.h": 12929785267195988209,
- "venv/lib/python3.13/site-packages/pygments/sphinxext.py": 2768161754523156130,
- "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/licenses/LICENSE": 17020744174398828059,
- "venv/lib/python3.13/site-packages/pygments/lexers/sgf.py": 6802546617450210439,
- "venv/lib/python3.13/site-packages/starlette/middleware/authentication.py": 15211131264936212938,
- "venv/lib/python3.13/site-packages/click/decorators.py": 2920877667855377423,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/authorization_server.py": 6858244712625056421,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/response.py": 15004896908941411698,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data": 9599129816090399315,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/nested_secrets.py": 15691917061715429369,
- "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_overlaps.py": 8287716909793575347,
- "venv/lib/python3.13/site-packages/pandas/arrays/__init__.py": 10005095663840461954,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/characteristics.py": 2916810597149066609,
- "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/WHEEL": 8600534672961461758,
- "venv/lib/python3.13/site-packages/uvicorn/loops/auto.py": 13086005977087619545,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/constructors.py": 7587476800569414769,
- "venv/lib/python3.13/site-packages/pygments/lexers/functional.py": 15896849233007178031,
- "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.pyi": 18253950285509265097,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ndarray_misc.pyi": 16219573290116396099,
- "backend/src/api/routes/translate/_job_routes.py": 10128664562563592050,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/shape.py": 13410030168622484801,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_equals.py": 9405821443172167066,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_arithmetic.py": 976970179757115407,
- "venv/lib/python3.13/site-packages/pandas/_testing/__init__.py": 10127496080404419481,
- "venv/lib/python3.13/site-packages/ecdsa/__init__.py": 6237633580090653788,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_index_tricks.py": 4676293127859087991,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_matmul.py": 16169282225324014901,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_pipe.py": 8255917221095334212,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_size.py": 14032390806503440750,
- "frontend/src/services/gitService.js": 15727247604802461729,
- "venv/lib/python3.13/site-packages/pip/_internal/models/scheme.py": 4101322315594430874,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resample_api.py": 3278209206670699265,
- "venv/lib/python3.13/site-packages/anyio/functools.py": 4300781896135050327,
- "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_byteswap.py": 5090287710338893350,
- "venv/lib/python3.13/site-packages/PIL/_imagingmath.pyi": 18222325750818585549,
- "frontend/src/routes/+error.svelte": 9437886843842311915,
- "venv/lib/python3.13/site-packages/jsonschema/cli.py": 9813914882090789748,
- "venv/lib/python3.13/site-packages/PIL/ImageMode.py": 2361901066832921091,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_common.h": 14732581790650403546,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi": 9835891299056543360,
- "venv/lib/python3.13/site-packages/httpx/__init__.py": 6383055693166097719,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows.py": 13341168721223961872,
- "venv/lib/python3.13/site-packages/numpy/strings/__init__.pyi": 6213864891045042045,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/_jaraco_text.py": 9046755357011730699,
- "venv/lib/python3.13/site-packages/urllib3/util/util.py": 12490259045660543460,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_reductions.py": 3575617237516305456,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix_py.py": 6653895521961110080,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.py": 15511055314565873928,
- "venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py": 18250473733460571816,
- "dist/docker/backend.0.1.1.tar.xz": 932529191402352855,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_formats.py": 13500155167624433622,
- "backend/src/plugins/storage/plugin.py": 8516872254456553013,
- "venv/lib/python3.13/site-packages/starlette/websockets.py": 13834731343216764204,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/build_tracker.py": 9389444024234384408,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/interval.py": 16281221279220043867,
- "venv/lib/python3.13/site-packages/pandas/core/arraylike.py": 11439602957100017713,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/wait.py": 6196757964348666082,
- "venv/lib/python3.13/site-packages/pandas/conftest.py": 747626550806435763,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/__init__.py": 3673322722277252961,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_floats.py": 3064615530495290792,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/resource_protector.py": 3563910821279222695,
- "backend/src/api/routes/translate/_metrics_routes.py": 14203374652620439805,
- "frontend/src/lib/stores/maintenance.svelte.js": 17672315346665850067,
- "venv/lib/python3.13/site-packages/pillow.libs/libxcb-64009ff3.so.1.1.0": 7322566017497612912,
- "venv/lib/python3.13/site-packages/packaging/_elffile.py": 9546225990833172494,
- "backend/src/services/git/__init__.py": 18353922816391181902,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_api.py": 7131036004750554905,
- "venv/lib/python3.13/site-packages/apscheduler/executors/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/grouper.py": 18110568057754450953,
- "backend/src/api/routes/__tests__/test_git_api.py": 4133163122739824202,
- "frontend/src/lib/components/reports/__tests__/report_card.ux.test.js": 10328656559485751380,
- "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE": 14610443802372107702,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/_log.py": 13011536737418204268,
- "backend/src/plugins/translate/__tests__/test_lang_detect.py": 2328877106785068272,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/conftest.py": 2643915042664055969,
- "venv/lib/python3.13/site-packages/numpy/exceptions.py": 10981418339663118022,
- "venv/lib/python3.13/site-packages/websockets/frames.py": 4901850477414613953,
- "venv/lib/python3.13/site-packages/dotenv/__init__.py": 15464030923609356017,
- "venv/lib/python3.13/site-packages/pydantic/v1/errors.py": 11245135449608452720,
- "backend/src/services/clean_release/repositories/artifact_repository.py": 7507938934134519998,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/unistring.py": 18037463865539157041,
- "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/REQUESTED": 15130871412783076140,
- "backend/git_repos/remote/test-repo.git/objects/ee/59553241ef084b83d3351ba4c33caf2ed9a840": 11587106407031972706,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_replace.py": 15992095120302643273,
- "frontend/src/lib/stores/__tests__/mocks/navigation.js": 16028014574825445651,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/random.py": 12722750410117529986,
- "backend/src/services/__tests__/test_llm_plugin_persistence.py": 17921598588767566887,
- "venv/lib/python3.13/site-packages/httpcore/_backends/trio.py": 8394426709857317737,
- "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_take.py": 1216902953519121176,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_str.py": 149688376805129532,
- "venv/lib/python3.13/site-packages/PIL/PsdImagePlugin.py": 4347581352716313298,
- "backend/src/services/clean_release/stages/base.py": 14966559035592717091,
- "venv/lib/python3.13/site-packages/jose/backends/_asn1.py": 14123487576864105793,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_duplicate_labels.py": 10663105616336167414,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_overlap.py": 4202716587079637350,
- "venv/lib/python3.13/site-packages/PIL/XpmImagePlugin.py": 6644626557482464312,
- "venv/lib/python3.13/site-packages/PIL/_imaging.cpython-313-x86_64-linux-gnu.so": 1425926264271197601,
- "frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte": 16168905765241471813,
- "venv/lib/python3.13/site-packages/rapidfuzz/utils.pyi": 7400725037332728015,
- "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/METADATA": 7788873460115135563,
- "venv/lib/python3.13/site-packages/numpy/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_expanding.py": 9047466276603454007,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_logical.py": 6818185860296232476,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/_orm_types.py": 5508682532707462217,
- "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/__init__.py": 3619091571279924576,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_fillna.py": 7244491410004453166,
- "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL": 5179340427739743287,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test__exceptions.py": 12099001631178696189,
- "venv/lib/python3.13/site-packages/numpy/_typing/_dtype_like.py": 1598511035344858524,
- "frontend/src/routes/datasets/DatasetPreview.svelte": 4250995999947659034,
- "frontend/src/components/git/GitInitPanel.svelte": 515428146955886062,
- "backend/src/core/task_manager/__init__.py": 15991802770215124472,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.pyx": 649821942746469002,
- "venv/lib/python3.13/site-packages/pytest_asyncio/plugin.py": 13414541723622354359,
- "venv/lib/python3.13/site-packages/apscheduler/util.py": 11440701924954413440,
- "venv/lib/python3.13/site-packages/starlette/templating.py": 9242638124487797988,
- "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.pyi": 9243829615414967057,
- "venv/lib/python3.13/site-packages/numpy/_typing/_array_like.py": 2161873439361281488,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/database.py": 7111764828004587758,
- "venv/lib/python3.13/site-packages/pytest/__init__.py": 6137272437722350673,
- "frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte": 13212946590809283743,
- "frontend/src/routes/git/+page.svelte": 3351712750068549963,
- "venv/lib/python3.13/site-packages/numpy/doc/ufuncs.py": 11706048944901534664,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_shift.py": 14681514853406253657,
- "venv/lib/python3.13/site-packages/pillow.libs/libtiff-295fd75c.so.6.2.0": 17866578820357536656,
- "venv/lib/python3.13/site-packages/pandas/_testing/_warnings.py": 5640964566228306285,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg8000.py": 6580512354643849828,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.py": 13853220736499979380,
- "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.pyi": 5269136485429780038,
- "venv/lib/python3.13/site-packages/pydantic/v1/main.py": 213087273729911492,
- "venv/lib/python3.13/site-packages/rapidfuzz/utils_cpp.cpython-313-x86_64-linux-gnu.so": 16145829319198889672,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.pyi": 751490187478960891,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkeyutils-dfe70bd6.so.1.5": 9414227432578104677,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_duplicates.py": 9830936017197354309,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_partial.py": 15129217814262096441,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_categorical.py": 10863578845754547294,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/proxy.py": 13008557041076030198,
- "venv/lib/python3.13/site-packages/pandas/tests/io/generate_legacy_storage_files.py": 11015954144633661960,
- "venv/lib/python3.13/site-packages/passlib/tests/_test_bad_register.py": 5446848310854472376,
- "venv/lib/python3.13/site-packages/pandas/_libs/json.pyi": 10989301892466547548,
- "venv/lib/python3.13/site-packages/psycopg2/extensions.py": 14197445323992851566,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_astype.py": 8505605634958454768,
- "venv/lib/python3.13/site-packages/pandas/_libs/algos.cpython-313-x86_64-linux-gnu.so": 15706331654215762588,
- "venv/lib/python3.13/site-packages/PIL/PngImagePlugin.py": 5076219228736706283,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_msvc_compat.hpp": 12504008513945919250,
- "frontend/build/_app/immutable/nodes/28.MJ5rlU4U.js": 14941281040668339074,
- "venv/lib/python3.13/site-packages/numpy/lib/mixins.py": 7404729635424818497,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_npfuncs.py": 13987318550267921389,
- "venv/lib/python3.13/site-packages/_pytest/deprecated.py": 5452408732344157294,
- "venv/lib/python3.13/site-packages/pygments/lexers/boa.py": 14409319610243925864,
- "venv/lib/python3.13/site-packages/pygments/lexers/prql.py": 1159462562014166646,
- "venv/lib/python3.13/site-packages/pandas/core/computation/eval.py": 3176226283265954028,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/controller.py": 5450931608244830335,
- "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/packaging/_manylinux.py": 8268418900652790584,
- "frontend/src/routes/datasets/review/review-workspace-helpers.js": 8577563379877694502,
- "venv/lib/python3.13/site-packages/pydantic/generics.py": 15019381413806459410,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/linalg.pyi": 269481015135399748,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/authorization_server.py": 4427151727224472650,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_halfyear.py": 9376272342364384767,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_tools.py": 13994164937603424236,
- "venv/lib/python3.13/site-packages/keyring/testing/util.py": 11195868112805409554,
- "venv/lib/python3.13/site-packages/websockets/typing.py": 13268801935274185287,
- "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_spec_conformance.py": 16448324304809345527,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/io.py": 11072022722163954973,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_frequencies.py": 14039315221824123200,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_subclass.py": 13490541871827928531,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_cumulative.py": 8178093067175155877,
- "frontend/src/lib/components/StartMaintenanceForm.svelte": 11114259982483681666,
- "frontend/build/_app/immutable/nodes/15.D77w-oKN.js": 12254106526344958795,
- "backend/src/schemas/dataset_review_pkg/_dtos.py": 10114042767789130927,
- "backend/tests/test_maintenance_api.py": 2012388734813578069,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/nested_schemas.py": 4114645644496880787,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.pyi": 4432290176776357346,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/__init__.py": 3015263524218708013,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/subprocess.py": 3095012838116670328,
- "venv/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py": 7733356903092860495,
- "venv/lib/python3.13/site-packages/numpy/random/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_partial_slicing.py": 15567512240469921599,
- "venv/lib/python3.13/site-packages/_pytest/mark/__init__.py": 9343015549300275714,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_select.py": 7083040959665006634,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dropna.py": 17272771246760486947,
- "venv/lib/python3.13/site-packages/numpy/core/umath.py": 4476812261188108155,
- "venv/lib/python3.13/site-packages/sqlalchemy/pool/events.py": 13473858896579666058,
- "backend/src/api/routes/dataset_review_pkg/_routes.py": 11040245149296528009,
- "venv/lib/python3.13/site-packages/_pytest/cacheprovider.py": 5114545353355728201,
- "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.py": 16539612003028676816,
- "venv/lib/python3.13/site-packages/PIL/SpiderImagePlugin.py": 12234762087257163606,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_period.py": 12593777226419608212,
- "backend/tests/test_dashboards_api.py": 15709552949816760924,
- "venv/lib/python3.13/site-packages/pygments/lexers/sieve.py": 15757825442941567629,
- "frontend/build/_app/immutable/chunks/sEGDVeoa.js": 9540107777971680079,
- "backend/git_repos/remote/test-repo.git/objects/6f/85e20ce3ef98cf07a2f102498b71b9462552c5": 3012017807908986452,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90": 15768643271492041853,
- "backend/src/models/dashboard.py": 18145369015035676491,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_compare.py": 171535659467902751,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_select.py": 17823338162428379468,
- "venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0": 13947441788826399574,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_palettes.py": 13495896173068490516,
- "venv/lib/python3.13/site-packages/pluggy/_warnings.py": 2664977718908223842,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_setops.py": 5208912445718807372,
- "venv/lib/python3.13/site-packages/PIL/PcfFontFile.py": 8867692961463798279,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_intervalindex.py": 5053113227747333759,
- "venv/lib/python3.13/site-packages/PIL/MspImagePlugin.py": 3034490726971829439,
- "venv/lib/python3.13/site-packages/pandas/_libs/groupby.cpython-313-x86_64-linux-gnu.so": 14931394220112658268,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_constructors.py": 6727209833819502644,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_setops.py": 13440916133402971190,
- "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/wgsl.py": 9718384325049172855,
- "venv/lib/python3.13/site-packages/jose/backends/base.py": 12795468809472351388,
- "venv/lib/python3.13/site-packages/numpy/_core/_methods.pyi": 9155045948490225716,
- "frontend/playwright-report/trace/snapshot.html": 11716473056415565262,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/authorization_server.py": 2491654903543600678,
- "venv/lib/python3.13/site-packages/pandas/compat/numpy/__init__.py": 1037113402100731082,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py": 5068814626384132900,
- "frontend/e2e/tests/translation.e2e.js": 12144904254817067746,
- "backend/src/api/routes/assistant/_command_parser.py": 4551109710541212154,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_liboffsets.py": 14705822637347212540,
- "backend/src/plugins/translate/__tests__/test_dictionary_import.py": 17094877730934121606,
- "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/licenses/LICENSE": 6653202620765194772,
- "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/licenses/LICENSE": 3868190977070717994,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/_cmd.py": 14954780419054588164,
- "backend/src/plugins/translate/orchestrator_exec.py": 965301343860940811,
- "venv/lib/python3.13/site-packages/pip/_internal/network/auth.py": 6159841209618753296,
- "venv/lib/python3.13/site-packages/pydantic/color.py": 1007422551673129827,
- "venv/lib/python3.13/site-packages/itsdangerous/timed.py": 12571102606719555007,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_format.py": 5231304674283854194,
- "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA": 16700674024421191168,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numeric.pyi": 17005748821769179511,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nested_sequence.pyi": 10985533017688918283,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_policy.py": 13856626567322091253,
- "backend/src/core/superset_client/_dashboards_filters.py": 17625905985676889586,
- "backend/src/dependencies.py": 13564949183453082453,
- "backend/alembic/versions/b1c2d3e4f5a6_add_source_hash_to_translation_records.py": 4775534557742900399,
- "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/passlib/handlers/mssql.py": 2800599582708170195,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arithmetic.py": 17043958604607035425,
- "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE": 4123064337800029995,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_size.py": 16658280641516916790,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_api.py": 10514120091521589282,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_indexing.py": 4334578480714520407,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_libfrequencies.py": 16302676625743291594,
- "frontend/src/lib/stores/__tests__/setupTests.js": 16228706107748081093,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_internal_dataclass.py": 13206778611516171760,
- "venv/lib/python3.13/site-packages/uvicorn/_subprocess.py": 13965754246493254447,
- "frontend/src/routes/migration/__tests__/migration_dashboard.ux.test.js": 17118608261683412409,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/boolean.py": 8821671562937866269,
- "venv/lib/python3.13/site-packages/starlette/status.py": 16192064443996706569,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_quantile.py": 11966156706220948315,
- "venv/lib/python3.13/site-packages/smmap/test/lib.py": 2924931247676024085,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_rowcount.py": 6682800584070485197,
- "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.py": 4154852745131464543,
- "venv/lib/python3.13/site-packages/_pytest/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_date_range.py": 16128552513324017349,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_sparse.py": 14343335524508450058,
- "venv/lib/python3.13/site-packages/pygments/styles/perldoc.py": 4857683935715743356,
- "venv/lib/python3.13/site-packages/pygments/lexers/berry.py": 4540479522141160472,
- "frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js": 17228280298558782730,
- "venv/lib/python3.13/site-packages/pandas/_typing.py": 17795648994662434211,
- "venv/lib/python3.13/site-packages/pyasn1/type/base.py": 6801504886392649787,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5support-d0bcff84.so.0.1": 16819924515291719993,
- "frontend/build/_app/immutable/nodes/35.BdI-3vAH.js": 15152994709151408688,
- "backend/src/core/utils/superset_context_extractor/_parsing.py": 18406152325228380468,
- "backend/src/plugins/translate/__tests__/test_target_schema.py": 2950009660172053425,
- "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/LICENSE": 4672913476475760762,
- "backend/tests/test_security_audit_fixes.py": 10329229098676202553,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iloc.py": 7586049606891014270,
- "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpp": 4590574206187223887,
- "venv/lib/python3.13/site-packages/pandas/core/window/common.py": 17956497339875932377,
- "backend/tests/test_translate_scheduler_guard.py": 13396608843530344156,
- "venv/lib/python3.13/site-packages/numpy/polynomial/laguerre.py": 151202984060101867,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_join.py": 1364886077926604427,
- "backend/ss_tools_backend.egg-info/PKG-INFO": 15134841326777953914,
- "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_rolling.py": 11118160360072677569,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py": 8530403239168529668,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reserved_words.py": 8022121780993497971,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/download.py": 7533669665002975823,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_toml_compat.py": 10196543528439925412,
- "venv/lib/python3.13/site-packages/pip/_vendor/idna/package_data.py": 3078502124870585867,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fromnumeric.pyi": 8671744104085911610,
- "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/attrs/exceptions.py": 2871247302586505373,
- "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/oauth2_session.py": 7076806577412682835,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/appdirs.py": 539688259643447487,
- "venv/lib/python3.13/site-packages/passlib/win32.py": 5311393450489898748,
- "venv/lib/python3.13/site-packages/pygments/lexers/c_like.py": 13004061780700827047,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/_dml_constructors.py": 4497038002189188311,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90": 6219951399575860362,
- "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/random/_pickle.pyi": 16081120364372391381,
- "venv/lib/python3.13/site-packages/numpy/polynomial/_polybase.py": 893743087939984792,
- "venv/lib/python3.13/site-packages/git/refs/reference.py": 2038789918710608481,
- "frontend/build/_app/immutable/chunks/gRGygy_f.js": 17282722948808474320,
- "backend/src/plugins/translate/orchestrator_run_completion.py": 1246106720048798445,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/mean_.py": 3641008929910474457,
- "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling.py": 18221459425751198218,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py": 15060063324909302240,
- "backend/src/plugins/translate/_llm_parse.py": 3278211416813203155,
- "venv/lib/python3.13/site-packages/numpy/core/arrayprint.py": 9652368112174245943,
- "venv/lib/python3.13/site-packages/numpy/dtypes.py": 14128421398870718692,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/__init__.py": 15991623390785635773,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_format.py": 1947585389944838076,
- "venv/lib/python3.13/site-packages/pygments/lexers/business.py": 10410439210806697214,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/logging.py": 9639351759822608724,
- "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.pyi": 10487441680587530350,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/discovery.py": 12479996594187326798,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/gcp.py": 12328409672947966867,
- "venv/lib/python3.13/site-packages/starlette/background.py": 10232175205397808417,
- "venv/lib/python3.13/site-packages/passlib/tests/test_totp.py": 9150389741890748343,
- "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/RECORD": 16874983218652404911,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/base_key.py": 10402800587070352851,
- "docker/all-in-one.Dockerfile": 10896793266219904099,
- "venv/lib/python3.13/site-packages/keyring/cli.py": 10996746519742056101,
- "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/WHEEL": 18203500019759199992,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/events.py": 7576713358952064464,
- "frontend/src/routes/tools/backups/+page.svelte": 5118871149725970953,
- "frontend/build/_app/immutable/chunks/BEgtrFG1.js": 8322179021947182552,
- "venv/lib/python3.13/site-packages/attr/_version_info.py": 3850449653182103457,
- "venv/lib/python3.13/site-packages/passlib/tests/sample1c.cfg": 13088198405762342506,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_ios.h": 6751259472945638998,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/test_decimal.py": 17811784255174057561,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_masked.py": 5380551301916549925,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/_spdx.py": 17182188548503720124,
- "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_contains.py": 17630310725250553247,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pct_change.py": 10313980265441433173,
- "backend/src/core/timezone.py": 15725829269123183582,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_object.py": 9215781825358309147,
- "venv/lib/python3.13/site-packages/pygments/lexers/automation.py": 8021926838024836904,
- "backend/git_repos/remote/test-repo.git/hooks/pre-merge-commit.sample": 10013699873067956556,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/histograms.pyi": 9255620158831643201,
- "venv/lib/python3.13/site-packages/pandas/io/formats/info.py": 215303194287834907,
- "backend/src/services/resource_service.py": 12557244514401781887,
- "backend/src/services/security_badge_service.py": 4068632889328254896,
- "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_interval.py": 14749388246573356959,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/hooks.py": 9888227370911151341,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_complex.py": 12963449957363121481,
- "venv/lib/python3.13/site-packages/pygments/lexers/roboconf.py": 1335271183806115470,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_common.f": 5913807803369559749,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/expression.py": 15511250785671695359,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_deprecations.py": 8310244516175542839,
- "venv/lib/python3.13/site-packages/numpy/typing/__init__.pyi": 10058149460938883683,
- "backend/src/plugins/translate/__tests__/test_dictionary_utils.py": 2587603845397371763,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename_axis.py": 12432900682994622455,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_indexing.py": 16291207621268530224,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hiworld.f90": 6321872653169140461,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/rsa_key.py": 7092106298733667895,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/bar.py": 12859947592168238832,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli/py.typed": 9796674040111366709,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarprint.py": 9482100952562512933,
- "venv/lib/python3.13/site-packages/pandas/core/sparse/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/_pytest/helpconfig.py": 3033477806668470951,
- "venv/lib/python3.13/site-packages/pandas/tests/io/xml/conftest.py": 17514079438846557943,
- "venv/lib/python3.13/site-packages/websockets/uri.py": 264376168984862773,
- "venv/lib/python3.13/site-packages/uvicorn/importer.py": 5449629250971153435,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_clearing_run_switches.py": 3020294789560975101,
- "venv/lib/python3.13/site-packages/uvicorn/lifespan/on.py": 2866195356090164296,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/revocation.py": 16178499278312777474,
- "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/RECORD": 2688648742701423549,
- "venv/lib/python3.13/site-packages/pandas/testing.py": 18352975429944961593,
- "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/test_rapidfuzz_packaging.py": 5189055608193366093,
- "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.pyi": 17528421279543420867,
- "backend/src/models/dataset_review_pkg/_session_models.py": 9902104970008253748,
- "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js": 18445680453131807754,
- "venv/lib/python3.13/site-packages/pygments/lexers/carbon.py": 6753624244809529841,
- "venv/lib/python3.13/site-packages/jaraco/functools/__init__.pyi": 2872039192528394677,
- "venv/lib/python3.13/site-packages/keyring/util/platform_.py": 16978095707950463638,
- "frontend/src/routes/storage/+page.svelte": 5003283673039328108,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py": 7019253290755243568,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_internal/req/req_dependency_group.py": 10505346210114745037,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_validate.py": 12789481642730855139,
- "venv/lib/python3.13/site-packages/PIL/PaletteFile.py": 4104323659569809769,
- "venv/lib/python3.13/site-packages/urllib3/connection.py": 12761371748350595804,
- "venv/lib/python3.13/site-packages/pygments/lexers/thingsdb.py": 6073447481627395832,
- "frontend/src/routes/+layout.svelte": 729110825767878269,
- "backend/alembic/versions/a7b1c2d3e4f5_add_provider_id_to_validation_policies.py": 7446022200459040057,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/adapters.py": 2224938661429637508,
- "venv/lib/python3.13/site-packages/pydantic/error_wrappers.py": 11273827025986230629,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_getitem.py": 8414677531950073373,
- "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/PIL/BmpImagePlugin.py": 16682567630621529903,
- "venv/lib/python3.13/site-packages/charset_normalizer/__init__.py": 12412600648990392633,
- "frontend/build/_app/immutable/chunks/Cs7qTEqk.js": 15866070137921022262,
- "backend/src/scripts/delete_running_tasks.py": 4209804708500252012,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/char.pyi": 13143560686049627445,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_observance.py": 18178414966262524534,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_subclass.py": 16342917051908786497,
- "venv/lib/python3.13/site-packages/rapidfuzz/utils_py.py": 12341806772632276946,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/util.py": 3591114320020964752,
- "venv/lib/python3.13/site-packages/numpy/testing/tests/test_utils.py": 5291132432383518704,
- "venv/lib/python3.13/site-packages/PIL/GifImagePlugin.py": 16073125611077200693,
- "backend/src/core/task_manager/persistence.py": 9599258324212845325,
- "venv/lib/python3.13/site-packages/numpy/ma/LICENSE": 6723325434476453127,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_upcast.py": 6496794053681247105,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_period.py": 3419297908709788013,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_is_monotonic.py": 12899848089975919515,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_reductions.py": 3227705565578016389,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_reductions.py": 14432782234851468060,
- "frontend/src/routes/validation/history/+page.svelte": 3920288174017004134,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_integrity.py": 12010564145080323987,
- "venv/lib/python3.13/site-packages/idna-3.11.dist-info/METADATA": 14036738037171597049,
- "venv/lib/python3.13/site-packages/pygments/lexers/openscad.py": 13045825115225232396,
- "venv/lib/python3.13/site-packages/PIL/IcnsImagePlugin.py": 1870235606309784691,
- "backend/src/core/superset_client/_dashboards_list.py": 18014687561732553425,
- "venv/lib/python3.13/site-packages/pygments/lexers/_scheme_builtins.py": 5722444920479775453,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_size.py": 8527839563560550806,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/common.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/nattype.cpython-313-x86_64-linux-gnu.so": 2311012065007769341,
- "venv/lib/python3.13/site-packages/psycopg2/tz.py": 9966680685796585198,
- "venv/lib/python3.13/site-packages/gitdb/test/test_stream.py": 18159319442241857857,
- "venv/lib/python3.13/site-packages/jeepney/io/trio.py": 11859775321483330469,
- "venv/lib/python3.13/site-packages/passlib/tests/test_hosts.py": 8284535274820610802,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_cumulative.py": 11752712818547022872,
- "venv/lib/python3.13/site-packages/pip/_vendor/certifi/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/io/sql.py": 12592024569011796790,
- "venv/lib/python3.13/site-packages/urllib3/util/ssl_match_hostname.py": 7411350247004265632,
- "venv/lib/python3.13/site-packages/pygments/lexers/fantom.py": 1986459352773446836,
- "frontend/src/lib/stores/__tests__/test_activity.js": 13851679930048900037,
- "backend/src/models/dataset_review_pkg/_profile_models.py": 16323179255423210120,
- "venv/bin/jsonschema": 16516374846693491442,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_inference.py": 5741637509343419942,
- "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/licenses/AUTHORS": 2987771679926243782,
- "venv/lib/python3.13/site-packages/pycparser/c_parser.py": 3954138286651284327,
- "venv/lib/python3.13/site-packages/cffi/parse_c_type.h": 9889309594462820068,
- "venv/lib/python3.13/site-packages/fastapi/security/utils.py": 2616633862993539558,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.py": 1341849861184131135,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_riscv_unix.h": 8607317131295864391,
- "venv/lib/python3.13/site-packages/pip/_internal/req/req_file.py": 5180401483285462901,
- "venv/lib/python3.13/site-packages/passlib/handlers/sha2_crypt.py": 8171587560325812664,
- "venv/lib/python3.13/site-packages/pandas/tests/config/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/future/__init__.py": 17688444679736059779,
- "frontend/static/favicon.png": 16740551781088792605,
- "frontend/src/lib/api/__tests__/reports_api.test.js": 4759560641984508050,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_join.py": 2585969863606902743,
- "frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js": 15166117912533507471,
- "backend/src/schemas/validation.py": 17282689016900793292,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/exceptions.py": 14982764273485726199,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/implicit.py": 5400555157488808948,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_na_values.py": 13527837495439739279,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_produces_warning.py": 750781117570375777,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/__init__.py": 13841777369501476946,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/declarative_asn1.pyi": 16934250836612138541,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_typst.py": 14619529283550788275,
- "venv/lib/python3.13/site-packages/iniconfig/_parse.py": 11418441008427032090,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo90.f90": 12508663906609241323,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.APACHE": 11041304845352917971,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_replace.py": 8165088653532047247,
- "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/WHEEL": 13232065379159720345,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/interface.py": 3134071530627935964,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/tool_support.py": 4926732415520779988,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/serialize.py": 11139432164346742421,
- "venv/lib/python3.13/site-packages/_pytest/runner.py": 5772610501857496741,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd_module.py": 7122050193390298178,
- "venv/lib/python3.13/site-packages/yaml/tokens.py": 2279161238859232338,
- "venv/lib/python3.13/site-packages/fastapi/__main__.py": 10755252341326986079,
- "frontend/src/lib/ui/HelpTooltip.svelte": 15082693035830243831,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein_py.py": 11350239659973489646,
- "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/METADATA": 11439969143853665311,
- "venv/lib/python3.13/site-packages/PIL/FontFile.py": 112053841436523305,
- "frontend/src/lib/api/datasetReview.js": 11780670121350173465,
- "backend/src/core/utils/superset_context_extractor/_filters.py": 14230663187221307078,
- "backend/src/api/routes/__tests__/test_clean_release_v2_api.py": 17447140422807500877,
- "frontend/src/routes/datasets/+page.svelte": 4090458050277453670,
- "venv/lib/python3.13/site-packages/apscheduler-3.11.2.dist-info/METADATA": 3179724236887811680,
- "backend/git_repos/remote/test-repo.git/objects/c5/b992984fe856bd81206304a881faa3087937cf": 2441623644664166468,
- "backend/tests/test_task_persistence.py": 14626604091774325821,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/result.py": 8306497889916212025,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/transforms.py": 3773159138960141434,
- "venv/lib/python3.13/site-packages/tzlocal/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/dtypes.pyi": 6713822658171717369,
- "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER": 17282701611721059870,
- "frontend/src/components/git/CommitModal.svelte": 12274093894389435426,
- "backend/src/api/routes/git/_gitea_routes.py": 3966408809424419232,
- "venv/lib/python3.13/site-packages/pandas/_libs/join.cpython-313-x86_64-linux-gnu.so": 2947947484481830203,
- "venv/lib/python3.13/site-packages/attr/exceptions.pyi": 12323493441583681402,
- "venv/lib/python3.13/site-packages/dotenv/variables.py": 5438726379749803751,
- "venv/lib/python3.13/site-packages/attrs/converters.py": 13109003765349201809,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py": 2516476609539242190,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_collections.py": 14307204206312829238,
- "venv/lib/python3.13/site-packages/numpy.libs/libgfortran-040039e1-0352e75f.so.5.0.0": 13946067868274850557,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/random.pyi": 1808392097712315455,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/selectable.py": 14646717349365560549,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_logical_ops.py": 16166386974005224415,
- "venv/lib/python3.13/site-packages/numpy/_typing/__init__.py": 18242238390157333247,
- "venv/lib/python3.13/site-packages/pycparser/c_ast.py": 5942107079119742,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timedeltas.py": 1175883320586860493,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_interval_range.py": 9900908262700749861,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/missing.py": 14589973874359353799,
- "venv/lib/python3.13/site-packages/pygments/lexers/ruby.py": 6898093948224302592,
- "venv/lib/python3.13/site-packages/packaging/tags.py": 1999137344425005827,
- "venv/lib/python3.13/site-packages/passlib/__init__.py": 6987142392711441525,
- "venv/lib/python3.13/site-packages/PIL/ImageColor.py": 17058618058554970738,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_datetime.py": 1678885152993000592,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_django.py": 8455054295577203929,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe_protocol.py": 12857147443873820285,
- "frontend/src/lib/api/translate/datasources.js": 17202165717960970061,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/__init__.py": 63497920264089252,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/common/pythoncapi-compat/COPYING": 3474104874623144155,
- "venv/bin/pyrsa-priv2pub": 16766314338551408621,
- "venv/lib/python3.13/site-packages/packaging/requirements.py": 2896326326372719999,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/console.py": 10217327186846649646,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/comparisons.pyi": 9338084426044982038,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/relationships.py": 8401569216905291119,
- "venv/lib/python3.13/site-packages/passlib/ext/django/models.py": 12386223748379294996,
- "backend/src/api/routes/git/_repo_lifecycle_routes.py": 410621371876058173,
- "backend/src/models/dataset_review_pkg/_filter_models.py": 11282786315414885098,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/ssh.py": 16262079536832961001,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_constructors.py": 979131987837682435,
- "backend/src/services/clean_release/__tests__/test_source_isolation.py": 462142504664192849,
- "venv/lib/python3.13/site-packages/numpy/_core/records.py": 11414828908088050950,
- "backend/src/schemas/_external_stubs.py": 3177836248301865994,
- "venv/lib/python3.13/site-packages/jaraco/functools/__init__.py": 15334412919279565528,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/strings.pyi": 402863478592154500,
- "backend/src/services/__tests__/test_resource_service.py": 7247551330585718683,
- "backend/src/plugins/translate/_llm_call.py": 9157531101342797409,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_indexing.py": 17106010337164216722,
- "venv/lib/python3.13/site-packages/numpy/fft/tests/test_pocketfft.py": 18025182347224285050,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/METADATA": 6557531107125553027,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_constructors.py": 6440526981746306640,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_rewrite_warning.py": 4895919872954538758,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py": 7852235015155694076,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/__init__.py": 10357835306532281617,
- "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.py": 16854377502491291093,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_finfo.py": 17174674209412768422,
- "backend/src/models/config.py": 9124130663272717982,
- "venv/lib/python3.13/site-packages/pandas/_libs/window/__init__.py": 15130871412783076140,
- "backend/git_repos/remote/test-repo.git/objects/00/fcf77cecdf261aef91eda792ab3384a3339922": 1527330822006618217,
- "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/WHEEL": 16097436423493754389,
- "backend/_convert_defs.py": 208535643309836247,
- "venv/lib/python3.13/site-packages/certifi/__main__.py": 13417658012431779061,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_client/__init__.py": 14186136918454802843,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_old_ma.py": 18116460138221458026,
- "venv/lib/python3.13/site-packages/_pytest/hookspec.py": 387790426108810884,
- "venv/lib/python3.13/site-packages/pygments/lexers/ooc.py": 14540210212631538007,
- "venv/lib/python3.13/site-packages/keyring/backends/kwallet.py": 3071915635647280308,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_ints.py": 5616705208267050659,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_astype.py": 15768655715952923925,
- "venv/lib/python3.13/site-packages/pygments/lexers/graph.py": 10445044822847205061,
- "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_put.py": 8547660958963625817,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_subplots.py": 4596089143375088346,
- "frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js": 7400069550465334990,
- "frontend/tailwind.config.js": 13139381085024634801,
- "backend/src/services/maintenance/__init__.py": 3167476255502727608,
- "venv/lib/python3.13/site-packages/numpy/f2py/__main__.py": 12567751646090102167,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_coercion.py": 3551994404797560483,
- "venv/lib/python3.13/site-packages/pip/_vendor/distro/__main__.py": 2688850704829116818,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.pyi": 51728851886466199,
- "venv/lib/python3.13/site-packages/pygments/styles/gh_dark.py": 7717523746712391809,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py": 6509914623926583629,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_use.f90": 2657057181044959432,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_map.py": 4761668276463940924,
- "venv/lib/python3.13/site-packages/greenlet/TBrokenGreenlet.cpp": 10822436772777706192,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/table.py": 16856253349556498073,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_formats.py": 2601044064677727807,
- "frontend/src/lib/stores/datasetReviewSession.js": 12759266804307584180,
- "venv/lib/python3.13/site-packages/dateutil/tz/_factories.py": 7538654189286887518,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcrypto-2e26a48f.so.3": 3658133521245392852,
- "backend/src/api/routes/git/_deps.py": 11478430655620147674,
- "backend/src/services/clean_release/repositories/compliance_repository.py": 2888085832526178946,
- "backend/src/api/routes/__tests__/test_assistant_api.py": 14069847490001200210,
- "backend/src/plugins/translate/scheduler.py": 13650497976959209825,
- "frontend/build/_app/immutable/chunks/BtMNxLZr.js": 5550630982455761657,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/__init__.py": 13749066369790839334,
- "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.pyi": 3661113433078225952,
- "venv/lib/python3.13/site-packages/anyio/streams/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/android.py": 8607703347015852195,
- "backend/src/plugins/translate/_run_source.py": 11569137727611732019,
- "venv/lib/python3.13/site-packages/anyio/streams/memory.py": 11762722143503428823,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odswriter.py": 5134385709728943904,
- "frontend/src/lib/api/translate/runs.js": 1220731879179347641,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/base.py": 16052592982063844259,
- "docker/nginx.ssl.conf": 12350396037548059686,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_index.py": 14187428934500390688,
- "venv/lib/python3.13/site-packages/pygments/lexers/rnc.py": 9747352274729854620,
- "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.py": 15989335816452913951,
- "venv/lib/python3.13/site-packages/_cffi_backend.cpython-313-x86_64-linux-gnu.so": 829323374625147265,
- "backend/src/services/git/_remote_providers.py": 7497094824437995253,
- "backend/git_repos/remote/test-repo.git/hooks/prepare-commit-msg.sample": 7530253302780245896,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop_duplicates.py": 5874427993953991216,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/__init__.py": 1398617034174236358,
- "venv/lib/python3.13/site-packages/pandas/_libs/testing.cpython-313-x86_64-linux-gnu.so": 16758333404587340103,
- "venv/lib/python3.13/site-packages/pygments/lexers/teal.py": 10004159499175716139,
- "venv/lib/python3.13/site-packages/iniconfig/__init__.py": 12623265899068631092,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_msvc.h": 2465089365642299646,
- "venv/lib/python3.13/site-packages/numpy/_typing/_add_docstring.py": 14657346268890680694,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nditer.py": 8341339612899904236,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/inspect.py": 1401259241736437656,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_extension.py": 17245018204352082978,
- "venv/lib/python3.13/site-packages/numpy/core/numerictypes.py": 5776941405348611027,
- "venv/lib/python3.13/site-packages/git/objects/__init__.py": 2110615482320355676,
- "venv/lib/python3.13/site-packages/httpcore/_sync/http11.py": 5947339024588907032,
- "venv/lib/python3.13/site-packages/urllib3/http2/connection.py": 1661620860881397554,
- "backend/src/plugins/translate/preview_review.py": 5584592578627646560,
- "venv/lib/python3.13/site-packages/pygments/styles/emacs.py": 4540417536507245024,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/WHEEL": 6514509858522675228,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/wrapper.py": 14599195010683170123,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/__init__.py": 11526998905763262175,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py": 18229054440703471493,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/cookies.py": 4997226307650350876,
- "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.py": 7446626038222262489,
- "venv/lib/python3.13/site-packages/pandas/io/pytables.py": 17482934215513855928,
- "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/RECORD": 13494296690334916257,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/type_check.pyi": 9177256991985898824,
- "venv/lib/python3.13/site-packages/pandas/util/version/__init__.py": 3844072588696074141,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/__init__.py": 15340047930888693984,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/PIL/DcxImagePlugin.py": 11767274218348117481,
- "venv/lib/python3.13/site-packages/pygments/lexers/codeql.py": 4254046699692048717,
- "venv/lib/python3.13/site-packages/pygments/lexers/rebol.py": 10460732731157940232,
- "frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js": 7736587487210851851,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_util.py": 16024147572807865219,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_constructors.py": 12118296571694122743,
- "venv/lib/python3.13/site-packages/fastapi/security/http.py": 8465565118555441408,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/multiarray.py": 3224049574922696945,
- "venv/lib/python3.13/site-packages/numpy/_typing/_scalars.py": 17701938912160369190,
- "venv/lib/python3.13/site-packages/pygments/util.py": 4815334059917765852,
- "venv/lib/python3.13/site-packages/pandas/core/internals/__init__.py": 1377108808392195313,
- "venv/lib/python3.13/site-packages/_pytest/debugging.py": 16135285365306979060,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_utils.py": 10936299012115637790,
- "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.pyi": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_astype.py": 11995587502880659624,
- "venv/lib/python3.13/site-packages/jaraco/classes/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_find_common_type.py": 9581516171321396333,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/redis.py": 11313520438600819390,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/stride_tricks.pyi": 5844806555773292985,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/__init__.py": 4870269250323682576,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/asyncio.py": 11442130378027628520,
- "venv/lib/python3.13/site-packages/_pytest/_code/__init__.py": 6211607282116942091,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_boxplot_method.py": 7635131059308651529,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/heuristics.py": 1422768761337195135,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_map.py": 10769974470610467636,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rank.py": 14115215895836854973,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__main__.py": 111505188798650285,
- "venv/lib/python3.13/site-packages/pydantic/class_validators.py": 4643597082531287188,
- "venv/lib/python3.13/site-packages/pandas/io/formats/css.py": 11288129826285529457,
- "venv/lib/python3.13/site-packages/pandas/io/sas/sas7bdat.py": 17851617851457266799,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/row.py": 9763935103055608874,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_indexing.py": 5063545640498065297,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/unused_registry.py": 10153622516112471812,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply.py": 8103417303073393969,
- "venv/lib/python3.13/site-packages/sqlalchemy/event/legacy.py": 13465911776953636949,
- "venv/lib/python3.13/site-packages/sqlalchemy/pool/__init__.py": 4337679908168515343,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/context.py": 1041624619197012753,
- "venv/lib/python3.13/site-packages/PIL/WalImageFile.py": 12442826195371137238,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/refresh_token.py": 17927903035152872556,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/json.py": 15373167408891671190,
- "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.py": 1809069379864985298,
- "venv/lib/python3.13/site-packages/PIL/ImageShow.py": 11437096951764124817,
- "venv/lib/python3.13/site-packages/authlib/deprecate.py": 3563885283090710443,
- "venv/lib/python3.13/site-packages/yaml/events.py": 745772917931702910,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/npyio.pyi": 14147712281086095231,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/dependency.py": 7300594038182867460,
- "venv/lib/python3.13/site-packages/passlib/crypto/digest.py": 15890463288512025688,
- "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape_base.pyi": 10291383658131961346,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/http/httptools_impl.py": 10367325397209016951,
- "venv/lib/python3.13/site-packages/pygments/__init__.py": 14493583771211110135,
- "frontend/build/_app/immutable/chunks/BWQQsteK.js": 15588475815071543641,
- "backend/src/core/superset_client/_databases.py": 16562767538012813426,
- "venv/lib/python3.13/site-packages/pydantic/json_schema.py": 15678278224696353978,
- "venv/lib/python3.13/site-packages/charset_normalizer/md.cpython-313-x86_64-linux-gnu.so": 1835299664481804968,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi": 10548370574281981402,
- "venv/lib/python3.13/site-packages/anyio/abc/_tasks.py": 16839170934610571514,
- "frontend/playwright-report/trace/snapshot.v8KI4P3m.js": 7854911091722310751,
- "venv/lib/python3.13/site-packages/dateutil/tz/win.py": 8427821225251397364,
- "frontend/src/lib/api/translate.js": 18140498250896378509,
- "backend/src/core/migration_engine.py": 18205310218665191965,
- "venv/lib/python3.13/site-packages/pygments/lexers/asn1.py": 15030988816882821134,
- "backend/src/api/routes/git/_repo_routes.py": 12158952761025397291,
- "backend/src/services/clean_release/stages/__init__.py": 2966227562547886302,
- "backend/_batch_convert_defs.py": 2671571251303777016,
- "backend/git_repos/remote/test-repo.git/hooks/pre-rebase.sample": 15693225890270078290,
- "venv/lib/python3.13/site-packages/fastapi/middleware/wsgi.py": 3706578020491442104,
- "venv/lib/python3.13/site-packages/pandas/core/api.py": 3390809109543982410,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/console.py": 3540660073442483692,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/dml.py": 5340326603935367534,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polybase.pyi": 3404315099794022355,
- "frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js": 16890149311572703440,
- "venv/lib/python3.13/site-packages/pandas/core/construction.py": 10646956189518908985,
- "backend/src/services/sql_table_extractor.py": 10885590114154069199,
- "venv/lib/python3.13/site-packages/pandas/tests/test_aggregation.py": 16863055892192070549,
- "venv/lib/python3.13/site-packages/gitdb/db/base.py": 3375449584942578385,
- "venv/lib/python3.13/site-packages/numpy/random/__init__.pyi": 13833571330152615376,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_delete.py": 3485374671877063217,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py": 1331438198531942242,
- "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/pygments/lexer.py": 3658450949169647228,
- "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/RECORD": 10552906886624188222,
- "frontend/src/routes/datasets/__tests__/DatasetList.test.js": 10189122239208504978,
- "backend/src/models/dataset_review_pkg/__init__.py": 1796062139548584878,
- "venv/lib/python3.13/site-packages/pycparser/ply/cpp.py": 1665654017894222868,
- "backend/src/models/maintenance.py": 4470866349123892443,
- "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.py": 2401931196871484449,
- "venv/lib/python3.13/site-packages/pygments/lexers/bqn.py": 11823648528816858738,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_conversion.py": 12184280074522274780,
- "venv/lib/python3.13/site-packages/pydantic_settings/main.py": 17272314000918984790,
- "venv/lib/python3.13/site-packages/_pytest/setuponly.py": 10959102379908419762,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/models.py": 3567900447243180991,
- "venv/lib/python3.13/site-packages/_pytest/main.py": 931018496411984909,
- "venv/lib/python3.13/site-packages/itsdangerous/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_config/dates.py": 3863381688916127265,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_round.py": 1299086932398824299,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/validator.py": 11486125578281617670,
- "venv/lib/python3.13/site-packages/jaraco/functools/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/macos.py": 17442393555211213147,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_constructors.pyi": 4993066609272697419,
- "venv/lib/python3.13/site-packages/passlib/tests/test_utils_md4.py": 15270721044910698449,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_dt_accessor.py": 2229616362327032253,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/models.py": 17870758731501836303,
- "venv/lib/python3.13/site-packages/referencing/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_csv.py": 10737444103906389448,
- "venv/lib/python3.13/site-packages/pydantic/v1/_hypothesis_plugin.py": 6383299780629629080,
- "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/REQUESTED": 15130871412783076140,
- "frontend/build/_app/immutable/nodes/19.BtYix_y_.js": 13099146879599461804,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/errors.py": 18154419146257747681,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_aggregate.py": 15038915958422670700,
- "backend/src/api/routes/assistant/_llm_planner.py": 7325833916307204752,
- "backend/src/services/__tests__/test_llm_provider.py": 14345242680566878510,
- "venv/lib/python3.13/site-packages/authlib/jose/drafts/__init__.py": 4770885427721822507,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/setuptools_build.py": 13594639612360346306,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/json/__init__.py": 7877061921210840955,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_common.py": 10797243274520625867,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np121.pkl.gz": 4708588000144933291,
- "venv/lib/python3.13/site-packages/dateutil/zoneinfo/rebuild.py": 1813298167468704155,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parsing.py": 2228959015420278458,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/token_validator.py": 13917237710752731397,
- "frontend/src/lib/components/layout/TaskDrawer.svelte": 1108434227611806299,
- "venv/lib/python3.13/site-packages/websockets/utils.py": 17624459810483092475,
- "venv/lib/python3.13/site-packages/numpy/_typing/_nested_sequence.py": 7827259347937485408,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_protocols.py": 5019018645804313814,
- "venv/lib/python3.13/site-packages/pygments/formatters/__init__.py": 8009871891954370829,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_set_value.py": 17480833128128893268,
- "backend/git_repos/remote/test-repo.git/hooks/push-to-checkout.sample": 4825338927654285910,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_complex.py": 11732242536199439023,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/background.py": 2105814165112049750,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/__init__.py": 15130871412783076140,
- "backend/git_repos/remote/test-repo.git/objects/cf/d2dcbd55735b8cedf21e04e64ac627c6f9a458": 10982669277486885525,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py": 5951113078754792806,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/annotation.py": 15855576199737688124,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.py": 17817123894903120316,
- "backend/src/services/git/_gitea.py": 2348444900635153882,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_api.py": 13319208721442328400,
- "venv/lib/python3.13/site-packages/pygments/lexers/__init__.py": 4627540245914849670,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/install.py": 17631777189475433503,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_case_when.py": 4133174129660834805,
- "venv/lib/python3.13/site-packages/pandas/io/pickle.py": 5418646169167774144,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/visitors.py": 5190923415390076080,
- "venv/lib/python3.13/site-packages/websockets/asyncio/connection.py": 17044409627448400723,
- "venv/lib/python3.13/site-packages/psycopg2/extras.py": 7510107741729866600,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/starlette/middleware/__init__.py": 9524277524025372856,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jws_algs.py": 11920621906391796226,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_common.py": 2223069451949206319,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_fiscal.py": 14652343698825214870,
- "venv/lib/python3.13/site-packages/pandas/tests/libs/test_hashtable.py": 7762405492052106717,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/util.py": 4890614159013873000,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_describe.py": 11923715539897559626,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_alter_axes.py": 11338712836362534969,
- "venv/lib/python3.13/site-packages/fastapi/templating.py": 10760135144345238340,
- "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py": 5995058808539530576,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_common.py": 12064185052519470358,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_insert.py": 6970975909565157982,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/provision.py": 8707620698060818654,
- "venv/lib/python3.13/site-packages/git/objects/fun.py": 15014209679156260865,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_equals.py": 6429101196875333574,
- "venv/lib/python3.13/site-packages/pycparser/ply/ygen.py": 5520340773074632724,
- "venv/lib/python3.13/site-packages/pycparser/_build_tables.py": 569728086093219621,
- "venv/lib/python3.13/site-packages/pygments/lexers/sas.py": 6128008194712914874,
- "frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte": 11335071999625939315,
- "frontend/src/components/backups/BackupManager.svelte": 15318298322895797591,
- "dist/docker/frontend.0.1.1.tar.xz": 14558310887004056908,
- "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.pyi": 1424133074692438241,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/query.py": 3867868366067025348,
- "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.pyi": 9629457630163613604,
- "venv/lib/python3.13/site-packages/uvicorn/py.typed": 15240312484046875203,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/json.py": 4660603129768960095,
- "venv/lib/python3.13/site-packages/uvicorn/middleware/asgi2.py": 5355343704425405009,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/requests.py": 6703055041957748929,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_npfuncs.py": 8238385897366878558,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/preloaded.py": 3719702436309355562,
- "frontend/e2e/e2e-nohealth.mjs": 5921562935931064381,
- "frontend/build/_app/immutable/nodes/5.Qu948XkR.js": 7156066372883630056,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_common.py": 9097104320321411408,
- "frontend/playwright-report/data/a19c216148b1612f8e11679d34071559b77021a0.png": 2734494351837969206,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_with_comments.f": 3980077223827767077,
- "backend/src/plugins/translate/_token_budget.py": 13508548690925198562,
- "venv/lib/python3.13/site-packages/anyio/_core/_eventloop.py": 6853955946028131785,
- "venv/lib/python3.13/site-packages/keyring/backends/Windows.py": 4103830951042463184,
- "venv/lib/python3.13/site-packages/numpy/random/_philox.pyi": 7503018432880404291,
- "backend/src/core/superset_client/_user_projection.py": 15240732089847883635,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/rsa.py": 5392922995791487437,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py": 8864112842559211971,
- "venv/lib/python3.13/site-packages/numpy/_core/records.pyi": 14194354215405544730,
- "venv/lib/python3.13/site-packages/numpy/_core/_struct_ufunc_tests.cpython-313-x86_64-linux-gnu.so": 13269324887178340397,
- "venv/lib/python3.13/site-packages/pandas/core/util/numba_.py": 3535857372998653863,
- "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptography.py": 4383854709657749855,
- "venv/lib/python3.13/site-packages/ecdsa/util.py": 10543788809724099209,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get.py": 6509102681661636928,
- "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.c": 2519219289444051739,
- "venv/lib/python3.13/site-packages/numpy.libs/libscipy_openblas64_-096271d3.so": 14338208504131470036,
- "venv/lib/python3.13/site-packages/pillow.libs/libbrotlicommon-c55a5f7a.so.1.2.0": 2635192149914499986,
- "venv/lib/python3.13/site-packages/passlib/utils/compat/_ordered_dict.py": 14248790502300368024,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/io/formats/xml.py": 12235904458551067063,
- "venv/lib/python3.13/site-packages/PIL/_avif.pyi": 18222325750818585549,
- "venv/lib/python3.13/site-packages/authlib/common/security.py": 2291133227104016684,
- "venv/bin/pyrsa-decrypt": 10929163076272054227,
- "frontend/playwright-report/trace/index.CzXZzn5A.css": 10367596602957476705,
- "backend/src/core/logger/__tests__/test_logger.py": 5608415766873765106,
- "frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js": 5982682724976240528,
- "venv/lib/python3.13/site-packages/anyio/streams/text.py": 12507591237176920223,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_slp_switch.py": 16490710972475154509,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/conftest.py": 17897502508251413988,
- "venv/lib/python3.13/site-packages/pluggy/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_version_meson.py": 4875297137037630519,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/dynamic.py": 15220116196072524330,
- "backend/src/services/clean_release/dto.py": 16033619016556005561,
- "venv/lib/python3.13/site-packages/pygments/lexers/arturo.py": 4565524340706235725,
- "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/PIL/_binary.py": 14039167720582222043,
- "venv/lib/python3.13/site-packages/numpy/f2py/__init__.pyi": 3566887042414273892,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_asof.py": 15792528637923603240,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/secrets.py": 17816662030600756342,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_deprecated_kwargs.py": 10379929935087904974,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion": 2607512361823362698,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine_first.py": 11425059090050867171,
- "venv/lib/python3.13/site-packages/jeepney/bindgen.py": 7094585345946943534,
- "venv/lib/python3.13/site-packages/pandas/util/_exceptions.py": 14426860079366867683,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_s3.py": 17425535047477778484,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/category.py": 18192569199634406001,
- "venv/lib/python3.13/site-packages/greenlet/TStackState.cpp": 16720079760074325527,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/yaml.py": 17801117405950663611,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_tokenizer.py": 7994281991455916540,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_converters.py": 8869440774594127419,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.pyi": 15114028503984522176,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_head_tail.py": 1906121476322841736,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_round.py": 9358309072340573675,
- "venv/lib/python3.13/site-packages/pandas/tests/io/xml/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_row.py": 918740441973901148,
- "venv/lib/python3.13/site-packages/urllib3/poolmanager.py": 15431313180245757657,
- "venv/lib/python3.13/site-packages/pygments/__main__.py": 13200500591994479045,
- "venv/lib/python3.13/site-packages/pygments/lexers/idl.py": 11454152060351801696,
- "venv/lib/python3.13/site-packages/fastapi/security/api_key.py": 6965937678104291169,
- "frontend/playwright-report/trace/uiMode.html": 2646979321132705707,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_sparc_sun_gcc.h": 2915128971664712180,
- "backend/src/scripts/test_dataset_dashboard_relations.py": 11883199369340933897,
- "backend/src/services/dataset_review/semantic_resolver.py": 11369306880421964134,
- "venv/lib/python3.13/site-packages/pandas/_libs/lib.cpython-313-x86_64-linux-gnu.so": 6452315003728497116,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_unique.py": 3148372351781648868,
- "venv/lib/python3.13/site-packages/starlette/applications.py": 13591448461234020757,
- "venv/lib/python3.13/site-packages/pygments/lexers/vyper.py": 6477559246065994199,
- "backend/tests/services/dataset_review/test_superset_matrix.py": 3788494235626090289,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/_has_cy.py": 11979732417254560424,
- "frontend/src/routes/settings/FeaturesSettings.svelte": 14192374301379217586,
- "frontend/src/components/git/GitReleasePanel.svelte": 11177244258160406730,
- "venv/lib/python3.13/site-packages/anyio/_core/_testing.py": 14024940365851109155,
- "venv/lib/python3.13/site-packages/gitdb/test/test_util.py": 541144638852210407,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/adapter.py": 5908944827805063108,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/request.py": 10492090878715126550,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_io.py": 4199750143323741326,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_scrypt.py": 8106466515670064013,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_inference.py": 16402427186697071465,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_fillna.py": 16297834601116528166,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/conftest.py": 13381752264278264218,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/WHEEL": 8600534672961461758,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5-fcafa220.so.3.3": 5620628698712971642,
- "frontend/src/routes/tools/mapper/+page.svelte": 11196482975871090089,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/index.py": 2763962019423787504,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.cpython-313-x86_64-linux-gnu.so": 16927263232848238698,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x448.py": 3960540415600165213,
- "frontend/build/_app/immutable/chunks/2dOUpm6k.js": 11811637653151731489,
- "frontend/vitest.config.js": 4756170101280085905,
- "backend/src/core/utils/matching.py": 1700014874878218207,
- "venv/lib/python3.13/site-packages/pydantic/v1/annotated_types.py": 12925825196690299531,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_function_base.pyi": 2792940598392356268,
- "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/__init__.py": 12911374670789466961,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_converter.py": 7709581879446228856,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/endpoint.py": 8519226897299461194,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_month.py": 1613806538807726074,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_printing.py": 1901396869745313303,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/linalg.pyi": 7217817172953767893,
- "venv/lib/python3.13/site-packages/more_itertools/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/passlib/ext/__init__.py": 15240312484046875203,
- "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.pyi": 9911899303567570646,
- "venv/lib/python3.13/site-packages/annotated_doc/__init__.py": 6834198874252778425,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_duplicated.py": 6659959750254523427,
- "venv/lib/python3.13/site-packages/pygments/lexers/gsql.py": 15294109558028161389,
- "venv/bin/websockets": 12099863324306500376,
- "frontend/build/_app/immutable/chunks/0SSHfn-s.js": 1512028033550082311,
- "venv/lib/python3.13/site-packages/ecdsa/test_sha3.py": 12459459298663975730,
- "venv/lib/python3.13/site-packages/itsdangerous/exc.py": 11181421963755661477,
- "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE.PSF": 13208428090829817329,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/util.py": 18279366777506483176,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2cmap.py": 5863341586534531594,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpq-9b38f5e3.so.5.17": 9680474575710585826,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.f": 9330535808093475892,
- "venv/lib/python3.13/site-packages/jsonschema/_keywords.py": 949562792260528762,
- "venv/lib/python3.13/site-packages/passlib/handlers/digests.py": 18158237109145814857,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_common_basic.py": 1945891789924713537,
- "venv/lib/python3.13/site-packages/numpy/core/multiarray.py": 18368443598659711836,
- "frontend/src/lib/api/validation.js": 10650815174196870103,
- "frontend/src/components/storage/FileList.svelte": 6226735853135032532,
- "backend/src/services/__tests__/test_llm_prompt_templates.py": 12364821019604393930,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90": 9097998998863007705,
- "venv/lib/python3.13/site-packages/pip/_internal/distributions/wheel.py": 13979536782410081712,
- "backend/src/services/dataset_review/clarification_engine.py": 16343602687904467259,
- "backend/alembic/versions/b0c1d2e3f4a5_cascade_ondelete_translate_fks.py": 1764442834210967136,
- "venv/lib/python3.13/site-packages/jaraco/classes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/io/parsers/python_parser.py": 7297059565749331767,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/hooks.py": 8580161128344266243,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/__init__.py": 1437580234680265326,
- "frontend/src/routes/datasets/DatasetList.svelte": 12931773180198281284,
- "venv/lib/python3.13/site-packages/attrs/filters.py": 6844006230924162452,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/conftest.py": 16571782049241458769,
- "backend/src/plugins/translate/_lang_detect.py": 2125979777533490081,
- "venv/bin/pip3.13": 13861749540792881808,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval.py": 8549680643865283913,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/traceback.py": 2535227583726271746,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/freeze.py": 8644678595442275485,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/interfaces.py": 4890958419958257958,
- "venv/lib/python3.13/site-packages/pandas/tseries/holiday.py": 1134358927599488799,
- "venv/lib/python3.13/site-packages/uvicorn/lifespan/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/METADATA": 15876173086384975957,
- "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.py": 2953876934840155920,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_all_methods.py": 18227706645906325527,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/math.py": 1647133236144311250,
- "frontend/src/pages/Settings.svelte": 4380702370507713361,
- "venv/lib/python3.13/site-packages/git/objects/submodule/util.py": 8621897576747443758,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_federal.py": 16758212916399857971,
- "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/RECORD": 7914594107698271488,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/accessors.py": 12743680296510533030,
- "venv/lib/python3.13/site-packages/urllib3/contrib/socks.py": 645086578806871685,
- "venv/bin/pytest": 2593802493707545818,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/METADATA": 5045041742469375466,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pop.py": 14885271225856187795,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_extension_interface.py": 11693583111513457974,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_generic.py": 1098361087956787007,
- "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/uvicorn/supervisors/statreload.py": 5018382301336802445,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_info.py": 15151894356374015812,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/scalars.pyi": 17683675356659300769,
- "venv/lib/python3.13/site-packages/websockets/legacy/__init__.py": 12332512329533591682,
- "venv/lib/python3.13/site-packages/jeepney/wrappers.py": 15234251727654692435,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/backend.py": 9072112660082423691,
- "backend/src/services/profile_utils.py": 6022237321079224237,
- "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.pyi": 10077265709692546934,
- "venv/lib/python3.13/site-packages/fastapi/middleware/gzip.py": 436886407566263171,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/apps.py": 10758062668702044519,
- "frontend/build/_app/immutable/chunks/CHelQZPK.js": 13538277300205681632,
- "venv/lib/python3.13/site-packages/pandas/util/_doctools.py": 3766479022075611396,
- "venv/lib/python3.13/site-packages/jose/jws.py": 11592462993417182096,
- "backend/src/plugins/translate/sql_generator.py": 14497259013250233663,
- "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/licenses/LICENSE": 1641332741515411734,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filters/__init__.py": 835924536855006596,
- "venv/lib/python3.13/site-packages/pandas/core/indexers/__init__.py": 1756397319068017890,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/common.py": 16314033415206173235,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_fields.py": 16222559851336781264,
- "venv/lib/python3.13/site-packages/pandas/core/ops/array_ops.py": 10061020479033421596,
- "venv/lib/python3.13/site-packages/pygments/lexers/_tsql_builtins.py": 829193091321611630,
- "venv/lib/python3.13/site-packages/requests/auth.py": 912521029864094489,
- "venv/lib/python3.13/site-packages/urllib3/util/url.py": 15992369651965016538,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/search.py": 8292218231992728142,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/indexing.py": 18009437216172136227,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_hashtable.py": 2620207240930665390,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/well_known.py": 7183795183137931709,
- "venv/lib/python3.13/site-packages/urllib3/_version.py": 839747992523118887,
- "venv/lib/python3.13/site-packages/anyio/to_interpreter.py": 8369454842687342401,
- "venv/lib/python3.13/site-packages/pandas/core/indexers/objects.py": 409599993084996593,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/keywrap.py": 10424037418528425800,
- "venv/lib/python3.13/site-packages/pillow.libs/liblzma-61b1002e.so.5.8.2": 11405063484938458842,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token.py": 4747545058753492487,
- "venv/lib/python3.13/site-packages/numpy/lib/scimath.pyi": 18165025261847276375,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_fillna.py": 13675584998644907265,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/engines.py": 10876954465293959720,
- "venv/lib/python3.13/site-packages/httpcore/_sync/connection.py": 1539337414493486168,
- "venv/lib/python3.13/site-packages/numpy/_typing/_char_codes.py": 14162745886150625150,
- "venv/lib/python3.13/site-packages/pygments/lexers/d.py": 18120801227801223376,
- "backend/src/core/superset_client/__init__.py": 3185082867840025180,
- "venv/lib/python3.13/site-packages/pandas/core/roperator.py": 2587829042468916489,
- "backend/src/core/async_superset_client.py": 16280184433020523265,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/gitdb/fun.py": 55226330810782184,
- "venv/lib/python3.13/site-packages/cffi/ffiplatform.py": 6782148110863549472,
- "frontend/src/components/git/GitOperationsPanel.svelte": 5140779139910068800,
- "backend/src/plugins/translate/dictionary_filter.py": 18047895364995512274,
- "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/METADATA": 14180973198574731599,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_throw.py": 4119265751381210399,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/claims.py": 2035724920423374302,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_string.py": 9224234539232195189,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 2991745295485163924,
- "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/INSTALLER": 17282701611721059870,
- "backend/src/plugins/llm_analysis/models.py": 7637744212927477541,
- "venv/lib/python3.13/site-packages/pandas/io/__init__.py": 9767690163638898709,
- "backend/logs/app.log.1": 1282701464293071456,
- "venv/lib/python3.13/site-packages/pandas/io/xml.py": 326466573926392764,
- "venv/lib/python3.13/site-packages/_pytest/config/__init__.py": 12787579251203510616,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api1.c": 8494977275215578998,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/resolver.py": 2492962412506082234,
- "venv/lib/python3.13/site-packages/pip/_internal/distributions/base.py": 16714704323747942110,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/dtype.pyi": 465999539608816848,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/comparisons.pyi": 4158883009780474220,
- "frontend/src/routes/settings/StorageSettings.svelte": 1953157077500445570,
- "backend/src/services/clean_release/demo_data_service.py": 14506634271910590558,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.pyi": 9019577563960071498,
- "venv/lib/python3.13/site-packages/_pytest/pathlib.py": 9719734558816066453,
- "venv/lib/python3.13/site-packages/pip/_internal/network/lazy_wheel.py": 12936988990566680659,
- "venv/lib/python3.13/site-packages/pandas/tests/window/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/typing_inspection/introspection.py": 13916695705179237047,
- "venv/lib/python3.13/site-packages/apscheduler/executors/asyncio.py": 2230610508870117058,
- "venv/bin/httpx": 6651007446865716794,
- "venv/lib/python3.13/site-packages/ecdsa/test_malformed_sigs.py": 2606295770491528880,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_functions.py": 2255133375699086300,
- "venv/lib/python3.13/site-packages/fastapi/encoders.py": 1914192268055730299,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/flatiter.pyi": 9598576095384661517,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_color.py": 3700828402084646308,
- "venv/lib/python3.13/site-packages/PIL/JpegImagePlugin.py": 10621639599916796689,
- "venv/lib/python3.13/site-packages/pip/_internal/network/__init__.py": 1586148254475575526,
- "backend/src/services/clean_release/approval_service.py": 14346840951852454312,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_c_parser_only.py": 3038797485572319804,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/__init__.py": 6327819603201859020,
- "venv/lib/python3.13/site-packages/pygments/lexers/comal.py": 769727871242464458,
- "venv/lib/python3.13/site-packages/pygments/lexers/asm.py": 13861952972248758785,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_bar.py": 7791068963246005463,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_shape_base.py": 8837845103338426570,
- "venv/lib/python3.13/site-packages/charset_normalizer/cli/__main__.py": 2148876100501691980,
- "frontend/build/_app/immutable/chunks/DNOraAy0.js": 868732761380476466,
- "venv/lib/python3.13/site-packages/python_multipart/multipart.py": 5677735019292537174,
- "backend/src/plugins/migration.py": 10457528901248546685,
- "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.pyi": 14558091964387571257,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi": 13016654355866474644,
- "venv/bin/normalizer": 10972303485259566838,
- "backend/src/plugins/translate/__tests__/test_orchestrator.py": 10313792176402719801,
- "backend/git_repos/remote/test-repo.git/objects/3e/05ec6ef6504483c4bc7d00f0d0272c38ec661f": 11182016264585388842,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_exceptions.py": 12145393002202744314,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_algos.py": 5356470832688354593,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/traversals.py": 1188980668212022868,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/zip-safe": 15240312484046875203,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_core.py": 12712110303898046818,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/__init__.py": 11157967642611612522,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_categorical.py": 18254320571347851153,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_ufunc.py": 669019702416198889,
- "venv/lib/python3.13/site-packages/git/remote.py": 1694919255653049944,
- "venv/lib/python3.13/site-packages/pygments/lexers/diff.py": 5930189593946259160,
- "frontend/build/_app/immutable/chunks/CjoRN64c.js": 16472953773693067178,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/__init__.py": 71159121705871510,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_insert.py": 17383986803728810587,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_http_headers.py": 13187746870209705951,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_constructors.py": 17219764538851313252,
- "backend/src/schemas/auth.py": 2548857752520407876,
- "backend/src/services/maintenance/_chart_manager.py": 11268757631496775895,
- "backend/src/services/clean_release/exceptions.py": 16765031947674227117,
- "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_regression.py": 5652583095949741238,
- "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/pawn.py": 18127303119414402594,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/measure.py": 18327922742808984428,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/regexopt.py": 16073437303824961930,
- "venv/lib/python3.13/site-packages/pydantic_core/core_schema.py": 8106298745123589494,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_month.py": 8485374160446988786,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/mypy.py": 823265492261272631,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/__init__.py": 11009955319062089477,
- "venv/lib/python3.13/site-packages/ecdsa/rfc6979.py": 11564966030899162026,
- "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/client_mixin.py": 17980753662107479779,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/scrypt.py": 15294662527620994511,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.py": 17993169044119596860,
- "venv/lib/python3.13/site-packages/pandas/core/algorithms.py": 487939626203097713,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_polynomial.pyi": 9134949577567498894,
- "venv/lib/python3.13/site-packages/pydantic/v1/color.py": 14545509649623975912,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_numba.py": 1668304729617150075,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_spss.py": 4865360315909532603,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/signals.py": 13677199634497673845,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_accumulations.py": 11428556645065711062,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/warnings.py": 2552021607611112605,
- "venv/lib/python3.13/site-packages/pygments/formatters/_mapping.py": 13335227913146542481,
- "backend/git_repos/remote/test-repo.git/hooks/pre-receive.sample": 6118492409684431911,
- "frontend/build/_app/immutable/chunks/Bz99hFgy.js": 2788010001753617987,
- "backend/git_repos/remote/test-repo.git/objects/4e/227f4d8289ea657ae813b1460f979ae4b676b3": 5659284628452785331,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/sphinxext.py": 2403717774564798878,
- "venv/lib/python3.13/site-packages/starlette/responses.py": 14081178833432955042,
- "venv/lib/python3.13/site-packages/rsa/asn1.py": 3861968161559322784,
- "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_linalg.py": 2939739913218718132,
- "venv/lib/python3.13/site-packages/numpy/tests/test_lazyloading.py": 17465787495701737655,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.pyi": 3145980717589050713,
- "venv/lib/python3.13/site-packages/pytest/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/entrypoints.py": 11268059714209889385,
- "venv/lib/python3.13/site-packages/rpds/rpds.cpython-313-x86_64-linux-gnu.so": 561326734302492859,
- "venv/lib/python3.13/site-packages/pydantic/v1/class_validators.py": 6471688474853407718,
- "venv/lib/python3.13/site-packages/fastapi/datastructures.py": 727178955746650271,
- "venv/lib/python3.13/site-packages/ecdsa/test_pyecdsa.py": 14542286382742044648,
- "venv/lib/python3.13/site-packages/click/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/index_tricks.py": 10051261976498916957,
- "venv/lib/python3.13/site-packages/pandas/core/frame.py": 2630807744775247533,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connectionpool.py": 10453724680327835821,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/dotenv.py": 5872848911499749500,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/ansi.py": 948249091929588017,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/issue232.py": 6498198296113395367,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.pyi": 9003794318682878317,
- "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.pyi": 6576645822227068922,
- "venv/lib/python3.13/site-packages/pandas/api/typing/__init__.py": 6438268275857060114,
- "venv/lib/python3.13/site-packages/secretstorage/exceptions.py": 16701299261122689924,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_inspect.py": 10573558345297891848,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_datetimeindex.py": 14816894350435545024,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/requests/api.py": 12339139862411341381,
- "venv/lib/python3.13/site-packages/keyring/backends/fail.py": 5792496235026678021,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_append.py": 17016125916761365423,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex.tpl": 8820045022551446255,
- "venv/lib/python3.13/site-packages/sqlalchemy/schema.py": 16029542421991709659,
- "venv/lib/python3.13/site-packages/PIL/BufrStubImagePlugin.py": 5520941821175895889,
- "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/RECORD": 5612689057373270213,
- "venv/lib/python3.13/site-packages/pygments/lexers/capnproto.py": 15713281507099411738,
- "frontend/src/lib/stores/health.js": 3621667160018048028,
- "frontend/src/routes/settings/__tests__/settings_page.ux.test.js": 14507112961464496362,
- "venv/lib/python3.13/site-packages/h11/_receivebuffer.py": 4631433251046338381,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.pyi": 15789956857032062129,
- "venv/lib/python3.13/site-packages/uvicorn/server.py": 15714008348292243019,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_update_delete.py": 1317337950621091021,
- "frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js": 6358696236009732713,
- "frontend/build/_app/immutable/nodes/38.lN6lyang.js": 10345064950322542935,
- "venv/lib/python3.13/site-packages/certifi/cacert.pem": 14727832973577663826,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_freq_attr.py": 17290447066681837965,
- "venv/lib/python3.13/site-packages/httpcore/_exceptions.py": 6716590711697088732,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/__init__.py": 17454177076687312424,
- "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/interval.py": 3964550092873794670,
- "venv/lib/python3.13/site-packages/PIL/_util.py": 17116054813914373606,
- "venv/lib/python3.13/site-packages/charset_normalizer/constant.py": 3070316197495651997,
- "venv/lib/python3.13/site-packages/pygments/lexers/lean.py": 14518351619544450286,
- "venv/lib/python3.13/site-packages/pygments/lexers/bibtex.py": 14652372822443154388,
- "backend/src/api/routes/translate/_helpers.py": 6946167155296110158,
- "venv/lib/python3.13/site-packages/pygments/lexers/resource.py": 8057351545636349791,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23533.f": 12558972205518833024,
- "backend/tests/services/clean_release/test_report_audit_immutability.py": 4795829940402801626,
- "backend/src/plugins/translate/orchestrator_cancel.py": 673611364664367049,
- "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.pyi": 8916922961301555974,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_categorical.py": 12897027063618569795,
- "backend/alembic/env.py": 7020161137665650592,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-np0-objarr.npy": 1615546603475261360,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.py": 15426828792217499138,
- "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.py": 11397521081216402594,
- "venv/lib/python3.13/site-packages/pip/_vendor/certifi/cacert.pem": 15624463015628939254,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/util.py": 5364455058429522633,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/util.py": 6088868370298560146,
- "venv/lib/python3.13/site-packages/pygments/lexers/_ada_builtins.py": 16331776886501464264,
- "venv/lib/python3.13/site-packages/rsa/__init__.py": 14623742580410014505,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_textreader.py": 388955620768371652,
- "venv/lib/python3.13/site-packages/numpy/_core/memmap.pyi": 14124415711399771715,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/__init__.py": 16434403703599680307,
- "venv/lib/python3.13/site-packages/annotated_types/__init__.py": 7367790549779882749,
- "venv/lib/python3.13/site-packages/pandas/tests/test_sorting.py": 10751098438703044961,
- "venv/lib/python3.13/site-packages/pygments/lexers/srcinfo.py": 16466766917840327610,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_is_monotonic.py": 4626065848596214108,
- "frontend/src/lib/components/translate/TargetSchemaHint.svelte": 9354096644840520484,
- "frontend/build/_app/immutable/chunks/DSxK3NUv.js": 8639953729041066468,
- "backend/src/api/routes/profile.py": 8666418382456481533,
- "backend/git_repos/remote/test-repo.git/objects/a7/49f11fad695dff77faf1708c7320867d0be1df": 4641609158325033031,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/exc.py": 1448374203226983757,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh27697.f90": 4990763135487995517,
- "frontend/playwright-report/data/ac7f153484f7d6b15b773641e328a5ad9204f736.webm": 17964728097298408466,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/live.py": 8586058300967410643,
- "backend/tests/conftest.py": 5565151856098492311,
- "backend/src/api/routes/translate/_schedule_routes.py": 18139325016758974063,
- "venv/lib/python3.13/site-packages/pydantic/v1/decorator.py": 6124748023704700724,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/__init__.py": 15821192733097665649,
- "frontend/src/routes/+page.svelte": 5863865830077771796,
- "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/licenses/LICENSE": 11199044866758471950,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_readers.py": 2136472634307645842,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/yang.py": 7409365668425173823,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arrayobject.py": 13337664596833150958,
- "venv/lib/python3.13/site-packages/PIL/_imagingft.pyi": 1385456134120145584,
- "venv/lib/python3.13/site-packages/pygments/lexers/php.py": 17636450950688953288,
- "venv/lib/python3.13/site-packages/smmap/test/test_util.py": 5634593621291240094,
- "backend/src/api/routes/__tests__/test_reports_openapi_conformance.py": 17231166761215151699,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.cpython-313-x86_64-linux-gnu.so": 9014806524727977333,
- "venv/lib/python3.13/site-packages/pygments/lexers/crystal.py": 3579547906957125755,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.py": 3762934316884129514,
- "venv/lib/python3.13/site-packages/pip/py.typed": 10243553515949422671,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/color.py": 15062855556511243610,
- "venv/lib/python3.13/site-packages/fastapi/exceptions.py": 12665775976182239091,
- "venv/lib/python3.13/site-packages/secretstorage/defines.py": 9590959702075554048,
- "venv/lib/python3.13/site-packages/git/refs/head.py": 16271128287606894569,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/styled.py": 8726407298858811635,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/exceptions.py": 7518613450390473990,
- "venv/lib/python3.13/site-packages/apscheduler/executors/base.py": 1980520974511822101,
- "venv/lib/python3.13/site-packages/pygments/lexers/dns.py": 17149871769553794654,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/mutable.py": 9323088483998280629,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_transform.py": 18159263102656491974,
- "venv/lib/python3.13/site-packages/PIL/_webp.pyi": 18222325750818585549,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/json5.py": 9736695186548899403,
- "frontend/src/lib/ui/Button.svelte": 14815370250842191735,
- "venv/lib/python3.13/site-packages/pygments/lexers/grammar_notation.py": 9009644754106884095,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/typing.py": 17638587764345605306,
- "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/WHEEL": 9788895026336324100,
- "venv/lib/python3.13/site-packages/pydantic/experimental/missing_sentinel.py": 1637241331832367709,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-1.csv": 9129730764673472086,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/nonce.py": 18219168479887197733,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/provision.py": 7362363963464621570,
- "frontend/build/_app/immutable/chunks/rzyp_Wbp.js": 10559672264716197308,
- "venv/lib/python3.13/site-packages/numpy/testing/overrides.pyi": 17408923209056015964,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/WHEEL": 7414522633964952515,
- "frontend/build/_app/immutable/chunks/Dn-Kr3zV.js": 11981784044886973393,
- "venv/lib/python3.13/site-packages/numpy/_core/function_base.pyi": 8343632640078378312,
- "backend/src/services/git_service.py": 12429116089116885657,
- "backend/conftest.py": 16521922883434363388,
- "venv/lib/python3.13/site-packages/pygments/lexers/monte.py": 15158829991357994573,
- "backend/git_repos/remote/test-repo.git/objects/71/47ad0836409b35c1650dddf5fa6329ba61a824": 16601919569600972016,
- "venv/lib/python3.13/site-packages/numpy/_core/umath.py": 6132761780113682667,
- "venv/lib/python3.13/site-packages/pandas/_libs/parsers.cpython-313-x86_64-linux-gnu.so": 14134106903573638108,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiarray.py": 5928288171180750841,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/data/win64python2.npy": 11005857803794805939,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.pyi": 16372699564794732463,
- "venv/lib/python3.13/site-packages/httpcore/_async/http_proxy.py": 13364803556177997526,
- "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/RECORD": 10052481303799123207,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_sort_values.py": 15072305514178699398,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py": 11172336980866895356,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_sh_gcc.h": 3574353221233465215,
- "venv/lib/python3.13/site-packages/pygments/lexers/pddl.py": 9256112535059995841,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/__init__.py": 10470644151952252331,
- "frontend/src/routes/datasets/review/ReviewWorkspaceLeftSidebar.svelte": 9009994851177005358,
- "backend/src/plugins/translate/preview_constants.py": 12447768695944862994,
- "venv/lib/python3.13/site-packages/urllib3/contrib/pyopenssl.py": 11839715589709210412,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/indexable.py": 4131796922597075758,
- "frontend/src/lib/components/assistant/__tests__/assistant_confirmation.integration.test.js": 12582020574293031526,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_frame.py": 4303613319747945709,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_comparison.py": 11333735187162513512,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_asof.py": 18383318159051131669,
- "venv/lib/python3.13/site-packages/iniconfig/exceptions.py": 16501270224069836264,
- "venv/lib/python3.13/site-packages/uvicorn/lifespan/off.py": 16254524872582859561,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_assignability.pyi": 1718610984396277997,
- "venv/lib/python3.13/site-packages/pygments/lexers/blueprint.py": 6370363226580199085,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_shape_manipulation.py": 12598431412396627042,
- "venv/lib/python3.13/site-packages/numpy/random/_common.pxd": 3402284125943848851,
- "backend/src/models/dataset_review_pkg/_enums.py": 501173908863819198,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/requirements.py": 2362917888844255805,
- "venv/lib/python3.13/site-packages/_pytest/faulthandler.py": 13329320306353718649,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_formats.py": 2743326139283991615,
- "frontend/src/components/llm/ProviderConfig.svelte": 18108375341352259203,
- "venv/lib/python3.13/site-packages/urllib3/exceptions.py": 9687187566231423953,
- "venv/lib/python3.13/site-packages/websockets/extensions/__init__.py": 13067201313921664210,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nep50_promotions.py": 6318578947214302182,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/poly1305.py": 10854598965202354516,
- "backend/src/plugins/translate/dictionary_import_export.py": 3211239952922862631,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_gcs.py": 7733247456252965901,
- "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/METADATA": 6960169108624303030,
- "venv/lib/python3.13/site-packages/pandas/core/computation/expressions.py": 10684284531040203747,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_explode.py": 16195468192763502449,
- "venv/lib/python3.13/site-packages/anyio/_core/_resources.py": 8463932838064724564,
- "frontend/src/lib/stores/environmentContext.js": 9960741825828562980,
- "venv/lib/python3.13/site-packages/passlib/totp.py": 14590474309565233318,
- "venv/lib/python3.13/site-packages/keyring/backends/SecretService.py": 17482492072907438453,
- "venv/lib/python3.13/site-packages/_pytest/tmpdir.py": 10834220332037364219,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/__init__.py": 18069619555394133945,
- "venv/lib/python3.13/site-packages/PIL/GribStubImagePlugin.py": 14954946414134984896,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_tooltip.py": 853808724844451770,
- "venv/lib/python3.13/site-packages/pydantic_settings/utils.py": 14396350455520958703,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi": 16042272072158438261,
- "venv/lib/python3.13/site-packages/sqlalchemy/pool/impl.py": 4687705587963980337,
- "backend/src/core/auth/api_key.py": 15898549010462339946,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_nat.py": 7400568652984772972,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/lock.py": 14782882714168174465,
- "backend/src/services/auth_service.py": 5948958621485759282,
- "venv/lib/python3.13/site-packages/urllib3/fields.py": 9503202008440141421,
- "venv/lib/python3.13/site-packages/cffi/recompiler.py": 17809252277700094304,
- "venv/lib/python3.13/site-packages/jose/backends/rsa_backend.py": 13507186353881931758,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/timedeltas.py": 13653393430363556843,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_indexing.py": 7181087459615188551,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/__init__.py": 913610541217778747,
- "venv/lib/python3.13/site-packages/keyring/backend_complete.bash": 16589214602970214174,
- "venv/lib/python3.13/site-packages/keyring/errors.py": 4587094338672775040,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_crosstab.py": 6631711416347033281,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/automap.py": 4672057253309608464,
- "venv/lib/python3.13/site-packages/packaging/markers.py": 11602308203217831543,
- "backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py": 968076476163114767,
- "backend/src/core/task_manager/context.py": 11799776870777277331,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_timedelta64.py": 16821719402662529276,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/recfunctions.py": 18330899924171767482,
- "backend/test.db": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_normalize.py": 11373923576259976755,
- "venv/lib/python3.13/site-packages/sqlalchemy/event/registry.py": 2857989070743633709,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/common.py": 7426635866622531875,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/base.py": 13634605726041717070,
- "venv/lib/python3.13/site-packages/websockets/legacy/http.py": 16266924390281399720,
- "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/fastapi/exception_handlers.py": 9907950997607808699,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_win32_console.py": 18092547253031555768,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/clsregistry.py": 1589692649837935355,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_astype.py": 4178231007649608531,
- "venv/lib/python3.13/site-packages/gitdb/test/lib.py": 13294941660283059872,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/hash.py": 11824898770873127699,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/logging.py": 2426447364230673649,
- "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/_writer.py": 15053365792216907149,
- "venv/lib/python3.13/site-packages/_pytest/_argcomplete.py": 3586514420674089892,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict.py": 808180749933361743,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arithmetic.py": 3209727509456212551,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/__init__.py": 8093984834068317399,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_setops.py": 17350958906336246626,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_sample.py": 4641567828238191927,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args.py": 5821040955806257450,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_constructors.py": 6515602441449955627,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_sequence.py": 3721630758772772345,
- "venv/lib/python3.13/site-packages/httpcore/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/git/refs/symbolic.py": 14996822770181935589,
- "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE": 16499431172938528491,
- "venv/lib/python3.13/site-packages/pandas/io/formats/_color_data.py": 15614976586613738953,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_ssl_constants.py": 14834514243239777933,
- "backend/src/api/routes/mappings.py": 2467003850993962558,
- "backend/:memory:test_tasks": 9776368437354383244,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh2848.f90": 5799106109999071412,
- "venv/lib/python3.13/site-packages/pygments/lexers/verifpal.py": 9190813166686923928,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_swaplevel.py": 3584770792383216626,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_at_time.py": 15352346149584081864,
- "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_reductions.py": 11624188672428941494,
- "venv/lib/python3.13/site-packages/numpy/f2py/setup.cfg": 17974180080760231128,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_formats.py": 13752366280743004410,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/roles.py": 5448455900674232810,
- "venv/lib/python3.13/site-packages/numpy/tests/__init__.py": 15130871412783076140,
- "backend/src/core/plugin_loader.py": 8193009851819399597,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.cpython-313-x86_64-linux-gnu.so": 14468234464367691795,
- "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/__init__.py": 9083396324667433335,
- "frontend/src/services/adminService.js": 5974657342670197690,
- "venv/lib/python3.13/site-packages/attr/_cmp.pyi": 14443711863388606665,
- "venv/lib/python3.13/site-packages/websockets/extensions/permessage_deflate.py": 12957105912018691390,
- "venv/lib/python3.13/site-packages/ecdsa/ellipticcurve.py": 15624510849346629163,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/dtype.py": 9342837412280377086,
- "venv/lib/python3.13/site-packages/numpy/core/overrides.py": 11228841530565061867,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/__init__.py": 2635182244050911910,
- "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.pyi": 6286629088867436848,
- "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/RECORD": 8971487317739420905,
- "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_des.py": 7198931807116651263,
- "docker/backend.Dockerfile": 3370913626880503214,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_copy.py": 3114918520437707410,
- "venv/lib/python3.13/site-packages/jsonschema/_format.py": 8987698648383779883,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/dml.py": 17308908394336670576,
- "venv/lib/python3.13/site-packages/pygments/lexers/felix.py": 2334148799642808111,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_map.py": 6556132946198785761,
- "venv/include/site/python3.13/greenlet/greenlet.h": 16216120538647882082,
- "frontend/src/components/auth/ProtectedRoute.svelte": 17731993354153255366,
- "frontend/src/routes/datasets/review/ReviewWorkspaceHeader.svelte": 15302107925819930527,
- "venv/lib/python3.13/site-packages/referencing/_attrs.pyi": 10030665705880994025,
- "venv/lib/python3.13/site-packages/sqlalchemy/connectors/aioodbc.py": 2018840826888846321,
- "backend/src/services/git/_sync.py": 18140332203522670777,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numeric.py": 14451517189908259173,
- "venv/lib/python3.13/site-packages/pandas/tests/test_common.py": 8987965560487646705,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/base.py": 13454394827268856575,
- "scripts/generate_financial_arrears_data.py": 15989529185799374517,
- "venv/lib/python3.13/site-packages/starlette/endpoints.py": 3379755567024530053,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/packages.py": 11689856177725665974,
- "venv/lib/python3.13/site-packages/attr/_cmp.py": 3297594878548179300,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_numba.py": 203614377324678234,
- "venv/lib/python3.13/site-packages/PIL/PdfParser.py": 13710342183037972042,
- "venv/lib/python3.13/site-packages/dateutil/rrule.py": 398469817784230512,
- "backend/git_repos/remote/test-repo.git/hooks/post-update.sample": 4288868784459664203,
- "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas.py": 9446226619493404132,
- "venv/lib/python3.13/site-packages/keyring/backends/libsecret.py": 11621088556661567306,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_setops.py": 15196593522537569500,
- "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_ewm.py": 12153690217678546798,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_xlsxwriter.py": 8445547874832015203,
- "venv/lib/python3.13/site-packages/pygments/lexers/_openedge_builtins.py": 4979988747924637739,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi": 3254633032236269842,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_dialect.py": 6294522482440261756,
- "venv/lib/python3.13/site-packages/pygments/lexers/text.py": 10572727755736597715,
- "backend/src/api/routes/validation/__tests__/test_validation_api.py": 3854767876193048673,
- "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/WHEEL": 3749476255729626245,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/events.py": 15099787454570172797,
- "frontend/build/_app/immutable/nodes/36.B_fEKtct.js": 18068657546781069466,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/fromnumeric.py": 3792079757208879362,
- "venv/lib/python3.13/site-packages/fastapi/applications.py": 4975013401500183420,
- "venv/lib/python3.13/site-packages/greenlet/TMainGreenlet.cpp": 9489520001674089404,
- "venv/lib/python3.13/site-packages/pandas/_config/display.py": 433650013567734821,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_setops.py": 16240008859650640717,
- "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/RECORD": 2024211292009381421,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/json.py": 14738429697319670035,
- "venv/lib/python3.13/site-packages/pygments/lexers/_scilab_builtins.py": 17453812809700086888,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_generator_mt19937.py": 7299586490442539723,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo77.f": 16156304612888138777,
- "frontend/src/app.html": 10207534912546549080,
- "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.pyi": 2628035888703031029,
- "venv/lib/python3.13/site-packages/fastapi/_compat/may_v1.py": 9880083742927480960,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/__init__.py": 11914508471759255927,
- "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_implementation.py": 12245524932757110911,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/metadata.py": 1362166613223529108,
- "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.py": 1644743742545329282,
- "venv/lib/python3.13/site-packages/PIL/Hdf5StubImagePlugin.py": 15654153796225833950,
- "venv/lib/python3.13/site-packages/pip/_internal/req/req_set.py": 534498057184394558,
- "venv/lib/python3.13/site-packages/PIL/ImageFile.py": 15765130658900167517,
- "backend/src/plugins/maintenance_banner.py": 13137032570032257498,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/jwe.py": 10478268710546063196,
- "backend/src/api/routes/translate/__init__.py": 6357999798616465776,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_ddl.py": 3690189094298044728,
- "venv/lib/python3.13/site-packages/pip/_internal/req/constructors.py": 17485271035479378662,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/scope.py": 4096190764836489091,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_common.py": 3559416690270529904,
- "venv/lib/python3.13/site-packages/uvicorn/middleware/wsgi.py": 9179913252056394958,
- "venv/lib/python3.13/site-packages/starlette/middleware/sessions.py": 11719848399661632707,
- "venv/lib/python3.13/site-packages/greenlet/TGreenlet.hpp": 6993553444981671786,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_almost_equal.py": 9333355453468475330,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.cpython-313-x86_64-linux-gnu.so": 11019871270094058038,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/memory.py": 9947113720821563254,
- "venv/lib/python3.13/site-packages/multipart/__init__.py": 6496114190873890851,
- "frontend/src/routes/dashboards/health/+page.svelte": 11635018493969113169,
- "venv/lib/python3.13/site-packages/python_multipart/__init__.py": 10290895261363712562,
- "venv/lib/python3.13/site-packages/pandas/core/series.py": 11618272682977710696,
- "venv/lib/python3.13/site-packages/keyring/http.py": 1408024724330078009,
- "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/WHEEL": 13347410390513723930,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_api.py": 13739775047493489785,
- "venv/lib/python3.13/site-packages/PIL/__main__.py": 827665918723937817,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_reshape.py": 5572426834735088916,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_apply.py": 11248068903302454630,
- "venv/lib/python3.13/site-packages/pygments/lexers/ampl.py": 4594260378653369985,
- "venv/lib/python3.13/site-packages/pandas/core/col.py": 4221271461723119525,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/_json.py": 6718137926109998531,
- "frontend/build/_app/immutable/chunks/7p8qW0H9.js": 8406910162058460039,
- "backend/src/plugins/translate/preview_prompt_builder.py": 15837150631111510351,
- "frontend/build/_app/immutable/chunks/Dul6iTE7.js": 10339509389374345579,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_cumulative.py": 6346947559103505068,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/__init__.py": 11709551233929312136,
- "venv/lib/python3.13/site-packages/urllib3/util/ssl_.py": 11720964010284185952,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/extension_types.py": 1856757457657310231,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_pandas.py": 10894229569442891394,
- "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE": 14316979437290727897,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_insert.py": 11635164392966270621,
- "venv/lib/python3.13/site-packages/cffi/api.py": 5325821560978502135,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_validators.py": 2939255306814626438,
- "venv/lib/python3.13/site-packages/pandas/io/formats/string.py": 14718123345899686696,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_strings.py": 7168544888340296373,
- "venv/lib/python3.13/site-packages/httpcore/_async/socks_proxy.py": 9026788710898138090,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/dtype_api.h": 17040779421165903019,
- "venv/lib/python3.13/site-packages/jsonschema/tests/fuzz_validate.py": 2328585939822059352,
- "venv/lib/python3.13/site-packages/pydantic/v1/config.py": 12050640083719340958,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/test_array_with_attr.py": 6568496539994758985,
- "venv/lib/python3.13/site-packages/uvicorn/main.py": 5843333502356171120,
- "venv/lib/python3.13/site-packages/pygments/lexers/ada.py": 17032408976634308999,
- "frontend/playwright-report/trace/assets/defaultSettingsView-D31xz8zv.js": 1301407320635785789,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_windows.py": 9171347078900057357,
- "backend/src/scripts/clean_release_tui.py": 3006670970245009659,
- "venv/lib/python3.13/site-packages/pip/_internal/models/index.py": 2839270935469791607,
- "venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py": 16951268065271931235,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_series.py": 10922287546912569276,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_duplicated.py": 14676058112867601208,
- "venv/lib/python3.13/site-packages/pydantic/typing.py": 6661252174518316760,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-2.csv": 5423145402839576695,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_repeat.py": 18394463352314692642,
- "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/licenses/LICENSE": 5563356551734678258,
- "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py": 7906029092844029127,
- "venv/lib/python3.13/site-packages/pygments/lexers/nimrod.py": 8457135214131458774,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/operators.py": 2468046993343796128,
- "venv/lib/python3.13/site-packages/pygments/lexers/_luau_builtins.py": 13690910306072616818,
- "venv/lib/python3.13/site-packages/pygments/lexers/stata.py": 7249891970174867363,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex_like.py": 13803156447991282315,
- "venv/lib/python3.13/site-packages/httpcore/_async/connection.py": 2155744160496556069,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_conversion_utils.py": 1567199588622767277,
- "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.cpython-313-x86_64-linux-gnu.so": 3478629877770507853,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_repeat.py": 16971624301893342868,
- "venv/lib/python3.13/site-packages/passlib/tests/sample1b.cfg": 2872366861156549016,
- "venv/lib/python3.13/site-packages/pygments/lexers/func.py": 12257919753150082714,
- "venv/lib/python3.13/site-packages/pygments/lexers/clean.py": 17772169928835025327,
- "frontend/build/_app/immutable/chunks/DsxtPyvP.js": 3746126985395053120,
- "backend/src/plugins/translate/__tests__/test_dictionary_crud.py": 2458404726842277862,
- "venv/lib/python3.13/site-packages/websockets/__init__.py": 4916307256304054040,
- "venv/lib/python3.13/site-packages/pandas/tests/series/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_editable.py": 12494407279914732338,
- "venv/lib/python3.13/site-packages/fastapi/temp_pydantic_v1_params.py": 9436036880518047720,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_object_arr.py": 4725156416161661681,
- "venv/lib/python3.13/site-packages/pygments/lexers/foxpro.py": 14032656072384708293,
- "venv/lib/python3.13/site-packages/gitdb/__init__.py": 15381521749253695923,
- "venv/lib/python3.13/site-packages/greenlet/slp_platformselect.h": 10428201768098464386,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_msvc.h": 14580207065003376324,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.pyi": 5973671421648618563,
- "venv/lib/python3.13/site-packages/pygments/lexers/go.py": 11118104397271513417,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_take.py": 3281943380342853080,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_methods.py": 14881910898871057761,
- "venv/lib/python3.13/site-packages/PIL/CurImagePlugin.py": 17697303205012181529,
- "frontend/build/_app/immutable/chunks/CrLU7zQO.js": 14265962769345069959,
- "venv/lib/python3.13/site-packages/numpy/random/__init__.pxd": 7355772669172093814,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_interaction.py": 12216477658994324787,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_indexing.py": 1947969642791009285,
- "venv/lib/python3.13/site-packages/pandas/_libs/writers.cpython-313-x86_64-linux-gnu.so": 6878855127769203372,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/boxplot.py": 7090586111222952862,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/__init__.py": 9884041726796476720,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/rule.py": 5318344538761246105,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ciphers.pyi": 18143251582901996072,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_array_from_pyobj.py": 9596224861290975079,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunclike.pyi": 12215374902556647369,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_freq_attr.py": 7685756734926749093,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_hour.py": 14128508606361694814,
- "venv/lib/python3.13/site-packages/keyring/backend_complete.zsh": 14339032329370660432,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/ecdsa/ssh.py": 17010933326090778158,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/putmask.py": 10934101690788549526,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_pickle.py": 6232650893735715362,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_regression.py": 4611768764484593979,
- "venv/lib/python3.13/site-packages/pygments/lexers/tal.py": 447505725492547461,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_api.py": 5813060676255093777,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nth.py": 17151595277666975085,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_extension_array_equal.py": 16119106336497630796,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_array.py": 12514884344165043136,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE": 9584102918819171104,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_shares_memory.py": 2911029123657970431,
- "venv/lib/python3.13/site-packages/gitdb/db/ref.py": 1176701624460337371,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/factory.py": 3042005457138956499,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/METADATA": 12295263493152296681,
- "venv/lib/python3.13/site-packages/fastapi/logger.py": 11590581556317053213,
- "venv/lib/python3.13/site-packages/pandas/core/internals/blocks.py": 6448406236246476333,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_time_grouper.py": 3203729024111501071,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_hist_box_by.py": 16197297231683144299,
- "frontend/src/routes/reports/+page.svelte": 18404964858248487921,
- "frontend/src/routes/dashboards/[id]/+page.svelte": 4275945584687045315,
- "backend/tests/core/migration/test_archive_parser.py": 8027202509785909637,
- "venv/lib/python3.13/site-packages/pydantic/env_settings.py": 18250976255197243083,
- "frontend/playwright-report/trace/codeMirrorModule.DYBRYzYX.css": 14866915564324637173,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/prepare.py": 13514839972066861359,
- "venv/lib/python3.13/site-packages/websockets/legacy/exceptions.py": 16025779645869134942,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_pickle.py": 16196792378104396231,
- "backend/src/models/mapping.py": 10572260229324193085,
- "venv/lib/python3.13/site-packages/PIL/TiffImagePlugin.py": 6845043550424565106,
- "backend/src/api/routes/admin_api_keys.py": 488294242540518616,
- "backend/src/services/clean_release/audit_service.py": 13892224612412540989,
- "venv/lib/python3.13/site-packages/numpy/_pytesttester.pyi": 5750506937526308405,
- "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_config.py": 3636377988901907424,
- "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs.py": 15657897994221955882,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_freq_attr.py": 1720704043778272895,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_coercion.py": 3339075591248270762,
- "venv/lib/python3.13/site-packages/click/__init__.py": 9261629899056870564,
- "venv/lib/python3.13/site-packages/pluggy/__init__.py": 8269188363563356631,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/RECORD": 3617343778671172258,
- "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/WHEEL": 1598805043198466373,
- "venv/lib/python3.13/site-packages/_pytest/terminalprogress.py": 5490989904517343259,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dtype.py": 5553691086633215767,
- "venv/lib/python3.13/site-packages/PIL/_deprecate.py": 15076725072094847812,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_fillna.py": 7349777469648334282,
- "venv/lib/python3.13/site-packages/pygments/lexers/jmespath.py": 7426464251945393925,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcom_err-2abe824b.so.2.1": 12870528025628871295,
- "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/METADATA": 15888766579203341778,
- "venv/lib/python3.13/site-packages/pandas/_libs/internals.cpython-313-x86_64-linux-gnu.so": 2008633361686956377,
- "venv/lib/python3.13/site-packages/rapidfuzz/_common_py.py": 15410157970973169427,
- "venv/lib/python3.13/site-packages/multipart/multipart.py": 26386459953377432,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_utils.py": 8668650648802195016,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_constructors.py": 17392287676196409733,
- "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.py": 338595621218646492,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py": 16768579082462294745,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_gc.py": 6383305344377882524,
- "frontend/src/components/git/GitManager.svelte": 12767660311913624739,
- "backend/src/core/task_manager/models.py": 11636421249104836957,
- "backend/src/api/routes/translate/_run_list_routes.py": 11620203305409913352,
- "venv/lib/python3.13/site-packages/pycparser/c_generator.py": 14922277346364091122,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/interval.py": 17965911911189276907,
- "venv/lib/python3.13/site-packages/pandas/core/internals/managers.py": 13547912653290063698,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/loading.py": 3460142472461437916,
- "backend/git_repos/remote/test-repo.git/hooks/pre-push.sample": 8029776382195911768,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/framework_integration.py": 3935346152156572025,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_datetime.py": 11417836378782978454,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_comment.py": 5603075924832933306,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/__init__.py": 11808051681178127650,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/RECORD": 8104089156015954779,
- "venv/lib/python3.13/site-packages/starlette/middleware/trustedhost.py": 8302185291610019926,
- "venv/lib/python3.13/site-packages/pygments/lexers/hexdump.py": 10665271113239513484,
- "venv/lib/python3.13/site-packages/cffi/__init__.py": 13427266446746498548,
- "venv/lib/python3.13/site-packages/git/index/typ.py": 11661540784850363024,
- "venv/lib/python3.13/site-packages/websockets/sync/utils.py": 15135020989207191168,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_pick.py": 15760492005471315814,
- "venv/lib/python3.13/site-packages/cryptography/exceptions.py": 5173540025160237758,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_setops.py": 14246225281428284850,
- "venv/lib/python3.13/site-packages/websockets/asyncio/client.py": 5694225754072131767,
- "venv/lib/python3.13/site-packages/pandas/core/window/ewm.py": 12143982379243011357,
- "venv/lib/python3.13/site-packages/rapidfuzz/__init__.pyi": 13131938031654453415,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/wheel.py": 828222664427570058,
- "run.sh": 16549488891429944178,
- "venv/lib/python3.13/site-packages/attr/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/padding.py": 11244071766694094554,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_longdouble.py": 9337218715436213122,
- "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_transform.py": 6759417099641034692,
- "venv/lib/python3.13/site-packages/pygments/formatters/other.py": 13124903290103898118,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/getlimits.pyi": 93747984191461691,
- "frontend/src/routes/datasets/__tests__/DatasetPreview.test.js": 12281160027416292128,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_dst.py": 12243642467695371088,
- "venv/lib/python3.13/site-packages/pygments/lexers/_googlesql_builtins.py": 12251289884604745945,
- "frontend/src/components/MissingMappingModal.svelte": 14222261650100098814,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/base.py": 5924592154431932923,
- "venv/lib/python3.13/site-packages/anyio/pytest_plugin.py": 4165280709813718099,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/compiler.py": 11662494978292401568,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py": 13763154154862871596,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_astype.py": 4023134352880775277,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90": 5518911932373565642,
- "backend/src/plugins/translate/_batch_sizer.py": 1521118320045674063,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/authorization_code.py": 4958605540994687737,
- "backend/src/services/clean_release/enums.py": 5838176998590033780,
- "backend/src/services/git/_url.py": 11387722385592868210,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/ecdsa/test_ellipticcurve.py": 11125783981574901613,
- "venv/lib/python3.13/site-packages/anyio/to_process.py": 16627578499791368365,
- "venv/lib/python3.13/site-packages/pydantic/v1/networks.py": 13262073155118055511,
- "venv/lib/python3.13/site-packages/numpy/_core/lib/libnpymath.a": 17555816778997028283,
- "venv/lib/python3.13/site-packages/passlib/crypto/_md4.py": 379335134151814809,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_function_base.py": 16624804022675533740,
- "venv/lib/python3.13/site-packages/pandas/core/internals/construction.py": 893951849732478990,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_map.py": 32086858815359344,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_assign.py": 2647902466315482406,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_fillna.py": 8802093795040069423,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_convert.py": 17957207974799052653,
- "venv/lib/python3.13/site-packages/PIL/ImageOps.py": 3884310863548175682,
- "venv/lib/python3.13/site-packages/numpy/__init__.cython-30.pxd": 1476688171642957054,
- "venv/lib/python3.13/site-packages/numpy/lib/__init__.py": 12211229657513986410,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/PIL/SgiImagePlugin.py": 6916200065790425497,
- "venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py": 4418971149260853240,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_empty.py": 13006241382741353569,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_stack.py": 5316826578695144945,
- "venv/lib/python3.13/site-packages/pandas/io/orc.py": 12754290195886557668,
- "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/git/__init__.py": 15867730798565725003,
- "frontend/src/lib/utils.js": 2362133402815996206,
- "frontend/src/components/llm/__tests__/provider_config.integration.test.js": 2807487384272452401,
- "backend/src/api/routes/validation.py": 13836068409484617547,
- "backend/src/services/notifications/service.py": 3120728755335117444,
- "backend/src/services/clean_release/repositories/policy_repository.py": 9074701224814573817,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_unix.h": 13709837360414450184,
- "venv/lib/python3.13/site-packages/pip/_internal/distributions/sdist.py": 9490366272695301385,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_non_compound.f90": 8048650253889213460,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/test_period_index.py": 6634414375581820058,
- "venv/lib/python3.13/site-packages/PIL/_version.py": 3025206805667405876,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/array_api_info.pyi": 7887489694871300469,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authorization_server.py": 13696038495666024258,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libgssapi_krb5-497db0c6.so.2.2": 6199424505696679197,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_pct_change.py": 18056235438452125034,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_misc.py": 16393451200513733144,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_cross.py": 17742712348672218852,
- "venv/lib/python3.13/site-packages/ecdsa/_rwlock.py": 7971972922423146201,
- "venv/lib/python3.13/site-packages/h11/_version.py": 9334144031400715479,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_formats.py": 18080627205081311773,
- "venv/lib/python3.13/site-packages/git/exc.py": 14278238357119816365,
- "venv/lib/python3.13/site-packages/pygments/lexers/modeling.py": 15714077241620129689,
- "backend/src/plugins/translate/orchestrator_planner.py": 16598342286617456459,
- "backend/tests/services/clean_release/test_publication_service.py": 12656754025482108211,
- "venv/lib/python3.13/site-packages/apscheduler/schedulers/__init__.py": 16211693040174992594,
- "venv/lib/python3.13/site-packages/pygments/lexers/promql.py": 8929925488296216854,
- "venv/lib/python3.13/site-packages/pandas/core/methods/to_dict.py": 4653628436393663485,
- "venv/lib/python3.13/site-packages/rsa/parallel.py": 4968566722541778371,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqlconnector.py": 17538029557373507617,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/__init__.py": 1923528231486706442,
- "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/sync_openid.py": 5670082466989878756,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_array.py": 16867692337986161626,
- "venv/lib/python3.13/site-packages/pip/_internal/distributions/installed.py": 18153165899841229597,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/groupby.py": 12749730954888633240,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_parse_dates.py": 7597935994945336408,
- "venv/lib/python3.13/site-packages/pygments/formatters/bbcode.py": 8614391937525677922,
- "venv/lib/python3.13/site-packages/greenlet/platform/setup_switch_x64_masm.cmd": 8473866644286785815,
- "backend/alembic/versions/9f8e7d6c5b4a_add_is_multimodal_to_llm_providers.py": 11090205342799426943,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/ops.py": 2036968385544457016,
- "frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js": 8659643137288661057,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/functions.py": 16567226076808693246,
- "venv/lib/python3.13/site-packages/pandas/errors/cow.py": 14381282473643980776,
- "venv/lib/python3.13/site-packages/jsonschema/_utils.py": 14237077105384631097,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/test_support.pyi": 3893434234020223151,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers.py": 4940305787631493030,
- "venv/lib/python3.13/site-packages/pydantic/experimental/pipeline.py": 9493054841465227788,
- "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/keyring/backends/macOS/__init__.py": 1010937986753403630,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_user_array.py": 8711697474193296376,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/accessor.py": 8373575175447947401,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop_duplicates.py": 2397396876872403048,
- "venv/lib/python3.13/site-packages/rsa/util.py": 13423880475585138638,
- "venv/lib/python3.13/site-packages/pip/_internal/self_outdated_check.py": 991029278889407558,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_nlargest.py": 1423106021399469694,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dtypes.py": 4985057130807802395,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/io/json/_table_schema.py": 3103776773020058805,
- "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/WHEEL": 16784970174376303810,
- "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js": 3080911695504204499,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslib.cpython-313-x86_64-linux-gnu.so": 10742615805788605480,
- "venv/lib/python3.13/site-packages/iniconfig/py.typed": 15130871412783076140,
- "frontend/build/_app/immutable/chunks/DDT5MMTm.js": 14618179099689778175,
- "venv/lib/python3.13/site-packages/pandas/core/computation/engines.py": 1889823242704769952,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_normalize.py": 7378656958631172603,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_orc.py": 1248059610437937895,
- "venv/lib/python3.13/site-packages/pygments/lexers/futhark.py": 10102535873433759899,
- "backend/git_repos/remote/test-repo.git/objects/aa/ea042a37c6f7bd010d91db93951328da7f01cc": 11936716919619613939,
- "venv/lib/python3.13/site-packages/pygments/lexers/_cocoa_builtins.py": 15468347167912293394,
- "frontend/src/components/tasks/TaskLogPanel.svelte": 10382066588776421689,
- "venv/lib/python3.13/site-packages/_pytest/reports.py": 13930709338396699351,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_exceptions.py": 15290185665769490169,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/__init__.py": 15735839022111230173,
- "venv/lib/python3.13/site-packages/pandas/tests/libs/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/PIL/TarIO.py": 13651401276968618561,
- "venv/lib/python3.13/site-packages/PIL/PdfImagePlugin.py": 16082854250442815862,
- "venv/lib/python3.13/site-packages/multipart/decoders.py": 11346752866822986212,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/oracledb.py": 7158791242292470472,
- "venv/lib/python3.13/site-packages/urllib3/util/__init__.py": 2848870790459558599,
- "backend/src/plugins/translate/service_datasource.py": 10240814407336170041,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_period.py": 7727606662611927293,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_validate.py": 2133732492454460539,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_month.py": 14597470286884431085,
- "venv/lib/python3.13/site-packages/httpx/_utils.py": 4836536051177895209,
- "venv/lib/python3.13/site-packages/pip/_internal/vcs/git.py": 17060377178521307324,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_bindgen.py": 8637878018232418583,
- "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/WHEEL": 691462085217888236,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/file_proxy.py": 17695135735211897444,
- "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/integration.py": 3085827906490477329,
- "venv/lib/python3.13/site-packages/pandas/core/generic.py": 10174952306641057447,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/integration.py": 12670848015915724967,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_dropna.py": 3168969662216766293,
- "venv/lib/python3.13/site-packages/pandas/compat/_optional.py": 12714208019736797073,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_doc.py": 7865575374100528149,
- "venv/lib/python3.13/site-packages/referencing/retrieval.py": 11921179805977833120,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tolist.py": 8343058000369672317,
- "venv/lib/python3.13/site-packages/authlib/oidc/registration/__init__.py": 9448552677419908109,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_indexing.py": 1926721846569184112,
- "venv/lib/python3.13/site-packages/pandas/tests/test_optional_dependency.py": 7930709646653025355,
- "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/WHEEL": 9100692507274722091,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/WHEEL": 14550174241288068152,
- "venv/lib/python3.13/site-packages/click/globals.py": 18353671282454331523,
- "venv/lib/python3.13/site-packages/apscheduler/job.py": 1858376671986108667,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.pyi": 8571452382806614924,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_attr_equal.py": 5612259834202470413,
- "venv/lib/python3.13/site-packages/pygments/lexers/forth.py": 17623561228839319663,
- "venv/lib/python3.13/site-packages/pip/_internal/index/package_finder.py": 12631116673181479779,
- "backend/src/scripts/clean_release_cli.py": 777127038463156812,
- "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.pyi": 2667658052734929089,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/zookeeper.py": 4318643109309626098,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8693/__init__.py": 11065844267208884531,
- "venv/lib/python3.13/site-packages/psycopg2/pool.py": 8855184580138330938,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_replace.py": 8166203537440976347,
- "venv/lib/python3.13/site-packages/anyio/_core/_asyncio_selector_thread.py": 1760597191437520000,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_contains.py": 5273759677032634868,
- "venv/lib/python3.13/site-packages/typing_extensions.py": 8402965285733247527,
- "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.pyi": 2186875333484796630,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_compat.h": 6512969159139431485,
- "venv/lib/python3.13/site-packages/pygments/styles/tango.py": 12389250878249075539,
- "backend/src/services/clean_release/repositories/candidate_repository.py": 1901083195512401226,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_replace.py": 4953527309376861139,
- "venv/lib/python3.13/site-packages/pip/_internal/network/xmlrpc.py": 5064964778750366059,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/profiling.py": 16030397164203895281,
- "backend/src/services/validation_run_service.py": 5527352359336135164,
- "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.pyi": 5892973170789971535,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/utils.h": 3920393832993063886,
- "venv/lib/python3.13/site-packages/jsonschema/tests/_suite.py": 6307666366417438489,
- "venv/lib/python3.13/site-packages/pandas/_testing/contexts.py": 11714205921752896137,
- "backend/src/plugins/translate/__tests__/test_sql_generator.py": 7990788832878981127,
- "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/RECORD": 9678861487447993169,
- "venv/lib/python3.13/site-packages/PIL/_imaging.pyi": 17119084207765761921,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_envs.py": 5657151394155576509,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-1.csv": 16349400027062875699,
- "backend/src/core/__tests__/test_superset_profile_lookup.py": 12374214375171590188,
- "venv/lib/python3.13/site-packages/apscheduler/jobstores/rethinkdb.py": 16413299263077970925,
- "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_util.py": 13997184496924925110,
- "venv/lib/python3.13/site-packages/pandas/_libs/parsers.pyi": 18402185996588014111,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_client/apps.py": 14151733532064278336,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows_renderer.py": 1076842273781909680,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_isoc.py": 4923640657296076239,
- "venv/lib/python3.13/site-packages/pandas/tests/reductions/__init__.py": 16150188643076000414,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/client_credentials.py": 256154392957334831,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_constructors.py": 2786493777737472376,
- "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/licenses/LICENSE": 3509878235770224233,
- "backend/src/api/routes/__tests__/test_git_status_route.py": 4501452711469218555,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/meson.build": 9642189398934130247,
- "venv/lib/python3.13/site-packages/pygments/lexers/arrow.py": 6699009974224818979,
- "venv/lib/python3.13/site-packages/pyasn1/type/__init__.py": 15728752901274520502,
- "venv/lib/python3.13/site-packages/PIL/GimpPaletteFile.py": 2040459799887417392,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libldap-2974a1ba.so.2.0.200": 13590569080612602445,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/registry.py": 13306388361671753373,
- "venv/lib/python3.13/site-packages/pydantic/v1/parse.py": 5875950480538559709,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_dataframe.py": 14945138617962156057,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/objective.py": 10966124906622044512,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/__init__.py": 15130871412783076140,
- "frontend/build/_app/immutable/assets/0.C35F__rI.css": 18367119336440743976,
- "backend/src/core/migration/dry_run_orchestrator.py": 1628125044585364194,
- "venv/lib/python3.13/site-packages/attr/exceptions.py": 11532465891810816417,
- "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/RECORD": 10264342250058307301,
- "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD": 3288669175908898843,
- "venv/lib/python3.13/site-packages/pillow.libs/libwebpdemux-747f2b49.so.2.0.17": 7615380692384566654,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/einsumfunc.pyi": 8902765738896588686,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_str_accessor.py": 4066094997616994612,
- "venv/lib/python3.13/site-packages/fastapi/staticfiles.py": 4094330072433302614,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/request.py": 10484280068366411541,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_compound.f90": 15012692484070385863,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_conversion.py": 7507083194555424923,
- "venv/lib/python3.13/site-packages/pandas/io/formats/style.py": 13235403689320479165,
- "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/response.py": 9594165377270752433,
- "venv/lib/python3.13/site-packages/ecdsa/test_curves.py": 6577762025900435885,
- "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/METADATA": 15658158392301945427,
- "frontend/build/_app/immutable/chunks/DSCvrbNj.js": 7995659532253982919,
- "venv/lib/python3.13/site-packages/numpy/_core/getlimits.py": 7842717073693731093,
- "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/RECORD": 9461427699726982537,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunc_config.py": 14728417910466146460,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dtype.py": 5336980126536664360,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_rank.py": 5398520257852104723,
- "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/WHEEL": 18203500019759199992,
- "venv/lib/python3.13/site-packages/numpy/core/overrides.pyi": 1968648615494204783,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/jws_eddsa.py": 833927568269372333,
- "venv/lib/python3.13/site-packages/urllib3/_request_methods.py": 13671055114247516883,
- "frontend/src/routes/datasets/review/[id]/__tests__/dataset_review_workspace.ux.test.js": 14106200953934418963,
- "backend/src/core/__tests__/test_native_filters.py": 3389712167015600870,
- "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.pyi": 2104100025130695295,
- "venv/lib/python3.13/site-packages/httpx/_status_codes.py": 1758440600462491839,
- "backend/src/services/clean_release/__tests__/test_compliance_orchestrator.py": 15537957042757255513,
- "venv/lib/python3.13/site-packages/referencing/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/data.py": 9365024327689738663,
- "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/LICENSE": 6989336036499641077,
- "frontend/build/favicon.svg": 6451919037497541980,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/parameter.py": 2793853093222900337,
- "venv/lib/python3.13/site-packages/pandas/tests/test_take.py": 17628004130770326677,
- "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/licenses/LICENSE": 8438117004702803716,
- "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/METADATA": 13776251749114562660,
- "venv/lib/python3.13/site-packages/requests/compat.py": 5836590172733661320,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_.py": 644667973700652263,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_monotonic.py": 11817523305776951162,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_datetime.py": 7456744745424297814,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_function.py": 644452398244782315,
- "venv/lib/python3.13/site-packages/pandas/io/parsers/c_parser_wrapper.py": 5841064965672872661,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/persistence.py": 17908437937265384125,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/_internal_utils.py": 4091305333167213279,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reindex.py": 12459492712890114705,
- "venv/lib/python3.13/site-packages/pandas/tests/series/test_logical_ops.py": 4438104524064299182,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_clip.py": 11111183698178681331,
- "venv/lib/python3.13/site-packages/PIL/_imagingmorph.cpython-313-x86_64-linux-gnu.so": 11171810899664471137,
- "venv/lib/python3.13/site-packages/charset_normalizer/cli/__init__.py": 9702005609966176016,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/configuration.py": 1608697090566485893,
- "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/AUTHORS": 10073225185964928425,
- "venv/lib/python3.13/site-packages/attr/validators.py": 4453080662115911998,
- "backend/src/services/clean_release/stages/manifest_consistency.py": 5890428472425990952,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_astype.py": 7542068949396266883,
- "venv/lib/python3.13/site-packages/pandas/io/parsers/base_parser.py": 15148258424429418380,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/enumerated.py": 16623643153933348755,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi": 4376871621615688626,
- "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.pyi": 15509415708991012734,
- "venv/lib/python3.13/site-packages/pycparser/ply/ctokens.py": 1599952198962458730,
- "venv/lib/python3.13/site-packages/pip/_vendor/pkg_resources/__init__.py": 1677532855362260338,
- "venv/lib/python3.13/site-packages/anyio/streams/stapled.py": 9733127303038397237,
- "venv/lib/python3.13/site-packages/requests/packages.py": 7733041271118298220,
- "venv/lib/python3.13/site-packages/authlib/__init__.py": 8957417237987377675,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/binding.py": 17078280153372356796,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi": 11733449165276720901,
- "venv/lib/python3.13/site-packages/pygments/styles/inkpot.py": 10516710471319090846,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/resources.py": 11533706401259147051,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/__init__.py": 13584649922093198724,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/reporter.py": 6510864297510700136,
- "frontend/src/routes/datasets/__tests__/ColumnsTable.test.js": 15883951776898228284,
- "backend/src/plugins/translate/service.py": 10736582646810451588,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/licenses/LICENSE": 12688029424398428498,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py": 17873236864291624476,
- "venv/lib/python3.13/site-packages/anyio/_core/_synchronization.py": 7050001375718876608,
- "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.pyi": 13945478633722616250,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_amd64_unix.h": 16679226724722970205,
- "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/WHEEL": 7454950858448014158,
- "backend/src/plugins/translate/executor.py": 1010039663690969371,
- "venv/lib/python3.13/site-packages/ecdsa/test_ecdh.py": 3338834550392548171,
- "venv/lib/python3.13/site-packages/fastapi/types.py": 3867821246650502267,
- "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.py": 16859854811012717088,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/config.py": 10707678943298497676,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/__init__.py": 16146480198665866916,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tanh.csv": 6674536825156196036,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix_py.py": 17041764258638228993,
- "venv/lib/python3.13/site-packages/pygments/lexers/tlb.py": 1169242051301155885,
- "venv/lib/python3.13/site-packages/greenlet/TExceptionState.cpp": 17617354576371846109,
- "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/WHEEL": 5838667082726674838,
- "venv/lib/python3.13/site-packages/rsa/transform.py": 12261738253972114335,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_array_utils.py": 14682148205379122638,
- "venv/lib/python3.13/site-packages/referencing/tests/test_jsonschema.py": 9815500901482570619,
- "venv/lib/python3.13/site-packages/pygments/lexers/email.py": 4355246279485460399,
- "backend/src/core/auth/__init__.py": 16435384828055133073,
- "venv/lib/python3.13/site-packages/ecdsa/keys.py": 10281170640484982154,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/assignOnlyModule.f90": 15967199601254912096,
- "venv/lib/python3.13/site-packages/pygments/lexers/asc.py": 10744437946030875496,
- "frontend/build/_app/immutable/chunks/aNI39KyB.js": 1756469162576383723,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.pyf": 4660465266594480405,
- "venv/lib/python3.13/site-packages/idna/intranges.py": 12536174834761591006,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_loc.py": 2127584756555503873,
- "venv/lib/python3.13/site-packages/pandas/tests/config/test_config.py": 4630144191929135452,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi": 14119032813912827271,
- "venv/lib/python3.13/site-packages/numpy/_core/numeric.py": 12261531924304979741,
- "venv/lib/python3.13/site-packages/rpds/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/api/extensions/__init__.py": 882327406374020760,
- "venv/lib/python3.13/site-packages/PIL/McIdasImagePlugin.py": 14137545069906812251,
- "backend/test_pat_api.py": 4206656943734821967,
- "venv/lib/python3.13/site-packages/pip/__pip-runner__.py": 1138979712722199296,
- "venv/lib/python3.13/site-packages/cffi/vengine_cpy.py": 10684192171370688079,
- "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/__init__.py": 1798074863773727377,
- "venv/lib/python3.13/site-packages/requests/exceptions.py": 6474239743209354989,
- "venv/lib/python3.13/site-packages/requests/adapters.py": 17161109043243436200,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/token.py": 4161760290367932793,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_cisco.py": 1786475632318043669,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/groupby.py": 14661033005768429774,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/base.py": 10200916670889920659,
- "venv/lib/python3.13/site-packages/numpy/random/tests/test_seed_sequence.py": 7687465232954593311,
- "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/RECORD": 10036839994791510159,
- "frontend/src/routes/settings/__tests__/settings_page.integration.test.js": 4898515600493251972,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_groupby.py": 15721254196883995634,
- "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/WHEEL": 7145482834744213753,
- "venv/lib/python3.13/site-packages/attr/_compat.py": 4016698632899969390,
- "backend/src/plugins/translate/metrics.py": 11628699537333742678,
- "venv/lib/python3.13/site-packages/pandas/_libs/hashtable.pyi": 15034917167424979097,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/multiarray.pyi": 6368268452184570195,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_shift.py": 8547819448301023303,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_ops.py": 14420421526781215500,
- "venv/lib/python3.13/site-packages/cffi/setuptools_ext.py": 30796527302561458,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_table.tpl": 8706980975714184465,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/use_data.f90": 14624074967635860696,
- "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/METADATA": 3786116428839780263,
- "venv/lib/python3.13/site-packages/pygments/lexers/haxe.py": 1915270891525929751,
- "venv/lib/python3.13/site-packages/pygments/lexers/qvt.py": 1895735583818227972,
- "venv/lib/python3.13/site-packages/numpy/lib/_version.py": 15294708923334674060,
- "venv/lib/python3.13/site-packages/numpy/f2py/f2py2e.py": 738588649412338185,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/__init__.py": 8558541715982163200,
- "venv/lib/python3.13/site-packages/passlib/apache.py": 2357244937629445006,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/conftest.py": 15090201792072045503,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge.py": 11366935134260232329,
- "venv/lib/python3.13/site-packages/PIL/_typing.py": 17407980360703360848,
- "backend/tests/core/test_mapping_service.py": 14025593540151022064,
- "venv/lib/python3.13/site-packages/psycopg2/errors.py": 10441360078612452560,
- "venv/lib/python3.13/site-packages/numpy/_utils/_inspect.py": 7029935879540617057,
- "venv/lib/python3.13/site-packages/pygments/styles/borland.py": 17570558758932580659,
- "frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte": 6548767763019176627,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/__init__.py": 15130871412783076140,
- "frontend/src/lib/api/maintenance.js": 16247720324991780393,
- "backend/src/core/auth/security.py": 11836436636390315707,
- "venv/lib/python3.13/site-packages/PIL/ImageMath.py": 7395449734007598797,
- "venv/lib/python3.13/site-packages/gitdb/exc.py": 13975852664048821278,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/terminal_theme.py": 13727399800263579809,
- "backend/src/core/task_manager/__tests__/test_context.py": 9922342013893651977,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema.py": 14454690938977069049,
- "backend/src/plugins/translate/_batch_insert.py": 12482635271028646257,
- "venv/bin/uvicorn": 3776670267111625708,
- "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pyi": 15790738442952696034,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_inf.py": 8659210689723088321,
- "backend/src/core/task_manager/cleanup.py": 13007785075566443785,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py": 7624316342162916928,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/test_isfile.py": 14544060093268573418,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/errors.py": 12935154705443176852,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token_validator.py": 2932866595454490527,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/socks.py": 17581293673028078134,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatter.py": 16499277113779414101,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_any_index.py": 10800968419286329268,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/baked.py": 6911138208603240867,
- "venv/lib/python3.13/site-packages/pygments/styles/gruvbox.py": 9489017112545247388,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/_elements_constructors.py": 9279447066034364952,
- "venv/lib/python3.13/site-packages/pandas/tests/copy_view/util.py": 9373891872370603585,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test__iotools.py": 6260912730310453037,
- "frontend/src/components/TaskLogViewer.svelte": 15158021998452088463,
- "backend/src/api/routes/environments.py": 6175447476823722833,
- "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.pyi": 8708830448398500675,
- "venv/lib/python3.13/site-packages/pluggy/_callers.py": 1042673447718196223,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_mangle_dupes.py": 15613858733226279352,
- "backend/src/core/migration/__init__.py": 13075189211840127611,
- "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/utils.py": 7707707044867513457,
- "backend/src/services/clean_release/candidate_service.py": 7591584088002954798,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/merge.py": 300205528811693975,
- "venv/lib/python3.13/site-packages/starlette/config.py": 16509394679506300256,
- "venv/lib/python3.13/site-packages/PIL/features.py": 3481835375516797487,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/orm.py": 7554417559838785150,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/abc.py": 6227782083136374888,
- "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.pyi": 8195943561787777127,
- "venv/lib/python3.13/site-packages/packaging/licenses/_spdx.py": 16440031845441362300,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_latex.py": 2628895559914914693,
- "venv/lib/python3.13/site-packages/sqlalchemy/types.py": 15819795572817819102,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/token.py": 6987328478153445584,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/pickleable.py": 7712040860601343075,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_float.py": 10455718110956856820,
- "venv/lib/python3.13/site-packages/anyio/streams/buffered.py": 8916188172110578587,
- "venv/lib/python3.13/site-packages/PIL/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_libs/ops.cpython-313-x86_64-linux-gnu.so": 10490009128553397250,
- "venv/lib/python3.13/site-packages/_pytest/capture.py": 17850967053989495422,
- "venv/lib/python3.13/site-packages/pandas/tests/test_flags.py": 411845322592830527,
- "venv/lib/python3.13/site-packages/sqlalchemy/exc.py": 6372950288664776625,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/x509.pyi": 17458894097215345719,
- "backend/src/models/translate.py": 15158235523537226249,
- "venv/lib/python3.13/site-packages/pyasn1/codec/der/encoder.py": 4790267438222037867,
- "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/base.py": 15872835330892203433,
- "backend/src/api/routes/dashboards/_action_routes.py": 7104158712389299932,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/liblber-1c9097e2.so.2.0.200": 2651879839738900594,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/progress_bar.py": 15595912766961891283,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.cpython-313-x86_64-linux-gnu.so": 1137453907225619959,
- "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/pandas/core/_numba/executor.py": 2205130934861422769,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_update.py": 9098258267671647783,
- "venv/lib/python3.13/site-packages/numpy/_configtool.pyi": 9670892208858157218,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_matplotlib.py": 12775850858284584296,
- "venv/lib/python3.13/site-packages/pygments/lexers/_sourcemod_builtins.py": 11809503654078535014,
- "frontend/playwright-report/data/dcf41bdb395adaf70707a711375fd3b464dd384f.webm": 3819814233647777883,
- "venv/lib/python3.13/site-packages/git/objects/util.py": 691018806932355307,
- "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/__init__.py": 1229691061011958769,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py": 3369246520501764730,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_julian_date.py": 6868080396693831272,
- "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.py": 13446184230476677032,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/aead.py": 8740476942925346444,
- "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/aws.py": 1364297790170663941,
- "venv/lib/python3.13/site-packages/numpy/random/_generator.pyi": 17167649524261942483,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_truncate.py": 6478126371906156409,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/cx_oracle.py": 10093932131797570986,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_parse_dates.py": 5344929031479212951,
- "frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js": 1873684170678703500,
- "venv/lib/python3.13/site-packages/yaml/composer.py": 13619070314468518566,
- "frontend/src/lib/components/translate/TranslationRunProgress.svelte": 12659537213220151902,
- "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA": 14158024963562115116,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_thread_support.hpp": 7773996382104849037,
- "venv/lib/python3.13/site-packages/_pytest/assertion/__init__.py": 16392348866405910618,
- "venv/lib/python3.13/site-packages/greenlet/tests/leakcheck.py": 10179165748538820557,
- "venv/lib/python3.13/site-packages/pygments/lexers/webidl.py": 8097260111959278117,
- "frontend/playwright-report/trace/codicon.DCmgc-ay.ttf": 15579197054804464248,
- "venv/lib/python3.13/site-packages/PIL/_imagingtk.cpython-313-x86_64-linux-gnu.so": 1708198947135304326,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_ratio.py": 940213488194452623,
- "venv/lib/python3.13/site-packages/passlib/handlers/oracle.py": 12959175637015399815,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi": 8666343427862784832,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286_bc.pyf": 10893958728966010450,
- "frontend/src/routes/translate/history/+page.svelte": 9504117584329454876,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_dists.py": 16746363359320577809,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_isin.py": 11330491145602008796,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/modules.pyi": 131293606732000587,
- "venv/lib/python3.13/site-packages/dotenv/py.typed": 9796674040111366709,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_polynomial.pyi": 4266795948450921502,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_datetimelike.py": 15246580603900811749,
- "venv/lib/python3.13/site-packages/pandas/core/internals/concat.py": 12151675567885981464,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_getitem.py": 11882213323878588707,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/base.py": 6348888156686452825,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/multiarray.pyi": 17232959648651278910,
- "venv/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py": 13206297306768491360,
- "backend/src/services/dataset_review/event_logger.py": 8944052747593678117,
- "backend/git_repos/remote/test-repo.git/objects/22/91d2eb86d77accf7401f8952778809cd1aa4d4": 5120428041118096941,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_parquet.py": 11050150015772440923,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/utils.py": 11401792151107207834,
- "venv/lib/python3.13/site-packages/_pytest/config/exceptions.py": 3199245296954654462,
- "venv/lib/python3.13/site-packages/numpy/f2py/__version__.py": 8588600299261398598,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_loop.py": 6502725909989655118,
- "frontend/src/routes/datasets/review/+page.svelte": 8512810578824138490,
- "dist/docker/frontend.0.1.0.tar.xz": 16011357094675100098,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_ndarray_backed.py": 10097812802469682233,
- "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_utils.py": 2329717399120006435,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-313-x86_64-linux-gnu.so": 7490281502544276964,
- "venv/lib/python3.13/site-packages/pandas/core/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_index_as_string.py": 13421551616136437100,
- "venv/lib/python3.13/site-packages/starlette/datastructures.py": 12097180838087229563,
- "venv/lib/python3.13/site-packages/urllib3/filepost.py": 3814725067598042920,
- "venv/lib/python3.13/site-packages/pygments/lexers/_stan_builtins.py": 1961875544235948177,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_core_metadata.py": 5704137311404303574,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90": 8821492401453445757,
- "venv/lib/python3.13/site-packages/pygments/lexers/scripting.py": 4167168074165473790,
- "venv/lib/python3.13/site-packages/pandas/core/ops/common.py": 17314999825118928100,
- "frontend/playwright-report/trace/manifest.webmanifest": 565917384317025203,
- "frontend/src/lib/i18n/index.ts": 14616557360624297847,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polynomial.py": 777287409151500309,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_cython_aggregations.py": 10818895573637904764,
- "venv/lib/python3.13/site-packages/numpy/f2py/rules.pyi": 1342380029484127983,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_repeat.py": 9155935990114743583,
- "venv/lib/python3.13/site-packages/pygments/lexers/urbi.py": 1611762607688882372,
- "venv/lib/python3.13/site-packages/numpy/f2py/__version__.pyi": 9759534743796867731,
- "venv/lib/python3.13/site-packages/_pytest/config/argparsing.py": 11156052029258891503,
- "venv/lib/python3.13/site-packages/httpcore/_ssl.py": 6665087294869504820,
- "venv/lib/python3.13/site-packages/pycparser/ply/yacc.py": 4218889705926129841,
- "venv/lib/python3.13/site-packages/pandas/io/stata.py": 14370692318835340323,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/content": 16257335642847993866,
- "venv/lib/python3.13/site-packages/PIL/_imagingcms.pyi": 12476347428820346383,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/emath.pyi": 3718540478840842664,
- "venv/lib/python3.13/site-packages/pygments/lexers/pointless.py": 17552020039609007881,
- "frontend/build/_app/immutable/nodes/0.CWnMmjSc.js": 10108377383693638092,
- "venv/lib/python3.13/site-packages/pip/_internal/distributions/__init__.py": 1343779312297539596,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/numba/extending.py": 16515485226251040454,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/timedeltas.py": 7318851108932357510,
- "venv/lib/python3.13/site-packages/pandas/core/array_algos/datetimelike_accumulations.py": 14719894187829729175,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_old_base.py": 191359377446257900,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/models.py": 17356033861792227817,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/foo_deps.f90": 14350239197565389508,
- "frontend/src/lib/api/translate/target-schema.js": 10665479411127476571,
- "backend/src/core/encryption_key.py": 3858659138244440938,
- "backend/src/models/dataset_review_pkg/_mapping_models.py": 1407462125644004056,
- "backend/src/plugins/translate/preview_llm_client.py": 14412557858942627249,
- "venv/lib/python3.13/site-packages/websockets/datastructures.py": 5180442040351387281,
- "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/INSTALLER": 17282701611721059870,
- "frontend/e2e/helpers/api.helper.js": 12740720187461301874,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_value_counts.py": 15633881149834196174,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_npfuncs.py": 6132674295193898715,
- "venv/lib/python3.13/site-packages/pip/_internal/req/__init__.py": 12266077985828139928,
- "frontend/src/lib/components/MaintenanceEventsTable.svelte": 1697386217337210174,
- "backend/src/plugins/translate/orchestrator_aggregator.py": 1906675302571034503,
- "venv/lib/python3.13/site-packages/PIL/WebPImagePlugin.py": 5378349556563611996,
- "venv/lib/python3.13/site-packages/numpy/_core/printoptions.py": 3897105663572772838,
- "backend/src/api/routes/assistant/_admin_routes.py": 253209289619444139,
- "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/METADATA": 11759004913807981650,
- "venv/lib/python3.13/site-packages/numpy/lib/_datasource.py": 18136853038949826147,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/dtypes.py": 9839461501970023861,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_copy.py": 11335108864615756235,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/__init__.py": 14571251344510763303,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_easter.py": 3397863170068576196,
- "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA": 8128818962678047497,
- "venv/lib/python3.13/site-packages/pydantic/version.py": 3699343596421001359,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_dataclasses.py": 15256193972947054890,
- "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.pyi": 17639497083041129225,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/literal.py": 5641382379370828704,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/__init__.py": 12290228927283601067,
- "venv/lib/python3.13/site-packages/fastapi/dependencies/models.py": 8626894872248212015,
- "venv/lib/python3.13/site-packages/authlib/common/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/segment.py": 2555584120510872966,
- "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.py": 5260748170237305627,
- "venv/lib/python3.13/site-packages/_yaml/__init__.py": 3395829783751571350,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_datetimelike.py": 17304541521108700317,
- "venv/lib/python3.13/site-packages/PIL/_imagingmath.cpython-313-x86_64-linux-gnu.so": 77725273398858074,
- "venv/lib/python3.13/site-packages/pydantic_settings/version.py": 17263591404988984480,
- "venv/lib/python3.13/site-packages/pydantic/v1/utils.py": 902648247561165429,
- "venv/lib/python3.13/site-packages/numpy/_core/_operand_flag_tests.cpython-313-x86_64-linux-gnu.so": 12296711931541109624,
- "venv/lib/python3.13/site-packages/pandas/core/internals/api.py": 14632030170441237968,
- "frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte": 17593699210431624897,
- "venv/lib/python3.13/site-packages/pygments/lexers/oberon.py": 15220143799603451830,
- "frontend/build/_app/immutable/nodes/1.BHRH2YId.js": 6292738163244332451,
- "venv/lib/python3.13/site-packages/passlib/exc.py": 15559705487889657091,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_level_values.py": 12490886203425393290,
- "venv/lib/python3.13/site-packages/numpy/core/__init__.py": 10397294636564169377,
- "venv/lib/python3.13/site-packages/pip/_internal/cache.py": 210214424535803946,
- "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptodome.py": 15753279711312689193,
- "venv/lib/python3.13/site-packages/authlib/oauth2/base.py": 12948318231066662045,
- "backend/tests/test_smoke_plugins.py": 10704454611361370435,
- "venv/lib/python3.13/site-packages/pyasn1/codec/der/__init__.py": 15728752901274520502,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_setitem.py": 14920902525192671548,
- "frontend/src/components/DashboardGrid.svelte": 49663074759987369,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.pyi": 12925006572914814268,
- "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py": 12264234876933578367,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/data.f90": 13833561828029901615,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_unicode.py": 1103608932321322989,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_analytics.py": 4510712334676848202,
- "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/git/objects/tree.py": 10239027037919781330,
- "venv/lib/python3.13/site-packages/pygments/formatters/svg.py": 11686316844190214147,
- "backend/src/api/routes/storage.py": 3921659652525719249,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_conversion.pyi": 11580106670226366710,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/jwt.py": 9642615960197748105,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py": 17106903014205241774,
- "venv/lib/python3.13/site-packages/numpy/_core/_methods.py": 16805668769357938792,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_argparse.py": 11111699418217357084,
- "venv/lib/python3.13/site-packages/pygments/lexers/bare.py": 18266858932333619451,
- "venv/lib/python3.13/site-packages/pandas/tests/base/test_transpose.py": 1686867045869336370,
- "venv/lib/python3.13/site-packages/pydantic/experimental/arguments_schema.py": 8644805798814234457,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_constructors.py": 11786151805350138436,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/list/array.py": 8065856342131357421,
- "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/licenses/LICENSE.BSD": 3858254215169937333,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_formats.py": 1265319125235346745,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_mrecords.py": 15952147778503828707,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/__init__.py": 15130871412783076140,
- "backend/src/core/superset_client/_datasets_preview.py": 15457586484984946621,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/json.py": 6429651405841289922,
- "backend/src/core/superset_client/_datasets.py": 10922216252382553392,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets.py": 10923534235697247269,
- "venv/lib/python3.13/site-packages/pygments/styles/abap.py": 11543320440974964547,
- "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/LICENSE": 6581019367004699816,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/immutabledict.pyx": 11739218099400096619,
- "backend/git_repos/remote/test-repo.git/config": 14478893374498894766,
- "venv/lib/python3.13/site-packages/_pytest/python_api.py": 12953851690889336092,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/__init__.py": 6534110674636458866,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_align.py": 10284128457194204574,
- "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.pyi": 4729765666018003634,
- "frontend/playwright-report/trace/defaultSettingsView.BDKsFU3c.css": 12935551588108679759,
- "venv/lib/python3.13/site-packages/pandas/tseries/offsets.py": 13750652921710295115,
- "frontend/src/routes/validation/+page.svelte": 9845194549295283559,
- "venv/lib/python3.13/site-packages/cffi/backend_ctypes.py": 2042566833861899211,
- "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/WHEEL": 7127684561765977531,
- "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.pyi": 9854069702366900663,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/certs.py": 13366788049827102313,
- "venv/lib/python3.13/site-packages/numpy/__init__.pyi": 15820654525292895396,
- "venv/lib/python3.13/site-packages/websockets/legacy/client.py": 4032878587330592478,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_ujson.py": 12184194085993665945,
- "frontend/build/_app/immutable/chunks/B0K5kI6n.js": 6208436857520817685,
- "venv/lib/python3.13/site-packages/numpy/_typing/_shape.py": 12667553664122376205,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/http/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/constants.pyi": 15633065380510755171,
- "frontend/svelte.config.js": 8473636210766821560,
- "venv/lib/python3.13/site-packages/click/_winconsole.py": 8133229457213704188,
- "venv/lib/python3.13/site-packages/authlib/oauth2/client.py": 7237359250450222680,
- "backend/src/models/profile.py": 2482052763821027483,
- "backend/src/plugins/translate/preview_resolve_provider.py": 7349483761713339246,
- "backend/src/core/task_manager/manager.py": 1504518197419779491,
- "venv/lib/python3.13/site-packages/pygments/styles/dracula.py": 12379322008538174078,
- "venv/lib/python3.13/site-packages/pygments/lexers/_css_builtins.py": 17478340487186531268,
- "frontend/src/routes/storage/backups/+page.svelte": 8510588572169515495,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/concat.py": 2218848863149192467,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_xs.py": 1897144171324167738,
- "venv/lib/python3.13/site-packages/gitdb/const.py": 14122142034887286559,
- "backend/src/core/plugin_base.py": 5063738955101125652,
- "venv/lib/python3.13/site-packages/cryptography/__init__.py": 641702726372647770,
- "venv/lib/python3.13/site-packages/starlette/concurrency.py": 9835859079437525910,
- "venv/lib/python3.13/site-packages/pygments/styles/material.py": 14325514369696961874,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_diff.py": 7420674239386436885,
- "backend/tests/scripts/test_clean_release_cli.py": 14028295526033195944,
- "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.h": 5980733638838895780,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reflection.py": 1799734694597531652,
- "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.pyi": 15767546107856827543,
- "venv/lib/python3.13/site-packages/cffi/vengine_gen.py": 6582900613549620556,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/declarative/extensions.py": 217122171232375592,
- "venv/lib/python3.13/site-packages/fastapi/testclient.py": 2606236077497278662,
- "venv/lib/python3.13/site-packages/attrs/__init__.py": 9502968706258875910,
- "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.py": 17055498803745289016,
- "venv/lib/python3.13/site-packages/idna/uts46data.py": 5698404064763638591,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_frame.py": 2169381747938271444,
- "venv/lib/python3.13/site-packages/pygments/lexers/ul4.py": 9580182474451220952,
- "backend/src/models/assistant.py": 13943482616669949278,
- "backend/src/plugins/translate/plugin.py": 7704264206190779879,
- "venv/lib/python3.13/site-packages/pandas/api/typing/aliases.py": 11194270368147942988,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_character.py": 850554362222586199,
- "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/REQUESTED": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/python.py": 8995519134978505744,
- "venv/lib/python3.13/site-packages/pygments/lexers/wren.py": 6259586056260713984,
- "frontend/src/routes/datasets/review/[id]/+page.svelte": 3692143812318259790,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/wrapper.py": 4633931060151989960,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_real.py": 5283415082530228716,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_series_equal.py": 1223890028205011021,
- "venv/lib/python3.13/site-packages/click/termui.py": 7022374827798605437,
- "venv/lib/python3.13/site-packages/smmap/test/test_mman.py": 8977119225749253844,
- "venv/lib/python3.13/site-packages/pydantic/schema.py": 83238111330132033,
- "venv/lib/python3.13/site-packages/pandas/tests/test_errors.py": 10116716310156374885,
- "venv/lib/python3.13/site-packages/pyasn1/codec/cer/__init__.py": 15728752901274520502,
- "venv/lib/python3.13/site-packages/pydantic/deprecated/decorator.py": 8609500261161560793,
- "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/WHEEL": 17410883677306885019,
- "venv/lib/python3.13/site-packages/certifi/__init__.py": 9045580998764948967,
- "venv/lib/python3.13/site-packages/jsonschema/tests/test_cli.py": 3173259257428855556,
- "venv/lib/python3.13/site-packages/referencing/typing.py": 8296636464219681747,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f90continuation.f90": 17056591497459381871,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalar_ctors.py": 631744056514965940,
- "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/unrolled.py": 12651425412640834530,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_cumulative.py": 15644124412739892167,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_series.py": 16418555817529711079,
- "venv/lib/python3.13/site-packages/pip/_internal/models/target_python.py": 422323125651848065,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_win_type.py": 18105114803686556748,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/dml.py": 6519732236745017861,
- "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/_pytest/mark/expression.py": 1821437025841201912,
- "frontend/src/services/git-utils.js": 12982149055119314642,
- "backend/src/models/git.py": 9387561498910534118,
- "backend/tests/test_translate_executor_filter.py": 11717560360659156703,
- "venv/lib/python3.13/site-packages/git/refs/__init__.py": 16246686106073400519,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/string.tpl": 15796203549130590784,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_datetime.py": 13781712980921881470,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.pyx": 7085380878820747579,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/__init__.py": 14571251344510763303,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_set_value.py": 4166411740676564820,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_combine_concat.py": 3201068805128232483,
- "venv/lib/python3.13/site-packages/pydantic_core/__init__.py": 10563134104783445328,
- "venv/lib/python3.13/site-packages/_pytest/doctest.py": 6126919596776592278,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_py.py": 6518425342376455821,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_dlpack.py": 7908102652282922952,
- "venv/lib/python3.13/site-packages/pandas/io/spss.py": 864838144958947906,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/_selectable_constructors.py": 84919308502240880,
- "backend/src/services/clean_release/stages/no_external_endpoints.py": 5083253025896929417,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.pyi": 2700568594438441246,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/base.py": 3628510830969664111,
- "venv/bin/pygmentize": 2166491742035772877,
- "venv/lib/python3.13/site-packages/pandas/io/formats/console.py": 10370334487585281127,
- "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.pyi": 9291444594181042963,
- "venv/lib/python3.13/site-packages/_pytest/__init__.py": 3769333500910148571,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_period.py": 6047041810867211174,
- "venv/lib/python3.13/site-packages/packaging/utils.py": 3469957615920103670,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log.csv": 221209423454319618,
- "frontend/playwright-report/trace/xtermModule.DYP7pi_n.css": 9346562810570076139,
- "frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js": 2673586123384011532,
- "venv/lib/python3.13/site-packages/pandas/_libs/window/aggregations.pyi": 6072607880689125113,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/test_uuid.py": 13955678427426850807,
- "backend/src/api/routes/clean_release.py": 9890311709059474429,
- "venv/lib/python3.13/site-packages/PIL/GimpGradientFile.py": 9777026720028891154,
- "backend/src/services/clean_release/preparation_service.py": 9259410398708054305,
- "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/RECORD": 16558021503346615951,
- "frontend/build/_app/immutable/nodes/33.Aj1tQ4W1.js": 1594581007913482648,
- "venv/lib/python3.13/site-packages/numpy/testing/_private/__init__.py": 15130871412783076140,
- "backend/src/plugins/translate/dictionary_entries.py": 6947525668381597122,
- "venv/lib/python3.13/site-packages/rsa/pkcs1.py": 2576732594642491910,
- "venv/lib/python3.13/site-packages/rsa/randnum.py": 13958355153634534526,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_editable.py": 14352954849821931255,
- "frontend/tests/maintenance.test.ts": 18128393571681331195,
- "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/licenses/COPYING": 14459782230785388765,
- "frontend/src/routes/translate/dictionaries/+page.svelte": 1038433841421198720,
- "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.pyi": 8232620851756907417,
- "venv/lib/python3.13/site-packages/pydantic/root_model.py": 20625057828723317,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.py": 1472021608501071055,
- "backend/src/services/clean_release/policy_resolution_service.py": 1025435122296379201,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/ranges.py": 14549386056660231279,
- "venv/lib/python3.13/site-packages/pandas/_libs/interval.pyi": 15698173755300703836,
- "venv/lib/python3.13/site-packages/numpy/_core/lib/npy-pkg-config/npymath.ini": 1071371630695963467,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isin.py": 14387850595546682314,
- "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/RECORD": 11976403473353722969,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_base.py": 1251545894005373734,
- "venv/lib/python3.13/site-packages/pycparser/_ast_gen.py": 5464347629908906775,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/text.py": 6096215585499446070,
- "venv/lib/python3.13/site-packages/PIL/SunImagePlugin.py": 7661622930404688367,
- "venv/lib/python3.13/site-packages/gitdb/stream.py": 3035738824550231197,
- "merge_spec.py": 13855568343782022,
- "venv/lib/python3.13/site-packages/pygments/lexers/console.py": 18266795648198475028,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arrayprint.pyi": 2424868797160722318,
- "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/LICENSE": 16343563559291870811,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_series.pyi": 7112486730197067087,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_year.py": 1478857009124807836,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/timeout.py": 1807228452024740476,
- "backend/src/plugins/translate/service_bulk_replace.py": 5355744069308185607,
- "backend/src/plugins/translate/orchestrator_retry.py": 2531207787915962557,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_stringdtype.py": 8381476847196129074,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/PIL/BdfFontFile.py": 10811640174253687845,
- "backend/src/plugins/translate/preview.py": 5579180663525515759,
- "frontend/playwright-report/trace/index.BCnMPevh.js": 8625484717968740943,
- "venv/lib/python3.13/site-packages/anyio/_core/_exceptions.py": 11969894261631227715,
- "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/INSTALLER": 17282701611721059870,
- "backend/src/services/clean_release/repositories/approval_repository.py": 11060626515832882475,
- "venv/lib/python3.13/site-packages/keyring/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_indexing.py": 11572911419313573163,
- "venv/lib/python3.13/site-packages/starlette/__init__.py": 3252794766897205870,
- "venv/lib/python3.13/site-packages/passlib/tests/test_context.py": 15195609282700801214,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pyodbc.py": 8175468565413744516,
- "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/licenses/LICENSE": 16147999986886816451,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_datetimes.py": 7889573945417063183,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_fillna.py": 4610666845291315333,
- "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml.py": 6906547816798138000,
- "venv/lib/python3.13/site-packages/numpy/lib/_polynomial_impl.pyi": 2042169688753984918,
- "venv/lib/python3.13/site-packages/numpy/_core/arrayprint.pyi": 84606125837677197,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_bus.py": 4260827599660763641,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/errors.py": 6538052228921426956,
- "venv/lib/python3.13/site-packages/pandas/compat/__init__.py": 6077099417711209303,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_compression.py": 3167245427092658522,
- "frontend/src/services/storageService.js": 9489915460172592752,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_npy_units.py": 8966226962799105383,
- "backend/src/api/routes/__tests__/test_clean_release_source_policy.py": 15459112324357199814,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/__init__.py": 5027355874704300832,
- "venv/lib/python3.13/site-packages/numpy/conftest.py": 8971879716683736515,
- "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pycparser/ply/__init__.py": 5040371336745852622,
- "venv/lib/python3.13/site-packages/pip/_vendor/distro/distro.py": 12494639376332486204,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/requests/_internal_utils.py": 4091305333167213279,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_client/integration.py": 13610682193839598457,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/date/__init__.py": 16789767433439616593,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/rec.pyi": 9140655366667421698,
- "backend/git_repos/remote/test-repo.git/refs/heads/master": 12485529318667335076,
- "backend/src/services/clean_release/repository.py": 2475446738311184132,
- "backend/git_repos/remote/test-repo.git/hooks/pre-applypatch.sample": 15598058327720909861,
- "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/RECORD": 2963644632913976754,
- "venv/lib/python3.13/site-packages/passlib/tests/test_context_deprecated.py": 7876919198015151018,
- "venv/lib/python3.13/site-packages/numpy/ma/tests/test_extras.py": 16160090335191788104,
- "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/utils.py": 2959395751217827103,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_list_accessor.py": 8613662386779664039,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_string.py": 10141066226714805009,
- "venv/lib/python3.13/site-packages/numpy/ma/core.pyi": 4829891173366130328,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/_ranges.py": 2572903460327860111,
- "venv/lib/python3.13/site-packages/pandas/tests/test_nanops.py": 8709105600366913011,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/wheel.py": 450504439085405418,
- "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_array_ops.py": 6709502157317299163,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_overlaps.py": 2328652590379935311,
- "venv/lib/python3.13/site-packages/pygments/lexers/_stata_builtins.py": 18053452765493556047,
- "venv/lib/python3.13/site-packages/pygments/styles/autumn.py": 8750937312198920971,
- "venv/lib/python3.13/site-packages/passlib/pwd.py": 14727089240749133060,
- "venv/lib/python3.13/site-packages/jeepney/__init__.py": 1063800617763464773,
- "venv/lib/python3.13/site-packages/authlib/integrations/base_client/async_app.py": 4329794049222609894,
- "venv/lib/python3.13/site-packages/numpy/ma/extras.py": 7559838309481824664,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-2.csv": 7063857529719738394,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_numba.py": 8250377774229977284,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/base.py": 14734745827490220667,
- "venv/lib/python3.13/site-packages/jaraco/context/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/meson.py": 14659991367778746658,
- "venv/lib/python3.13/site-packages/PIL/TiffTags.py": 8688883943071546469,
- "venv/lib/python3.13/site-packages/httpx/_config.py": 8800538050293498928,
- "backend/src/services/clean_release/policy_engine.py": 7078053766918689048,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_head_tail.py": 13047338070883375426,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/install/wheel.py": 3531093454660385247,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation": 4826455560768665215,
- "venv/lib/python3.13/site-packages/pygments/lexers/css.py": 517586374264113606,
- "venv/lib/python3.13/site-packages/pip/_internal/locations/_distutils.py": 13559457590971821771,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/__init__.py": 15644105878811738516,
- "venv/lib/python3.13/site-packages/pandas/core/base.py": 10262717073058743378,
- "venv/lib/python3.13/site-packages/PIL/_avif.cpython-313-x86_64-linux-gnu.so": 5243449968857258659,
- "venv/lib/python3.13/site-packages/PIL/WmfImagePlugin.py": 15685062825106444247,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/index_command.py": 15798187258841839292,
- "backend/src/services/profile_service.py": 6301319288045056964,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_align.py": 6050248183327934780,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/serializer.py": 8708767945343850816,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_compat.py": 11481259393140789881,
- "backend/src/services/dataset_review/__init__.py": 3695054675894579272,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/_collections.py": 7772437080414835462,
- "venv/lib/python3.13/site-packages/pycparser/_c_ast.cfg": 2649342580905806389,
- "backend/:memory:test_auth": 1309242367339970214,
- "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/RECORD": 14375680579341422646,
- "venv/lib/python3.13/site-packages/jsonschema/__main__.py": 18136546137047911521,
- "venv/lib/python3.13/site-packages/fastapi/_compat/v2.py": 15078491685917047095,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/_fileno.py": 15541504502174047167,
- "venv/lib/python3.13/site-packages/starlette/types.py": 6372850128669191435,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libsasl2-883649fd.so.3.0.0": 13306917506408577991,
- "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/idna/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/__init__.py": 6532094538918910232,
- "venv/lib/python3.13/site-packages/numpy/_core/_dtype.py": 7796703383405149774,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimelike.py": 394614958716301173,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_timeseries_window.py": 1973365560758236222,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_numeric.py": 9383693732009547935,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_normalize.py": 3203921571999101793,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_formats.py": 5259100336852479395,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_construction.py": 10619501873883861745,
- "venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py": 1246582552828542841,
- "venv/lib/python3.13/site-packages/cryptography/utils.py": 18088508841978595788,
- "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/engine.py": 2652248727360250985,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/mypy.ini": 4763385838822685881,
- "venv/lib/python3.13/site-packages/pygments/lexers/devicetree.py": 9820277168995231927,
- "frontend/build/_app/immutable/chunks/B3miH4jD.js": 11736959945545311440,
- "frontend/build/_app/immutable/chunks/D0ftnVnT.js": 17464841514774947275,
- "venv/lib/python3.13/site-packages/cryptography/x509/ocsp.py": 17973800752927680404,
- "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/RECORD": 173225030102092319,
- "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.py": 14034239842770171660,
- "venv/lib/python3.13/site-packages/pygments/styles/manni.py": 11853576691280294949,
- "venv/lib/python3.13/site-packages/greenlet/tests/test_generator_nested.py": 12822240347707346718,
- "venv/lib/python3.13/site-packages/pygments/unistring.py": 18037463865539157041,
- "venv/lib/python3.13/site-packages/git/refs/remote.py": 4391983355222612205,
- "venv/lib/python3.13/site-packages/numpy/_core/strings.pyi": 1981676808027146409,
- "frontend/src/lib/components/reports/ReportCard.svelte": 6530314148568868862,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_value_counts.py": 13270420637302622174,
- "backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py": 5075014721013543720,
- "backend/src/api/routes/health.py": 2970999898180732726,
- "backend/tests/test_layout_utils.py": 5009482327800448704,
- "venv/lib/python3.13/site-packages/pygments/modeline.py": 6194365452131561478,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/histograms.pyi": 2281259341486424755,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_join.py": 1131792466825856990,
- "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.pyi": 7674087576653964854,
- "venv/lib/python3.13/site-packages/httpx/_types.py": 12461152436147308761,
- "backend/src/services/dataset_review/orchestrator_pkg/_helpers.py": 14441258905942300095,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.asm": 15349921092257597740,
- "venv/lib/python3.13/site-packages/pygments/styles/zenburn.py": 1031869867933871309,
- "venv/lib/python3.13/site-packages/ecdsa/_version.py": 17707102226558781833,
- "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/RECORD": 18314788057673509075,
- "venv/lib/python3.13/site-packages/cffi/cparser.py": 5246372077864988755,
- "backend/src/services/reports/type_profiles.py": 9186322444310801411,
- "venv/lib/python3.13/site-packages/referencing/tests/test_core.py": 8280983300775878144,
- "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.py": 12886275429547303345,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/api.py": 16364136812252343076,
- "venv/lib/python3.13/site-packages/pygments/lexers/lilypond.py": 1088755646568511197,
- "venv/lib/python3.13/site-packages/psycopg2/_json.py": 9729420372294281405,
- "frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js": 15614617116241362179,
- "venv/lib/python3.13/site-packages/authlib/oauth2/__init__.py": 13682931764896414722,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/tree.py": 4991806303236874829,
- "venv/lib/python3.13/site-packages/tzlocal/utils.py": 7893867974548929154,
- "venv/lib/python3.13/site-packages/pydantic/parse.py": 13750341403702794392,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_strings.py": 7379299916213794543,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sort_values.py": 12064896795288302730,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_legend.py": 13094583566764796297,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/provision.py": 2676876852726658063,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/requirements.py": 11478648568700804705,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_aix.h": 13316272821279308986,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/schema.py": 8358664670620586363,
- "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.pyi": 12275242654430570028,
- "venv/lib/python3.13/site-packages/pygments/styles/paraiso_light.py": 15941591873059208999,
- "venv/lib/python3.13/site-packages/passlib/ext/django/utils.py": 8118896525895185626,
- "frontend/src/routes/admin/users/+page.svelte": 12399730365576276239,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_libsparse.py": 1859997684694949029,
- "venv/lib/python3.13/site-packages/cryptography/x509/oid.py": 13909847799728532602,
- "backend/alembic_test.db": 14995253579408279707,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/evaluator.py": 6348022789899831255,
- "venv/lib/python3.13/site-packages/anyio/abc/_subprocesses.py": 4297459042599291531,
- "venv/lib/python3.13/site-packages/ecdsa/errors.py": 11755424742691057760,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/operators.py": 5584982192355398255,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/util.py": 2866856507760047219,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_datetime.py": 4179112383995346046,
- "venv/lib/python3.13/site-packages/PIL/GdImageFile.py": 16875784236394545058,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/filesize.py": 13234856188049714485,
- "venv/lib/python3.13/site-packages/_pytest/freeze_support.py": 494952714451267295,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_filters.py": 17271344092069736999,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/core": 10616484054735611337,
- "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/RECORD": 3283324710045856319,
- "backend/src/plugins/llm_analysis/__init__.py": 9254812131558249924,
- "venv/lib/python3.13/site-packages/numpy/_expired_attrs_2_0.py": 8786558894094307341,
- "venv/lib/python3.13/site-packages/pydantic/config.py": 1450073446492183677,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_index.py": 4908727359687606870,
- "venv/lib/python3.13/site-packages/cryptography/x509/base.py": 9124948989225782039,
- "venv/lib/python3.13/site-packages/PIL/_imagingtk.pyi": 18222325750818585549,
- "venv/lib/python3.13/site-packages/httpcore/_synchronization.py": 10997080307461682786,
- "venv/lib/python3.13/site-packages/pandas/_libs/algos.pyi": 22405377601029952,
- "frontend/src/lib/api/assistant.js": 12514226537527897950,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_arithmetic.py": 13320788210970132239,
- "venv/lib/python3.13/site-packages/urllib3/response.py": 1987354357306756790,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/typst.tpl": 5055419073126793137,
- "venv/lib/python3.13/site-packages/pandas/_libs/groupby.pyi": 6154952803757623626,
- "venv/lib/python3.13/site-packages/numpy/lib/format.pyi": 11752225430594536662,
- "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.pyi": 6534825471013879522,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/naming.py": 14503932124671438340,
- "frontend/build/_app/immutable/nodes/16.yCusNoj_.js": 1406373227455087905,
- "venv/lib/python3.13/site-packages/pandas/_libs/reshape.pyi": 88721900806893992,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_construction.py": 6564829381134214401,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/hstore.py": 9700253004947691961,
- "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/RECORD": 1689342214025776630,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/uninstall.py": 11003472265011262515,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_constructors.py": 7466113171256856591,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/__init__.py": 15130871412783076140,
- "backend/src/models/auth.py": 4040750225610660281,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.cpython-313-x86_64-linux-gnu.so": 657138415665704488,
- "venv/lib/python3.13/site-packages/pip/_internal/exceptions.py": 2252826732781519645,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/__init__.py": 96341051676048910,
- "venv/lib/python3.13/site-packages/uvicorn/protocols/utils.py": 6147480543268737542,
- "venv/lib/python3.13/site-packages/pandas/_libs/properties.cpython-313-x86_64-linux-gnu.so": 7092136701092358552,
- "venv/lib/python3.13/site-packages/pandas/core/indexes/extension.py": 7193879749426425951,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_quantile.py": 4225791949463893856,
- "venv/lib/python3.13/site-packages/pygments/lexers/_vbscript_builtins.py": 9882134558469491349,
- "venv/lib/python3.13/site-packages/pygments/lexers/igor.py": 6506221273085723501,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_msvc.h": 17581467060937454503,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/jose/backends/__init__.py": 16581763658239070112,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp2.csv": 10950201682596097452,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/index.py": 15694995431926521471,
- "frontend/src/routes/storage/repos/+page.svelte": 2273592022555593164,
- "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.pyi": 4587511199710546030,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_partial_indexing.py": 4132091154215910029,
- "venv/lib/python3.13/site-packages/referencing/jsonschema.py": 14596871117484757502,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libpcre-9513aab5.so.1.2.0": 12298861477332583668,
- "venv/lib/python3.13/site-packages/pillow.libs/libbrotlidec-b57ddf63.so.1.2.0": 10032590058372320813,
- "venv/lib/python3.13/site-packages/numpy/_distributor_init.py": 1101690714183863290,
- "frontend/playwright-report/trace/assets/urlMatch-BYQrIQwR.js": 8070494174996726626,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_scalar_compat.py": 1306236983392218709,
- "venv/lib/python3.13/site-packages/numpy/_pytesttester.py": 17737911110576747508,
- "venv/lib/python3.13/site-packages/keyring/backend.py": 14185808762437650951,
- "backend/src/api/routes/translate/_run_routes.py": 16216908966766661647,
- "backend/src/api/routes/translate/_preview_routes.py": 12316180738640292691,
- "venv/lib/python3.13/site-packages/_pytest/compat.py": 10046464101087327473,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_x32_unix.h": 9165722966153119887,
- "backend/alembic/versions/e5f4d3c2b1a_add_policy_id_to_validation_results.py": 11168047633691803786,
- "venv/lib/python3.13/site-packages/pygments/lexers/textfmts.py": 17438453283146671997,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-2.csv": 4052796393463357888,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/validator.py": 14200019408839159476,
- "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.py": 10803011906582324302,
- "venv/lib/python3.13/site-packages/pandas/tseries/frequencies.py": 2262381949755250516,
- "venv/lib/python3.13/site-packages/pandas/tests/util/conftest.py": 11143177766735481660,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/flatiter.pyi": 6885824496927786205,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_first_valid_index.py": 15763400665851423183,
- "venv/lib/python3.13/site-packages/pandas/_testing/_hypothesis.py": 12298650110193262367,
- "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html.tpl": 12550218314797699304,
- "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/METADATA": 1684451390569121499,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_localize.py": 4937713043686953098,
- "venv/lib/python3.13/site-packages/pydantic/plugin/_loader.py": 792663962985957671,
- "venv/lib/python3.13/site-packages/gitdb/util.py": 645937410168583692,
- "venv/lib/python3.13/site-packages/pandas/core/reshape/reshape.py": 5387892304726762127,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64_np126.pkl.gz": 1630203486813146863,
- "frontend/src/lib/api/translate/__tests__/test-target-schema.test.js": 16872327388398551554,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_latex.py": 15077617224435782028,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_unary.py": 2573825678342936734,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/lexers/python.py": 17886036670342116501,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_value_attrspec.py": 7741590618654448240,
- "backend/src/api/routes/dataset_review.py": 6955521302681155464,
- "venv/lib/python3.13/site-packages/pandas/tests/internals/test_api.py": 11217428888457119601,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_docs_extraction.py": 5210114991139191634,
- "venv/lib/python3.13/site-packages/pydantic/v1/json.py": 16596969681914729251,
- "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 12574929384355254457,
- "venv/lib/python3.13/site-packages/keyring/backends/chainer.py": 12526770797516553385,
- "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/METADATA": 9458019064618635438,
- "frontend/src/lib/components/assistant/AssistantClarificationCard.svelte": 4264349064103133826,
- "backend/src/models/llm.py": 2659715328568075505,
- "frontend/src/components/tools/DebugTool.svelte": 2623666555575648117,
- "venv/lib/python3.13/site-packages/pip/_internal/models/__init__.py": 13482731985065116750,
- "venv/lib/python3.13/site-packages/websockets/version.py": 5853118844880112885,
- "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django_source.py": 15577951591316518967,
- "backend/src/core/auth/oauth.py": 2441694487419087464,
- "venv/lib/python3.13/site-packages/fastapi/openapi/docs.py": 16735218221639179927,
- "venv/lib/python3.13/site-packages/pip/_internal/locations/_sysconfig.py": 4773855595767526182,
- "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/licenses/LICENSE": 3868190977070717994,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/req_command.py": 2887890799766730546,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8414/__init__.py": 4781700006554860887,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/array.py": 13040461386712513615,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_scalar.py": 2434773821902319678,
- "venv/lib/python3.13/site-packages/PIL/ImageSequence.py": 16459886231802763032,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_numba.py": 6409810497251251179,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/errors.py": 12777931960088171310,
- "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/RECORD": 6349071557579241461,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/color_triplet.py": 17264298271771184,
- "venv/lib/python3.13/site-packages/click/_termui_impl.py": 3296085065310341855,
- "backend/src/services/clean_release/source_isolation.py": 9041802363608399236,
- "venv/lib/python3.13/site-packages/pyasn1/codec/native/encoder.py": 120921270972591880,
- "venv/lib/python3.13/site-packages/click/utils.py": 13475604420010022458,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets_properties.py": 2340780879864207500,
- "backend/src/services/clean_release/compliance_orchestrator.py": 6747364300631405520,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunc_config.pyi": 2005481648919369399,
- "venv/lib/python3.13/site-packages/pygments/lexers/graphviz.py": 15677908982985025500,
- "backend/src/api/routes/assistant/_dataset_review_dispatch.py": 555136946286235411,
- "venv/lib/python3.13/site-packages/numpy/lib/stride_tricks.py": 548928042543500365,
- "venv/lib/python3.13/site-packages/pandas/io/json/__init__.py": 12333505155070172626,
- "backend/src/core/utils/network.py": 535557448085943960,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/style.py": 12654125988995362593,
- "venv/lib/python3.13/site-packages/pygments/scanner.py": 5640381644804445932,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_to_numpy.py": 14845850776625255794,
- "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.py": 11621577915097515056,
- "venv/lib/python3.13/site-packages/websockets/imports.py": 1995356703044158461,
- "venv/lib/python3.13/site-packages/fastapi/params.py": 14263655860695381481,
- "venv/lib/python3.13/site-packages/anyio/__init__.py": 12752386096259972231,
- "venv/lib/python3.13/site-packages/httpx/__version__.py": 9473642134297828811,
- "venv/lib/python3.13/site-packages/jaraco/classes/properties.py": 6976928770004942858,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.f": 1486878017876900890,
- "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/WHEEL": 16223367184831500348,
- "venv/lib/python3.13/site-packages/pip/_internal/operations/check.py": 16650663913976953800,
- "venv/lib/python3.13/site-packages/pydantic/utils.py": 1533455264689378477,
- "venv/lib/python3.13/site-packages/pandas/compat/pickle_compat.py": 11073483984394766474,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict_of_blocks.py": 11646835537993064324,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_linux.h": 15772978805500070727,
- "venv/lib/python3.13/site-packages/pygments/lexers/other.py": 6893672181003034910,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.pyi": 2700568594438441246,
- "frontend/src/lib/auth/__tests__/permissions.test.js": 6261396581556099281,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending.pyx": 756189645898997788,
- "venv/lib/python3.13/site-packages/ecdsa/test_numbertheory.py": 2117130219401053225,
- "venv/lib/python3.13/site-packages/websockets/asyncio/router.py": 15039562376314233669,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/cmac.py": 12011944740750051829,
- "frontend/src/routes/datasets/__tests__/bulk_actions.test.js": 8445672988319354987,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/glibc.py": 12335359492756627313,
- "venv/lib/python3.13/site-packages/numpy/_core/numerictypes.pyi": 12144531601504755948,
- "backend/src/models/clean_release.py": 4198911944577810567,
- "venv/lib/python3.13/site-packages/keyring/core.py": 2764269590123131634,
- "venv/lib/python3.13/site-packages/jeepney/io/__init__.py": 2568357146184259175,
- "venv/lib/python3.13/site-packages/numpy/random/mtrand.pyi": 17144590106028661128,
- "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/expressions.py": 8015786996064244656,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_meson.py": 5735043585893007971,
- "venv/lib/python3.13/site-packages/passlib/tests/sample1.cfg": 9597283806285213340,
- "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_scrypt.py": 17378030264314664250,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/util.py": 4815334059917765852,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_value_counts.py": 5534713464063604301,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_unstack.py": 11834917665446437163,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/formatter.py": 11156733836937309465,
- "venv/lib/python3.13/site-packages/passlib/ext/django/__init__.py": 11713862539944289631,
- "frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js": 18193433457755419816,
- "frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js": 16008187945694980240,
- "venv/lib/python3.13/site-packages/anyio/abc/_streams.py": 8089057973257658396,
- "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.py": 12636954896699095212,
- "venv/lib/python3.13/site-packages/fastapi/responses.py": 6092572095549573593,
- "venv/lib/python3.13/site-packages/pip/_internal/req/req_uninstall.py": 3515239440812977025,
- "venv/lib/python3.13/site-packages/pandas/tests/io/test_pickle.py": 2910383574326146698,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/__init__.py": 8434616194114282088,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_polynomial.py": 3049262771098624825,
- "venv/lib/python3.13/site-packages/packaging/__init__.py": 5479277484104486860,
- "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.cpp": 7360124705400993707,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/hkdf.py": 8539232219382152238,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parse_iso8601.py": 9100947620267156161,
- "venv/lib/python3.13/site-packages/pandas/tests/resample/__init__.py": 15130871412783076140,
- "frontend/playwright-report/data/fe71864b4cbf83c1ddaa5774098c6fa987f91ff9.webm": 9945873951473992150,
- "frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js": 7841254655898186872,
- "frontend/src/components/Navbar.svelte": 2640465687592983765,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py": 2858987911347541177,
- "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.pyi": 15848834171197104301,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_equals.py": 11041884432990762650,
- "backend/src/schemas/health.py": 17351928434071690723,
- "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.pyi": 15067467792538416274,
- "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/METADATA": 6438256145634479451,
- "backend/src/services/rbac_permission_catalog.py": 11280653389166352517,
- "venv/lib/python3.13/site-packages/fastapi/_compat/v1.py": 9776181748061371513,
- "backend/git_repos/remote/test-repo.git/objects/99/38d17c3f4199e53e4d4ebc253fe9c840caa505": 8414792171590415839,
- "venv/lib/python3.13/site-packages/pygments/lexers/gcodelexer.py": 13712494327007684318,
- "backend/src/core/utils/superset_context_extractor/_base.py": 6349561308410782726,
- "venv/lib/python3.13/site-packages/pydantic/type_adapter.py": 10162988530225478692,
- "venv/lib/python3.13/site-packages/ecdsa/ecdsa.py": 9770689913380927623,
- "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/meson.build": 17468163147765825687,
- "venv/lib/python3.13/site-packages/pip/_internal/vcs/mercurial.py": 335201628064585213,
- "venv/lib/python3.13/site-packages/referencing/__init__.py": 10093824711214801917,
- "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.cpython-313-x86_64-linux-gnu.so": 18139875206371157315,
- "venv/lib/python3.13/site-packages/pip/_internal/commands/help.py": 4175797322922912326,
- "venv/lib/python3.13/site-packages/pip/_internal/cli/command_context.py": 9426036980437931533,
- "venv/lib/python3.13/site-packages/pandas/tests/test_expressions.py": 16378925536309828288,
- "venv/lib/python3.13/site-packages/pandas/io/parsers/__init__.py": 11752833703934347122,
- "venv/lib/python3.13/site-packages/sqlalchemy/log.py": 10101221585967121334,
- "frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte": 2392958189014264590,
- "venv/lib/python3.13/site-packages/git/compat.py": 16843345645628515492,
- "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.pyi": 9935587108964614958,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py": 5324490103277723813,
- "venv/lib/python3.13/site-packages/jose/__init__.py": 15575670403380555945,
- "venv/lib/python3.13/site-packages/pandas/_libs/sparse.cpython-313-x86_64-linux-gnu.so": 2051484129454294720,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_timestamp_method.py": 11393911418463808195,
- "venv/lib/python3.13/site-packages/urllib3/http2/probe.py": 4069929463671970243,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh22648.pyf": 15094859289098837494,
"venv/lib/python3.13/site-packages/fastapi/_compat/__init__.py": 12380131786677943349,
- "venv/lib/python3.13/site-packages/pygments/styles/_mapping.py": 11752660241391232497,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/constrain.py": 6513876973118703677,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_engines.py": 2790877023773269276,
- "frontend/src/lib/components/health/HealthMatrix.svelte": 18141816318382901531,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro_py.py": 11991492232381887787,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_util.py": 6664989864423807444,
- "venv/lib/python3.13/site-packages/dateutil/tz/__init__.py": 9617254832690762236,
- "venv/lib/python3.13/site-packages/pydantic/experimental/__init__.py": 492399139963056461,
- "venv/lib/python3.13/site-packages/greenlet/TPythonState.cpp": 12828594265749606443,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsinh.csv": 13695545125848146013,
- "venv/lib/python3.13/site-packages/starlette/middleware/httpsredirect.py": 16837082808103815044,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77fixedform.f95": 10898637805043867370,
- "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_xs.py": 11073752361562791165,
- "venv/lib/python3.13/site-packages/pygments/lexers/inferno.py": 9056274496469409594,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_kind.py": 18178830861475480607,
- "venv/lib/python3.13/site-packages/PIL/FtexImagePlugin.py": 8196606399875185931,
- "venv/lib/python3.13/site-packages/h11/_writers.py": 8585823094975171480,
- "venv/lib/python3.13/site-packages/numpy/lib/array_utils.py": 18135114588643176359,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_ufunc.py": 5025605639221470838,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_arithmetic.py": 17449383588949771785,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_reductions.py": 8258332365408303156,
- "venv/lib/python3.13/site-packages/pygments/lexers/procfile.py": 3860651022061090738,
- "frontend/src/types/dashboard.ts": 9718666955722367566,
- "frontend/src/routes/tools/debug/+page.svelte": 15897419227221157739,
- "backend/tests/services/clean_release/test_candidate_manifest_services.py": 14438251683804094377,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_low_level.py": 3579024079580951234,
- "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/RECORD": 7363618870628306370,
- "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/test_stack_unstack.py": 3737891757817696405,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_asof.py": 17616601748321325187,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/casting.py": 12226803454582253097,
- "venv/lib/python3.13/site-packages/pandas/tests/util/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/_testing/_io.py": 14264259716673715185,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/idna-3.11.dist-info/RECORD": 11541505360973709787,
- "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/RECORD": 11788532857617688351,
- "backend/src/services/clean_release/manifest_builder.py": 16367921257027024830,
- "backend/src/services/clean_release/repositories/manifest_repository.py": 12161285893423159929,
- "backend/git_repos/remote/test-repo.git/objects/79/b070ad8af7bbc12169f7660d2a7a72ec7a889a": 8153595714065675791,
- "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.pyi": 10360538024015064036,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/const_vs_enum.py": 12873459583943748931,
- "frontend/build/_app/immutable/chunks/BxfreSRb.js": 7524659291169347564,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_check_indexer.py": 2929031395357057009,
- "venv/lib/python3.13/site-packages/pip/_internal/vcs/bazaar.py": 5630511062945201327,
- "venv/lib/python3.13/site-packages/anyio/streams/tls.py": 4191898645554875562,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/collections.py": 16114931075157411913,
- "venv/lib/python3.13/site-packages/numpy/_core/umath.pyi": 11775804030935134661,
- "venv/lib/python3.13/site-packages/pytest_asyncio/__init__.py": 8162213292669110211,
- "venv/lib/python3.13/site-packages/pygments/lexers/_julia_builtins.py": 8846111188795315103,
- "venv/lib/python3.13/site-packages/PIL/XVThumbImagePlugin.py": 7472134175570205454,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_loongarch64_linux.h": 6566098590441297326,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/__init__.py": 371829636800613137,
- "venv/lib/python3.13/site-packages/pygments/formatters/html.py": 1918541918263449443,
- "backend/src/schemas/__init__.py": 8700952869915187087,
- "backend/src/plugins/translate/orchestrator_sql_rows.py": 13887342178846174274,
- "venv/lib/python3.13/site-packages/cryptography/x509/__init__.py": 4066756344049307453,
- "backend/alembic/versions/a5b6c7d8e9f0_set_null_ondelete_for_task_records_env_fk.py": 17528129825127496932,
- "venv/lib/python3.13/site-packages/pyasn1/type/namedval.py": 8273171503516887681,
- "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.py": 6348811074249398741,
- "venv/lib/python3.13/site-packages/pygments/lexers/archetype.py": 8995143180482517233,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_symbolic.py": 8093576026032854125,
- "venv/lib/python3.13/site-packages/pyasn1/codec/ber/__init__.py": 15728752901274520502,
- "venv/lib/python3.13/site-packages/pip/_vendor/certifi/core.py": 2300277198409164253,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_gather.py": 3634138701088855517,
- "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.pyi": 16799580742094025110,
- "venv/lib/python3.13/site-packages/cryptography/x509/extensions.py": 10197248868682803019,
- "venv/lib/python3.13/site-packages/pygments/lexers/webmisc.py": 9530962803076253849,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_interval_array_equal.py": 15654625365223535344,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_constructors.py": 12628643543371952431,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_groupby.py": 2738671407653333726,
- "venv/lib/python3.13/site-packages/pydantic_settings/exceptions.py": 18300876747412267999,
- "venv/lib/python3.13/site-packages/anyio/_backends/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp_impl.cpython-313-x86_64-linux-gnu.so": 11767771662042404251,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/screen.py": 6933591906297023845,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/twodim_base.pyi": 10156504423258357540,
- "venv/lib/python3.13/site-packages/authlib/oauth1/__init__.py": 3692257288065292607,
- "venv/lib/python3.13/site-packages/pip/_internal/main.py": 13711402795965346761,
- "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.py": 17277594393032382485,
- "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.py": 13574106461973044500,
- "venv/lib/python3.13/site-packages/pandas/tests/window/test_api.py": 6439927798101672423,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_partial.py": 3151286293440416036,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_describe.py": 14493300276133670380,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_integer.py": 16102640589300356639,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/metadata.py": 7204343250279221076,
- "venv/lib/python3.13/site-packages/requests/status_codes.py": 17005213506461710202,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_concat.py": 16549010224568175202,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api_latest.c": 5472633890472031814,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_chunksize.py": 7107619871245389835,
- "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_readlines.py": 15928258358116399067,
- "venv/lib/python3.13/site-packages/yaml/serializer.py": 1783761365703703558,
- "venv/lib/python3.13/site-packages/numpy/matlib.pyi": 8017902013455539981,
- "frontend/src/lib/ui/LanguageSwitcher.svelte": 15175441556916164874,
- "frontend/src/pages/Dashboard.svelte": 6613365687791502139,
- "backend/src/plugins/debug.py": 13683182174969777939,
- "venv/lib/python3.13/site-packages/pandas/tests/construction/test_extract_array.py": 3100523370314150013,
- "frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte": 4738179149247725720,
- "venv/lib/python3.13/site-packages/PIL/PSDraw.py": 1927169421822446045,
- "backend/src/core/utils/__init__.py": 12454773556575864508,
- "venv/lib/python3.13/site-packages/jsonschema/protocols.py": 847332300543820834,
- "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libselinux-0922c95c.so.1": 16516617710645376769,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/exclusions.py": 15852672500377116297,
- "venv/lib/python3.13/site-packages/pygments/styles/fruity.py": 7925019839136894457,
- "venv/lib/python3.13/site-packages/passlib/utils/__init__.py": 11704122205941631503,
- "venv/lib/python3.13/site-packages/pygments/lexers/_cl_builtins.py": 16540712925368297957,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_dtypes_basic.py": 10917162988625838981,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_astype.py": 8633811117672837999,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_dict.py": 16252265723192124609,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/models.py": 9513172366009392193,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.py": 5933622200264572885,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/resource_protector.py": 9147671710440653567,
- "venv/lib/python3.13/site-packages/pip/_vendor/truststore/py.typed": 15130871412783076140,
- "frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte": 8577281635452165836,
- "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/WHEEL": 16097436423493754389,
- "frontend/src/routes/settings/notifications/+page.svelte": 11507547877108528071,
- "backend/src/core/config_manager.py": 1668206562922192026,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/base.py": 664515424699746697,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_missing.py": 2976310411820303374,
- "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_css.py": 17765129030290410902,
- "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatters/_mapping.py": 13335227913146542481,
- "frontend/src/lib/stores/__tests__/mocks/environment.js": 3065694655373335793,
- "venv/lib/python3.13/site-packages/pillow.libs/libsharpyuv-95d8a097.so.0.1.2": 5320647379976541240,
- "backend/src/api/routes/dataset_review_pkg/_dependencies.py": 5445855387226126427,
- "backend/alembic/versions/8dd0a93af539_drop_deprecated_source_language_column_.py": 3574830605384611294,
- "venv/lib/python3.13/site-packages/charset_normalizer/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/attr/_config.py": 1864824728504480204,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/key_set.py": 8485970749081951741,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/format": 12697928260201325593,
- "venv/lib/python3.13/site-packages/sqlalchemy/orm/identity.py": 326059526167697655,
- "venv/lib/python3.13/site-packages/pygments/lexers/chapel.py": 7619603166448145621,
- "venv/lib/python3.13/site-packages/urllib3/util/request.py": 9432067988603015849,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/pubprivmod.f90": 8680230823849248800,
- "venv/lib/python3.13/site-packages/cffi/_embedding.h": 9441285871823018603,
- "venv/lib/python3.13/site-packages/numpy/core/einsumfunc.py": 3484247123731380377,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/lexers/mosel.py": 1877592344012288438,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_function_base.pyi": 10972502518588022706,
- "venv/lib/python3.13/site-packages/websockets/sync/client.py": 10892557975919033983,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_join.py": 11910166566689889389,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/test_arrow.py": 10068866425352207113,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_from_dummies.py": 5670811108950300761,
- "venv/lib/python3.13/site-packages/PIL/PalmImagePlugin.py": 13008868719182630239,
- "venv/lib/python3.13/site-packages/httpcore/_sync/http2.py": 11167798787131917524,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_legendre.py": 18266595775500927868,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarinherit.py": 15240535501243623986,
- "frontend/src/components/__tests__/task_log_viewer.test.js": 4344163242946147110,
- "venv/lib/python3.13/site-packages/pygments/lexers/modula2.py": 6575895980250662093,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/lower_f2py_fortran.f90": 13315882216322269383,
- "frontend/src/lib/components/settings/ApiKeysTab.svelte": 17208249963941978218,
- "frontend/src/lib/components/MaintenanceSettingsPanel.svelte": 8672462648876875400,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo90.f90": 58572216018544419,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ma.py": 15912582628112164509,
- "venv/lib/python3.13/site-packages/websockets/speedups.c": 11800200877763464246,
- "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/__init__.py": 5896924546560667519,
- "venv/lib/python3.13/site-packages/pandas/core/interchange/from_dataframe.py": 8278998381856028462,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/einsumfunc.pyi": 200771351328522379,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/extension/base/ops.py": 13451323660386712332,
- "venv/lib/python3.13/site-packages/numpy/_core/__init__.py": 14951958843029076911,
- "venv/lib/python3.13/site-packages/pandas/tests/window/moments/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/_pytest/_code/code.py": 5248836309618416369,
- "venv/lib/python3.13/site-packages/websockets/protocol.py": 6401227903827084901,
- "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/METADATA": 14126682758562488244,
- "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/METADATA": 3448868793744358515,
- "venv/lib/python3.13/site-packages/pip/_vendor/requests/help.py": 3124654001287175629,
- "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.py": 12355826783958402233,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_compiler_compat.hpp": 465436185632243991,
- "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/test_jsonschema_specifications.py": 12693210357718751894,
- "venv/lib/python3.13/site-packages/numpy/linalg/lapack_lite.pyi": 14069586330277925998,
- "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.py": 4984721349618127021,
- "venv/lib/python3.13/site-packages/numpy/_globals.py": 8736093011628027941,
- "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/licenses/LICENSE": 8364608327598414179,
- "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/RECORD": 8201759541483070364,
- "venv/lib/python3.13/site-packages/pandas/core/shared_docs.py": 2173578869755325502,
- "venv/lib/python3.13/site-packages/pandas/core/util/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.pyi": 6616985736007157309,
- "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/requirements.py": 13215932786801020434,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_public_dtype_api_table.h": 8933016749764021181,
- "venv/lib/python3.13/site-packages/pandas/core/ops/dispatch.py": 7041711677358147534,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_resolution.py": 9651416588266430520,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_unix.h": 9608771997528633681,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_julian_date.py": 850085757774959003,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_generic.py": 1297407268239966429,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop.py": 15751236355035730554,
- "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/RECORD": 15865206372525596795,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isna.py": 18394053826166267096,
- "venv/lib/python3.13/site-packages/pandas/io/api.py": 8275376846208437741,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/json.py": 15085143436056608404,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/mod.py": 2054876501774773382,
- "venv/lib/python3.13/site-packages/PIL/_imagingmorph.pyi": 18222325750818585549,
- "frontend/src/lib/stores/__tests__/sidebar.test.js": 3057168376995255911,
- "backend/src/core/utils/superset_context_extractor/_recovery.py": 11393453671559067169,
- "venv/lib/python3.13/site-packages/h11/_state.py": 11398755254809751139,
- "frontend/src/lib/stores/__tests__/mocks/env_public.js": 17950613826406014914,
- "venv/lib/python3.13/site-packages/greenlet/greenlet_internal.hpp": 13173115501223013762,
- "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpython-313-x86_64-linux-gnu.so": 7659849621107414188,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/requests.py": 14847842002253212098,
- "venv/lib/python3.13/site-packages/py.py": 16248211404003181569,
- "venv/lib/python3.13/site-packages/jeepney/io/tests/test_trio.py": 7459901627473962540,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_shape_manipulation.pyi": 3533739482029983817,
- "venv/lib/python3.13/site-packages/websockets/__main__.py": 11948055520555854616,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/errors.py": 17581857895562494222,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_dtypes.py": 13065857166166716628,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/__init__.py": 8807410829260170597,
- "venv/lib/python3.13/site-packages/passlib/context.py": 10362592407593745107,
- "venv/lib/python3.13/site-packages/pandas/io/json/_json.py": 1393095374713367445,
- "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/WHEEL": 16097436423493754389,
- "venv/lib/python3.13/site-packages/pygments/lexers/scdoc.py": 8481749542463754279,
- "backend/src/api/routes/assistant/_routes.py": 17155281273786858236,
- "backend/src/api/routes/assistant/_dispatch.py": 12376888449563411982,
- "venv/lib/python3.13/site-packages/idna/compat.py": 9758194415584776667,
- "venv/lib/python3.13/site-packages/numpy/random/_common.cpython-313-x86_64-linux-gnu.so": 12834724130890991478,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/packaging.py": 15555781487631855604,
- "venv/lib/python3.13/site-packages/pandas/core/methods/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/passlib/tests/test_utils_pbkdf2.py": 17016810698578473773,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_constructors.py": 9815164146739254076,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/crud.py": 805684028038896506,
- "venv/lib/python3.13/site-packages/pyasn1/type/useful.py": 10313387611927801339,
- "backend/src/plugins/llm_analysis/__tests__/test_client_headers.py": 6499914987034257707,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reset_index.py": 5946666595195952693,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_routines.py": 4860173574365060471,
- "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/licenses/LICENSE": 13322127602069971876,
- "venv/lib/python3.13/site-packages/pygments/lexers/int_fiction.py": 8806961041808606055,
- "backend/src/plugins/translate/__tests__/test_inline_correction.py": 9293076489563685553,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp.cpython-313-x86_64-linux-gnu.so": 10263790384087091349,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/keys.pyi": 1846673463183660140,
- "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/providers.py": 7267821734584612032,
- "venv/lib/python3.13/site-packages/_pytest/scope.py": 7603155109542903644,
- "venv/lib/python3.13/site-packages/pygments/lexers/jvm.py": 897669925284011089,
- "venv/lib/python3.13/site-packages/passlib/tests/test_utils.py": 10362977406431569031,
- "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_sorted.py": 1899608688401238388,
- "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertions.py": 5556667947376168765,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/json_schema_test_suite.py": 6152158310190822762,
- "venv/lib/python3.13/site-packages/pip/_vendor/packaging/version.py": 5000350193835202949,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_cov_corr.py": 13652339565475304679,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/_conditional.py": 14190849361275154667,
- "backend/src/core/superset_client/_datasets_preview_filters.py": 3588066821120121881,
- "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.cpython-313-x86_64-linux-gnu.so": 5441755022198996487,
- "backend/src/plugins/translate/service_utils.py": 15103456860964805370,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/introspection.py": 14645217065508644154,
- "venv/lib/python3.13/site-packages/pandas/core/tools/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame.py": 16757570551941104401,
- "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/WHEEL": 2357997949040430835,
- "venv/lib/python3.13/site-packages/annotated_doc/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/starlette/routing.py": 16063812008141874150,
- "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_numpyconfig.h": 18150055639397773687,
- "venv/lib/python3.13/site-packages/pandas/core/groupby/base.py": 16888506204910366302,
- "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/fetch.py": 13937019222549208796,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/models.py": 1370998944213578392,
- "venv/lib/python3.13/site-packages/certifi/py.typed": 15130871412783076140,
- "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/code.py": 9700811903057180696,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/filesystem.py": 7716285033598020316,
- "venv/lib/python3.13/site-packages/numpy/exceptions.pyi": 13942486291715303235,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_indexing.py": 81180636019259296,
- "frontend/src/lib/components/reports/ReportDetailPanel.svelte": 5659980083465412500,
- "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_year.py": 17441853503700184299,
- "venv/lib/python3.13/site-packages/pygments/lexers/julia.py": 13516407944275342328,
- "frontend/src/routes/+layout.ts": 8392799000856778740,
- "frontend/build/_app/immutable/nodes/22.CZgjFTnE.js": 15851348200685649144,
- "frontend/build/_app/immutable/chunks/C9EOgT5J.js": 5509721048432890523,
- "venv/lib/python3.13/site-packages/greenlet/greenlet.h": 16216120538647882082,
- "venv/lib/python3.13/site-packages/_pytest/unraisableexception.py": 4597178803320514675,
- "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp.py": 16797760903996739079,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/__init__.py": 8705044848308260480,
- "frontend/build/_app/immutable/chunks/D2LDFDH5.js": 1513005501777757570,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_data.py": 2397937327057341,
- "venv/lib/python3.13/site-packages/pygments/lexers/dotnet.py": 17970884907837213099,
- "venv/lib/python3.13/site-packages/pip/_vendor/typing_extensions.py": 10158933506062403688,
- "venv/lib/python3.13/site-packages/pydantic/aliases.py": 14481980467204711659,
- "venv/lib/python3.13/site-packages/jeepney/tests/test_fds.py": 6257376331171761928,
- "frontend/src/components/DynamicForm.svelte": 2120031570302269345,
- "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_timestamp.py": 12253372102602993034,
- "venv/lib/python3.13/site-packages/gitdb/test/test_pack.py": 7518388297247535189,
- "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_struct_accessor.py": 6567451952835390075,
- "frontend/eslint.config.js": 14296985543214702398,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_callback.py": 1689177048527329209,
- "venv/lib/python3.13/site-packages/pandas/core/strings/__init__.py": 13025387151657797130,
- "venv/lib/python3.13/site-packages/numpy/core/shape_base.py": 17925759824894973734,
- "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_defmatrix.py": 2982572083770917411,
- "venv/lib/python3.13/site-packages/pandas/core/accessor.py": 1188716996113179524,
- "frontend/src/lib/stores/__tests__/test_datasetReviewSession.js": 8646274524484627210,
- "venv/lib/python3.13/site-packages/pygments/style.py": 17393199235575070210,
- "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/resource_protector.py": 14354891358060085360,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/quoted_character/foo.f": 15318083678609435813,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_indexing.py": 16623126293364224089,
- "backend/src/scripts/seed_permissions.py": 2299443594185631497,
- "backend/src/api/routes/__tests__/test_clean_release_api.py": 8153144254371183034,
- "backend/src/plugins/translate/dictionary_validation.py": 16674754716565921261,
- "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.cpython-313-x86_64-linux-gnu.so": 9380059465932560412,
- "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/INSTALLER": 17282701611721059870,
- "backend/tests/test_translate_corrections.py": 6483644195889451514,
- "backend/src/scripts/init_auth_db.py": 8910351541713877041,
- "venv/lib/python3.13/site-packages/pydantic/tools.py": 8931184638883701008,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_py.py": 13809503317864539103,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_stride_tricks.py": 1064774375151677743,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_iter.py": 9232021002336641851,
- "venv/lib/python3.13/site-packages/typing_inspection/py.typed": 15130871412783076140,
- "frontend/src/routes/admin/settings/llm/+page.svelte": 17653948269643098768,
- "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/functions.py": 14107377669163193871,
- "venv/lib/python3.13/site-packages/pygments/lexers/yara.py": 17510792615476493957,
- "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/licenses/LICENSE": 14524289631770661180,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/__init__.pyi": 15130871412783076140,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_abc.py": 10164280045317807365,
- "backend/git_repos/remote/test-repo.git/refs/heads/feature/test": 7714224145564125988,
- "backend/git_repos/remote/test-repo.git/refs/heads/dev": 8596267258668462395,
- "frontend/build/_app/immutable/nodes/2.ygKEcgXs.js": 4758071082823820713,
- "backend/:memory:test_main": 8120796031785944903,
- "venv/lib/python3.13/site-packages/numpy/f2py/_backends/__init__.py": 4265012785873472600,
- "venv/lib/python3.13/site-packages/jsonschema/benchmarks/__init__.py": 5863110456909134678,
- "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/resource_protector.py": 17080006010679257864,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_misc.pyi": 7544619194032232861,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/warnings_and_errors.pyi": 3151453262733619734,
- "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.py": 9654828595008925976,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_docs.py": 17898499890274685198,
- "venv/lib/python3.13/site-packages/pandas/tests/io/excel/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pandas/core/tools/times.py": 6560679305255812809,
- "venv/lib/python3.13/site-packages/pydantic/_internal/_signature.py": 17075003201648027250,
- "venv/lib/python3.13/site-packages/pandas/core/window/expanding.py": 14141093310397856286,
- "venv/lib/python3.13/site-packages/PIL/_webp.cpython-313-x86_64-linux-gnu.so": 11070012119632935103,
- "frontend/src/components/git/BranchSelector.svelte": 2850678079887313044,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/scalar_string.f90": 15018631706178918578,
- "venv/lib/python3.13/site-packages/numpy/random/_mt19937.pyi": 15904463104068500379,
- "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/__main__.py": 6480933938145689964,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/coercions.py": 5112358449376598662,
- "venv/lib/python3.13/site-packages/PIL/TgaImagePlugin.py": 9208942494595222259,
- "venv/bin/activate.fish": 5275961582873298085,
- "frontend/build/_app/immutable/chunks/Ct73Sust.js": 3385889491616825090,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunclike.pyi": 14623308681600207918,
- "venv/lib/python3.13/site-packages/pandas/_libs/json.cpython-313-x86_64-linux-gnu.so": 2436285663630821963,
- "venv/lib/python3.13/site-packages/authlib/common/urls.py": 13627272625165922482,
- "venv/lib/python3.13/site-packages/pip/_internal/metadata/__init__.py": 8924316361489544973,
- "venv/lib/python3.13/site-packages/rsa/prime.py": 10820898885044917095,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_argsort.py": 7320661835159648143,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_m68k_gcc.h": 6580173800099450404,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/urls.py": 8698341051522816167,
- "venv/lib/python3.13/site-packages/referencing/tests/test_exceptions.py": 10846225989746274213,
- "backend/src/models/dataset_review_pkg/_finding_models.py": 13502025287982574359,
- "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/base_server.py": 9643197259080504542,
- "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py": 14946223589457772924,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_casting_floatingpoint_errors.py": 4301355720042319835,
- "venv/lib/python3.13/site-packages/jose/utils.py": 1926138853970725083,
- "frontend/src/lib/ui/Input.svelte": 1114920008107220678,
- "venv/lib/python3.13/site-packages/PIL/ImageTk.py": 17063969714816564357,
- "venv/lib/python3.13/site-packages/pygments/styles/onedark.py": 17580335614588531275,
- "venv/lib/python3.13/site-packages/passlib/tests/__init__.py": 16543763165305017760,
- "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_ndarray.py": 6863874753941288585,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunclike.py": 12077553320554633586,
- "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.py": 5221550291012182443,
- "venv/lib/python3.13/site-packages/PIL/ImageQt.py": 6607270889359138659,
- "venv/lib/python3.13/site-packages/websockets/sync/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pygments/styles/trac.py": 13968346768164381833,
- "venv/lib/python3.13/site-packages/numpy/_core/multiarray.pyi": 3494871767602648807,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/pycparser/c_lexer.py": 10964496587169353564,
- "venv/lib/python3.13/site-packages/numpy/core/fromnumeric.py": 2136433423902202138,
- "frontend/src/assets/svelte.svg": 13872699371039797074,
- "venv/lib/python3.13/site-packages/pygments/lexers/testing.py": 17148598391210353576,
- "backend/git_repos/remote/test-repo.git/objects/f7/6ee984d9d47c3cd0b362fdf60a47162bbc202d": 5351983130474596028,
- "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.py": 652332294655046106,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler_py.py": 16189204441438239231,
- "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_strptime.py": 14328510310436552635,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/hashes.py": 17310331665429541812,
- "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.pyi": 13068936038543812082,
- "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.py": 2490579175967301457,
- "frontend/src/routes/datasets/review/useReviewSession.js": 2360677870127730232,
- "venv/lib/python3.13/site-packages/pandas/tests/strings/test_find_replace.py": 262184394614748386,
- "venv/lib/python3.13/site-packages/pip/_vendor/distlib/markers.py": 8297667990263004097,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename.py": 4890779493250245903,
- "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_merge_asof.py": 8656532774394927388,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/numeric.py": 17834058423729918687,
- "backend/src/scripts/__init__.py": 5400372851656282343,
- "venv/lib/python3.13/site-packages/annotated_doc/main.py": 3384049281532298500,
- "venv/lib/python3.13/site-packages/_pytest/pytester_assertions.py": 1899505062406979663,
- "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/misc.py": 6571241778569465264,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/datetime.py": 6816292030061301011,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/__init__.py": 635200170992032966,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/test_custom_dtypes.py": 12322100282959605055,
- "venv/lib/python3.13/site-packages/pillow.libs/libfreetype-ee1c40c4.so.6.20.4": 12301510769231120312,
- "venv/lib/python3.13/site-packages/_pytest/_code/source.py": 9488112979192923739,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_astype.py": 7497268667246913350,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/util.py": 10640907133050862176,
- "venv/lib/python3.13/site-packages/PIL/ExifTags.py": 6869879826623916830,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/rec.pyi": 14615751247243515028,
- "venv/lib/python3.13/site-packages/numpy/_array_api_info.py": 9709101823494959741,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/_utils.py": 11574890848475750509,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_unique.py": 16285418015531891530,
- "venv/lib/python3.13/site-packages/numpy/__config__.pyi": 1422114139050700402,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/AB.inc": 10441778083831997423,
- "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_hermite.py": 3628609433179387988,
- "backend/src/plugins/translate/superset_executor.py": 5480256123348033488,
- "frontend/src/routes/datasets/[id]/+page.svelte": 7539252327680602221,
- "venv/lib/python3.13/site-packages/passlib/utils/md4.py": 4521366665754877351,
- "venv/lib/python3.13/site-packages/pandas/core/sparse/api.py": 9094651265692218821,
- "venv/lib/python3.13/site-packages/psycopg2/__init__.py": 15798412693009721199,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/integer.py": 7775055011080964709,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_arithmetic.py": 13304014482504911016,
- "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/WHEEL": 5076688779572520166,
- "venv/lib/python3.13/site-packages/numpy/ma/README.rst": 13203411621071845216,
- "venv/lib/python3.13/site-packages/anyio/_backends/_trio.py": 4764555436057754985,
- "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/index_tricks.pyi": 6035507586990711471,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/RECORD": 6187512110158566509,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tz_localize.py": 13699016868476153393,
- "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/__init__.py": 11121941644106061453,
- "frontend/src/services/toolsService.js": 1568142461283466080,
- "venv/lib/python3.13/site-packages/pip/_internal/utils/unpacking.py": 106471890743211548,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/__init__.py": 15130871412783076140,
- "backend/src/plugins/translate/preview_token_estimator.py": 254295902082954386,
- "backend/git_repos/remote/test-repo.git/hooks/update.sample": 8204581436750313444,
- "venv/lib/python3.13/site-packages/pydantic/dataclasses.py": 12384956801113860889,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi": 7385072545198817771,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_names.py": 10037208029090713121,
- "venv/lib/python3.13/site-packages/pygments/lexers/templates.py": 16267123844830647955,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/pager.py": 18072372651585577904,
- "venv/lib/python3.13/site-packages/pandas/io/excel/_calamine.py": 13354427767660487637,
- "backend/src/services/llm_prompt_templates.py": 16176053862101644239,
- "venv/lib/python3.13/site-packages/authlib/oidc/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/licenses/LICENSE": 10253862887434903467,
- "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.py": 12251264586530536622,
- "venv/lib/python3.13/site-packages/jeepney/io/common.py": 15160647397460834508,
- "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/__init__.py": 4290669519959060720,
- "venv/lib/python3.13/site-packages/websockets/cli.py": 14049106025886056110,
- "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.py": 18402126171936308228,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/mt19937-testset-2.csv": 14641856424618845798,
- "venv/lib/python3.13/site-packages/numpy/_core/strings.py": 3623885046208831106,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.obj": 11967637259540485652,
- "venv/lib/python3.13/site-packages/numpy/_core/_asarray.py": 3468915833437229425,
- "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/__init__.py": 18036348770966744795,
- "venv/lib/python3.13/site-packages/attr/_make.py": 2348458829123990579,
- "venv/lib/python3.13/site-packages/websockets/asyncio/compatibility.py": 9716993942839407921,
- "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_searchsorted.py": 11208047646304753715,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/named_types.py": 6099185243355915896,
- "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.py": 7352635707860427145,
- "venv/lib/python3.13/site-packages/pandas/core/dtypes/cast.py": 342228968652072052,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/test_indexing.py": 13703573544185051910,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_kurt.py": 2898715045429898166,
+ "venv/lib/python3.13/site-packages/pandas/io/xml.py": 326466573926392764,
+ "frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js": 15166117912533507471,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/aioodbc.py": 12704729841432715246,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/glibc.py": 12335359492756627313,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_subclass.py": 10949229764696473939,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_libsparse.py": 1859997684694949029,
+ "frontend/src/routes/datasets/review/ReviewWorkspaceRightRail.svelte": 13437011381072252917,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/__init__.py": 8811477458865810434,
+ "venv/lib/python3.13/site-packages/numpy/testing/tests/__init__.py": 15130871412783076140,
"venv/lib/python3.13/site-packages/pandas/tests/indexing/test_chaining_and_caching.py": 15814259766479305290,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_index.py": 4908727359687606870,
+ "backend/src/core/__tests__/test_superset_preview_pipeline.py": 13996819877413389729,
+ "backend/src/models/llm.py": 4879429354068794925,
+ "venv/lib/python3.13/site-packages/pyasn1/error.py": 11036037300994516747,
+ "venv/lib/python3.13/site-packages/requests/packages.py": 7733041271118298220,
+ "frontend/e2e/run-enterprise-clean-e2e.sh": 11626901202531925046,
+ "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/METADATA": 13776251749114562660,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_schema_gather.py": 3634138701088855517,
+ "venv/lib/python3.13/site-packages/numpy/ma/__init__.py": 214772578978182427,
+ "venv/lib/python3.13/site-packages/pygments/styles/borland.py": 17570558758932580659,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py": 7019253290755243568,
+ "venv/lib/python3.13/site-packages/requests/adapters.py": 17161109043243436200,
+ "venv/lib/python3.13/site-packages/psycopg2/_range.py": 7184417109068014771,
+ "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.pyi": 2744889206277418389,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.pyi": 17903213294220335051,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/formatter.py": 16499277113779414101,
+ "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.py": 2953876934840155920,
+ "venv/lib/python3.13/site-packages/numpy/_core/einsumfunc.pyi": 4729765666018003634,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/__init__.py": 15130871412783076140,
+ "frontend/build/_app/immutable/nodes/9.gqc4AufS.js": 5960943542680280016,
+ "venv/lib/python3.13/site-packages/numpy/_core/_internal.py": 13056946834347643109,
+ "backend/src/api/routes/maintenance/_routes.py": 18203881358318110485,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_nonkeyword_arguments.py": 11676809974120007408,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/mongodb.py": 5310116401542377882,
+ "venv/lib/python3.13/site-packages/smmap/test/test_mman.py": 8977119225749253844,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro.pyi": 3145980717589050713,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/entrypoints.py": 11268059714209889385,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_reductions.py": 2816859231048302619,
+ "venv/lib/python3.13/site-packages/pluggy/py.typed": 15130871412783076140,
"venv/lib/python3.13/site-packages/pygments/lexers/j.py": 9766594937623918053,
- "venv/lib/python3.13/site-packages/pygments/lexers/configs.py": 7712797939104760185,
- "frontend/src/lib/components/layout/Breadcrumbs.svelte": 8720668241659707399,
- "backend/src/services/health_service.py": 7707107506464919176,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_factorize.py": 5585211699185937865,
- "venv/lib/python3.13/site-packages/sqlalchemy/sql/_py_util.py": 12836989066113400538,
- "frontend/e2e/tests/live-project-check.e2e.js": 6182929777704468013,
- "backend/git_repos/remote/test-repo.git/objects/8c/4ea7958b7a7e140d27e1e7d8d1f9912fdf5992": 5862166356451798197,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_multiplier.f": 13432803601367981068,
- "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/__init__.py": 4390908730288159455,
- "venv/lib/python3.13/site-packages/_pytest/pastebin.py": 13946273207624603063,
- "venv/lib/python3.13/site-packages/pygments/styles/solarized.py": 11231143047572616298,
- "frontend/e2e/tests/smoke.e2e.js": 2195997260227657104,
- "venv/lib/python3.13/site-packages/jeepney/tests/__init__.py": 15130871412783076140,
- "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/zip-safe": 15240312484046875203,
- "frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js": 4930404579577741926,
- "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_aix.h": 8706347224105630468,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/protocol.py": 932296179250981622,
- "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_pbkdf2.py": 4977067068389993374,
- "venv/lib/python3.13/site-packages/_pytest/_io/saferepr.py": 8025234471485188730,
- "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64-testset-1.csv": 16078879475693341404,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reshape.py": 10576230966727810832,
- "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming_py.py": 16133454512601432815,
- "venv/lib/python3.13/site-packages/greenlet/tests/fail_initialstub_already_started.py": 5562030563802006923,
- "venv/lib/python3.13/site-packages/greenlet/PyGreenlet.hpp": 6366432579621298231,
- "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/INSTALLER": 17282701611721059870,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args_and_kwargs.py": 3381939712123764154,
- "venv/lib/python3.13/site-packages/pandas/tests/generic/test_to_xarray.py": 15341013524814290960,
+ "venv/lib/python3.13/site-packages/_pytest/logging.py": 10972553724755511468,
+ "venv/lib/python3.13/site-packages/keyring/backends/libsecret.py": 11621088556661567306,
+ "venv/lib/python3.13/site-packages/numpy/core/umath.py": 4476812261188108155,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/ops.py": 13451323660386712332,
+ "venv/lib/python3.13/site-packages/yaml/reader.py": 9873075843010693205,
+ "venv/lib/python3.13/site-packages/pygments/lexers/usd.py": 934820244673741695,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/__init__.py": 14571251344510763303,
+ "venv/lib/python3.13/site-packages/pydantic/typing.py": 6661252174518316760,
+ "venv/lib/python3.13/site-packages/httpx/_status_codes.py": 1758440600462491839,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/schema.py": 5391655516870611151,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/hashes.py": 8545380307201732345,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunclike.pyi": 12215374902556647369,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_scrypt.py": 8106466515670064013,
+ "venv/lib/python3.13/site-packages/git/objects/submodule/root.py": 5322248117564025370,
+ "venv/lib/python3.13/site-packages/git/index/base.py": 641556304637379636,
+ "venv/lib/python3.13/site-packages/attr/_version_info.py": 3850449653182103457,
+ "venv/lib/python3.13/site-packages/smmap/buf.py": 18231775424238352734,
+ "frontend/build/_app/immutable/nodes/18.CyOFIVFf.js": 2394236541224813694,
+ "venv/lib/python3.13/site-packages/yaml/representer.py": 10550136298978225013,
+ "backend/src/api/routes/translate/_run_routes.py": 16216908966766661647,
+ "backend/src/plugins/translate/_batch_sizer.py": 13074277127276828485,
+ "venv/lib/python3.13/site-packages/numpy/ma/core.pyi": 4829891173366130328,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/METADATA": 12295263493152296681,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_musllinux.py": 2423350951094915747,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/parse.py": 819235411736647763,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.cpython-313-x86_64-linux-gnu.so": 17089839649971421164,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein.py": 15426828792217499138,
+ "venv/lib/python3.13/site-packages/dateutil/zoneinfo/rebuild.py": 1813298167468704155,
+ "venv/lib/python3.13/site-packages/authlib/integrations/requests_client/utils.py": 2959395751217827103,
+ "venv/lib/python3.13/site-packages/uvicorn/workers.py": 7213290478118197047,
+ "frontend/build/_app/immutable/chunks/BN27KiHS.js": 7591779568493961830,
+ "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/licenses/AUTHORS": 17022185907188244883,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_stringdtype.py": 8381476847196129074,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/interface.py": 3134071530627935964,
+ "frontend/src/lib/ui/HelpTooltip.svelte": 15082693035830243831,
+ "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pxd": 14261507718442469988,
+ "backend/src/core/auth/logger.py": 13549160352454060608,
+ "venv/lib/python3.13/site-packages/pydantic/validators.py": 8292819706488319845,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.pyi": 13083543811193933305,
+ "examples/maintenance-api-python.py": 18279360934407602079,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_subclass.py": 13490541871827928531,
+ "frontend/src/lib/components/health/ScheduleAtAGlance.svelte": 2047418178814771337,
+ "venv/lib/python3.13/site-packages/pydantic/warnings.py": 5142352784799639092,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_discriminated_union.py": 1818179910730401509,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_clip.py": 13498704233745189154,
+ "frontend/build/_app/immutable/chunks/2dOUpm6k.js": 11811637653151731489,
+ "venv/lib/python3.13/site-packages/pandas/_config/dates.py": 3863381688916127265,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/console.py": 10217327186846649646,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/padding.py": 13763154154862871596,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/test_pyinstaller.py": 9430762168079129025,
+ "venv/lib/python3.13/site-packages/pygments/lexers/webmisc.py": 9530962803076253849,
+ "backend/src/api/routes/dashboards/_detail_routes.py": 3246373568851818130,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_common.py": 8987965560487646705,
+ "venv/lib/python3.13/site-packages/six.py": 948867418687428421,
+ "venv/lib/python3.13/site-packages/numpy/f2py/auxfuncs.py": 2234931733687557433,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_css_builtins.py": 17478340487186531268,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/categorical.py": 15993211255162930859,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ufunc_config.pyi": 11754104063443791746,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_indexing.py": 3841182456456779012,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_indexing.py": 14461606056665485421,
+ "venv/lib/python3.13/site-packages/idna-3.11.dist-info/WHEEL": 8600534672961461758,
+ "venv/lib/python3.13/site-packages/dotenv/py.typed": 9796674040111366709,
+ "venv/lib/python3.13/site-packages/httpcore/_async/http2.py": 16350817785499681224,
+ "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.py": 5260748170237305627,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.py": 5933622200264572885,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_validators.py": 2939255306814626438,
+ "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/WHEEL": 7314207500206292683,
+ "venv/lib/python3.13/site-packages/pygments/lexers/bdd.py": 5389493859905397060,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py": 7906029092844029127,
+ "backend/src/api/routes/git/_environment_routes.py": 5687847761729712859,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/fuzz_validate.py": 2328585939822059352,
+ "backend/src/services/reports/__tests__/test_report_normalizer.py": 5081647081006613913,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_isin.py": 8136794647591341784,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/package_data.py": 3078502124870585867,
+ "venv/lib/python3.13/site-packages/sqlalchemy/exc.py": 6372950288664776625,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/__init__.py": 5118993772178969104,
+ "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.py": 5564496700647900501,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/category.py": 18192569199634406001,
+ "venv/lib/python3.13/site-packages/yaml/serializer.py": 1783761365703703558,
+ "frontend/src/routes/datasets/__tests__/StatsBar.test.js": 16218511958634350787,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ndarray_assignability.pyi": 1718610984396277997,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-2.csv": 4052796393463357888,
+ "backend/tests/test_auth.py": 18059959539697963472,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_macosx.h": 3653129798702716366,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/issue232.py": 6498198296113395367,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_types.py": 651959450717569029,
+ "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/RECORD": 17985800801793506250,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ma.pyi": 8186102816080813799,
+ "frontend/e2e/helpers/api.helper.js": 12740720187461301874,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_file_buffer_url.py": 15377043158761455858,
+ "backend/git_repos/remote/test-repo.git/hooks/pre-applypatch.sample": 15598058327720909861,
+ "venv/lib/python3.13/site-packages/gitdb/pack.py": 7828244200815444166,
+ "frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js": 7475597145566385341,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_julia_builtins.py": 8846111188795315103,
+ "venv/lib/python3.13/site-packages/_pytest/junitxml.py": 5871715626272366062,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/compat.py": 17520043776344667309,
+ "venv/lib/python3.13/site-packages/yaml/__init__.py": 11044333164208875121,
+ "venv/lib/python3.13/site-packages/jaraco/classes/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_parser.py": 8145921552236189367,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_format.py": 16150524965028369071,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_masked_matrix.py": 1444179242134203344,
+ "venv/lib/python3.13/site-packages/numpy/ma/extras.py": 7559838309481824664,
+ "venv/lib/python3.13/site-packages/pydantic_settings/main.py": 17272314000918984790,
+ "venv/lib/python3.13/site-packages/pillow.libs/libzstd-761a17b6.so.1.5.7": 17875236748140157032,
+ "venv/lib/python3.13/site-packages/click/_utils.py": 16491408631876616271,
+ "venv/lib/python3.13/site-packages/rpds/__init__.py": 5862197328247012275,
+ "venv/lib/python3.13/site-packages/pydantic/schema.py": 83238111330132033,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/__init__.py": 11157967642611612522,
+ "venv/lib/python3.13/site-packages/more_itertools/__init__.pyi": 16479506520351014608,
+ "frontend/src/routes/dashboards/[id]/+page.svelte": 2328002918662170835,
+ "frontend/src/routes/reports/llm/[taskId]/+page.svelte": 809594987288256163,
+ "backend/src/api/routes/git/_router.py": 14821560101452369211,
+ "backend/src/services/rbac_permission_catalog.py": 11280653389166352517,
+ "venv/lib/python3.13/site-packages/pandas/_libs/parsers.pyi": 18402185996588014111,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_envs.py": 5657151394155576509,
+ "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_zips.py": 5184894018177148648,
+ "frontend/build/_app/immutable/chunks/DgoIDw4h.js": 10605176285482573925,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval_new.py": 3893421355544517336,
+ "venv/lib/python3.13/site-packages/pycparser-2.23.dist-info/METADATA": 3474626408138844944,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_easter.py": 3397863170068576196,
+ "backend/git_repos/remote/test-repo.git/refs/heads/feature/e2e-update": 9577764946931187657,
+ "frontend/src/routes/settings/EnvironmentsTab.svelte": 13575164255656888464,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/array_with_attr/array.py": 13040461386712513615,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_real.py": 5283415082530228716,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/__init__.py": 11850945878149145990,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_from_scalar.py": 16520136036631155842,
+ "venv/lib/python3.13/site-packages/numpy/_typing/__init__.py": 18242238390157333247,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/meta-data": 9599129816090399315,
+ "venv/lib/python3.13/site-packages/passlib/handlers/django.py": 66638338316838351,
+ "venv/lib/python3.13/site-packages/packaging/_parser.py": 13394093358675095309,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_almost_equal.py": 9333355453468475330,
+ "venv/lib/python3.13/site-packages/apscheduler/events.py": 10748346950729364899,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/ops.py": 2036968385544457016,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_select.py": 17823338162428379468,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_dtype.py": 12210524152630532747,
+ "venv/lib/python3.13/site-packages/pygments/util.py": 4815334059917765852,
+ "venv/lib/python3.13/site-packages/httpx/_decoders.py": 14478643473006178492,
+ "backend/:memory:test_auth": 1309242367339970214,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/loading.py": 3460142472461437916,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_win32_console.py": 18092547253031555768,
+ "frontend/build/_app/immutable/nodes/22.2G--WUWt.js": 8100099250827052249,
+ "venv/lib/python3.13/site-packages/numpy/random/c_distributions.pxd": 16574161095720077595,
+ "frontend/playwright-report/data/b13be72bc9111c369dd61bcb4b41565873341170.zip": 9286336518597330572,
+ "venv/lib/python3.13/site-packages/httpx/_urls.py": 4219389176352582046,
+ "venv/lib/python3.13/site-packages/PIL/TarIO.py": 13651401276968618561,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_api.py": 7131036004750554905,
+ "venv/lib/python3.13/site-packages/websockets/cli.py": 14049106025886056110,
+ "venv/lib/python3.13/site-packages/numpy/lib/scimath.pyi": 18165025261847276375,
+ "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.py": 3001896031623204147,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/histograms.pyi": 9255620158831643201,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/json_schema_test_suite.py": 6152158310190822762,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/foo.f90": 14491312943942432024,
+ "backend/src/core/superset_client/_base.py": 8704044125468217140,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_frame.py": 9378623452601244234,
+ "backend/src/plugins/llm_analysis/__tests__/test_client_headers.py": 6499914987034257707,
+ "venv/lib/python3.13/site-packages/click/types.py": 6491651131669287534,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arcsinh.csv": 13695545125848146013,
+ "venv/lib/python3.13/site-packages/passlib/utils/compat/__init__.py": 17369882236606423129,
+ "merge_spec.py": 13855568343782022,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_values.py": 430620320423334461,
"venv/lib/python3.13/site-packages/pydantic/plugin/_schema_validator.py": 857640644840976862,
- "venv/lib/python3.13/site-packages/numpy/_core/_dtype_ctypes.pyi": 14543653817631274394,
- "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/auth.py": 13542332344403032059,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24008.f": 3872245077994936272,
- "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_quoting.py": 1147992698412929658,
- "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_repr.py": 11737029058271003097,
- "venv/lib/python3.13/site-packages/pycparser/__init__.py": 16499940957411260458,
- "venv/lib/python3.13/site-packages/pygments/formatters/irc.py": 2133711525226123259,
- "frontend/playwright-report/data/d3248d538f098a40b756ead1ee1a92a7d61e7c7a.zip": 661058595618012246,
+ "venv/lib/python3.13/site-packages/numpy/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_insert.py": 6970975909565157982,
+ "venv/lib/python3.13/site-packages/pytest/__init__.py": 6137272437722350673,
+ "venv/lib/python3.13/site-packages/numpy/lib/_array_utils_impl.pyi": 11535882608355652318,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_gc.py": 6383305344377882524,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_isin.py": 14387850595546682314,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_shift.py": 14681514853406253657,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_na_values.py": 13527837495439739279,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/parsing.pyi": 11967691665766452312,
+ "venv/lib/python3.13/site-packages/PIL/XVThumbImagePlugin.py": 7472134175570205454,
+ "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/WHEEL": 9788895026336324100,
+ "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/METADATA": 8128818962678047497,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/array_ops.py": 10061020479033421596,
+ "frontend/e2e/tests/smoke.e2e.js": 11376448043256596939,
+ "scripts/build_offline_docker_bundle.sh": 1393881756263325163,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_numpy.py": 9663734591667845940,
+ "venv/lib/python3.13/site-packages/_pytest/python.py": 1829073958095716309,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_mock_val_ser.py": 12265320534388472158,
+ "frontend/build/_app/immutable/assets/0.DK5emaTL.css": 4565146476878643834,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/writeonly.py": 14213960431308620600,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_datetime.py": 7456744745424297814,
+ "backend/src/api/routes/dashboards/_projection.py": 9178951020532547334,
+ "venv/lib/python3.13/site-packages/PIL/_imagingft.cpython-313-x86_64-linux-gnu.so": 11054435406031360190,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/parameters.py": 1647490964392525933,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_get_dummies.py": 16112674981222844375,
+ "frontend/src/routes/settings/MigrationMappingsTable.svelte": 574459541553883663,
+ "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/base.py": 15872835330892203433,
+ "venv/lib/python3.13/site-packages/pygments/lexers/c_cpp.py": 1211842877043321095,
+ "venv/lib/python3.13/site-packages/numpy/_core/shape_base.pyi": 10225243791643474943,
+ "venv/lib/python3.13/site-packages/numpy/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parse_iso8601.py": 9100947620267156161,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/pyodbc.py": 11271266527234292020,
+ "venv/lib/python3.13/site-packages/jaraco/classes/ancestry.py": 11742194518360056470,
+ "venv/lib/python3.13/site-packages/authlib/common/security.py": 2291133227104016684,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_emoji_replace.py": 8166203537440976347,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_period.py": 6255181868181182780,
+ "venv/bin/f2py": 11006035631504708368,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authorization_server.py": 13696038495666024258,
+ "venv/lib/python3.13/site-packages/numpy/_core/shape_base.py": 3996519099530770308,
+ "backend/src/services/clean_release/__tests__/test_source_isolation.py": 462142504664192849,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pop.py": 5700439923973346681,
+ "backend/src/plugins/translate/dictionary_import_export.py": 12639118203353044308,
+ "venv/lib/python3.13/site-packages/numpy/fft/__init__.py": 9343449448737026658,
+ "frontend/src/components/Navbar.svelte": 2640465687592983765,
+ "venv/lib/python3.13/site-packages/numpy/ma/mrecords.py": 687170905107114309,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/specifiers.py": 12284901056355482991,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_console.py": 11657469008721907972,
+ "venv/lib/python3.13/site-packages/pydantic/type_adapter.py": 10162988530225478692,
+ "venv/lib/python3.13/site-packages/passlib/utils/des.py": 2650106381178222229,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_attr_equal.py": 5612259834202470413,
+ "venv/lib/python3.13/site-packages/PIL/AvifImagePlugin.py": 1872412416505003364,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/flatiter.py": 3066469329738423021,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_regression.py": 12593643817685777170,
+ "venv/lib/python3.13/site-packages/numpy/lib/introspect.py": 5706729538356302335,
+ "venv/lib/python3.13/site-packages/pandas/tseries/api.py": 14785127136180503704,
+ "venv/lib/python3.13/site-packages/pygments/lexers/gleam.py": 5161116162065925222,
+ "frontend/src/services/git-utils.js": 12982149055119314642,
+ "venv/lib/python3.13/site-packages/numpy/lib/_utils_impl.pyi": 15767546107856827543,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/shape_base.pyi": 5046405609030418900,
+ "venv/lib/python3.13/site-packages/numpy/random/_mt19937.cpython-313-x86_64-linux-gnu.so": 85866616759631810,
+ "backend/src/services/maintenance/__init__.py": 3167476255502727608,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/connection.py": 5582413226288987808,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/rec/__init__.py": 7467092880535460658,
+ "venv/lib/python3.13/site-packages/passlib/ext/django/__init__.py": 11713862539944289631,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/_py_processors.py": 16557117595879208702,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.pyi": 9003794318682878317,
+ "venv/lib/python3.13/site-packages/PIL/DdsImagePlugin.py": 10646832373516499548,
+ "venv/lib/python3.13/site-packages/pygments/lexers/diff.py": 5930189593946259160,
+ "scripts/scan_secrets.sh": 10827095619853567115,
+ "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/METADATA": 7727489762869155085,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/check.py": 16650663913976953800,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA_py.py": 2494967094400350388,
+ "venv/lib/python3.13/site-packages/pydantic_settings/utils.py": 14396350455520958703,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_get_level_values.py": 12490886203425393290,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/index_tricks.pyi": 11463747060334597941,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas7bdat.py": 8963983384208121526,
+ "venv/lib/python3.13/site-packages/h11/_events.py": 13800479928851716538,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_str.py": 149688376805129532,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_astype.py": 15275720655739710249,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/psycopg.py": 8023549900603235601,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/datetimes.py": 10585034798097337148,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/chararray.pyi": 9683985931409244216,
+ "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_ios.h": 6751259472945638998,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/box.py": 14303526978791498662,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/index_tricks.pyi": 6035507586990711471,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion": 2607512361823362698,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.py": 15558318749939680074,
+ "venv/lib/python3.13/site-packages/uvicorn/middleware/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/fastapi/utils.py": 15402403831700548944,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_cov_corr.py": 13652339565475304679,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_decorators_v1.py": 16723743964226526155,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_cpu.h": 13799366908726531089,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/defmatrix.py": 4940170059946018356,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_timer.py": 8196003526646080498,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.py": 7446626038222262489,
+ "venv/lib/python3.13/site-packages/pandas/core/tools/datetimes.py": 13313374952742129866,
+ "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/dotenv/variables.py": 5438726379749803751,
+ "venv/lib/python3.13/site-packages/pygments/lexers/chapel.py": 7619603166448145621,
+ "venv/lib/python3.13/site-packages/pygments/lexers/zig.py": 470431199354307668,
+ "frontend/src/routes/validation/[id]/+page.svelte": 17573557905368368906,
+ "backend/src/core/async_superset_client.py": 339440171038902146,
+ "backend/src/services/profile_preference_service.py": 6413505886389479915,
+ "venv/lib/python3.13/site-packages/pygments/lexers/hare.py": 8693002231020751711,
+ "frontend/src/lib/stores/datasetReviewSession.js": 12759266804307584180,
+ "backend/src/core/utils/fileio.py": 8848681882907859355,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py": 9627328185578406121,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/__init__.py": 5863110456909134678,
+ "venv/lib/python3.13/site-packages/psycopg2/errorcodes.py": 6711830404954314463,
+ "venv/lib/python3.13/site-packages/idna/__init__.py": 6489437464172324468,
+ "venv/lib/python3.13/site-packages/jose/backends/base.py": 12795468809472351388,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/dml.py": 6519732236745017861,
+ "venv/lib/python3.13/site-packages/gitdb/test/test_pack.py": 7518388297247535189,
+ "venv/lib/python3.13/site-packages/attr/_config.py": 1864824728504480204,
+ "venv/lib/python3.13/site-packages/numpy/linalg/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/licenses/LICENSE": 5669644120528099197,
+ "venv/lib/python3.13/site-packages/pygments/formatters/other.py": 13124903290103898118,
+ "venv/lib/python3.13/site-packages/numpy/_utils/_convertions.py": 12886275429547303345,
+ "venv/lib/python3.13/site-packages/pygments/lexers/apl.py": 16767474673619335683,
+ "venv/lib/python3.13/site-packages/pygments/lexers/xorg.py": 14591144191879110061,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/conftest.py": 3691712173202219606,
+ "venv/lib/python3.13/site-packages/cryptography/x509/__init__.py": 4066756344049307453,
+ "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/format_control.py": 12916176880659590456,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_timedelta64.py": 16821719402662529276,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_convert.py": 77283525137564255,
+ "venv/lib/python3.13/site-packages/packaging/_tokenizer.py": 7442392076059866359,
+ "frontend/src/routes/git/+page.svelte": 3351712750068549963,
+ "venv/lib/python3.13/site-packages/httpcore/_async/http11.py": 7565741048880549265,
+ "backend/src/scripts/clean_release_tui.py": 3006670970245009659,
+ "backend/git_repos/remote/test-repo.git/hooks/pre-merge-commit.sample": 10013699873067956556,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/filepost.py": 16698380375728063923,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending.pyx": 756189645898997788,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_astype.py": 4178231007649608531,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_monotonic.py": 11817523305776951162,
+ "venv/lib/python3.13/site-packages/cffi/verifier.py": 8473599757770867754,
+ "venv/lib/python3.13/site-packages/numpy/_core/_umath_tests.cpython-313-x86_64-linux-gnu.so": 3478629877770507853,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/der/decoder.py": 11876648884087997745,
+ "venv/lib/python3.13/site-packages/psycopg2/tz.py": 9966680685796585198,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh25337/data.f90": 13833561828029901615,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/sas/test_sas.py": 9446226619493404132,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/characteristics.py": 2916810597149066609,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/types.py": 16795741817129898714,
+ "venv/lib/python3.13/site-packages/git/__init__.py": 15867730798565725003,
+ "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/WHEEL": 16784970174376303810,
+ "frontend/src/routes/settings/SystemSettings.svelte": 17084926955388049976,
+ "backend/src/core/task_manager/manager.py": 1504518197419779491,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py": 14946223589457772924,
+ "venv/lib/python3.13/site-packages/pandas/util/_doctools.py": 3766479022075611396,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/concurrency.py": 1325673503812009695,
+ "venv/lib/python3.13/site-packages/numpy/_core/records.py": 11414828908088050950,
+ "venv/lib/python3.13/site-packages/pygments/lexers/gdscript.py": 12775803139854052838,
+ "frontend/src/lib/stores/__tests__/setupTests.js": 16228706107748081093,
+ "venv/lib/python3.13/site-packages/requests/utils.py": 17045260098091371478,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiprocessing.py": 5522490547285108448,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_abc.py": 10164280045317807365,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/conftest.py": 8406022190801970256,
+ "venv/lib/python3.13/site-packages/pygments/lexers/cddl.py": 1303059539145221713,
+ "backend/src/models/dataset_review_pkg/_enums.py": 501173908863819198,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/comparisons.pyi": 4158883009780474220,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_string.py": 13234624995755549329,
+ "frontend/build/_app/immutable/nodes/33.CWQZJeNR.js": 3208333969825773593,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_fields.py": 16222559851336781264,
+ "venv/lib/python3.13/site-packages/urllib3/util/wait.py": 14629837381061032546,
+ "venv/lib/python3.13/site-packages/pandas/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_ufunc.py": 669019702416198889,
+ "venv/lib/python3.13/site-packages/PIL/FliImagePlugin.py": 13364963053197422923,
+ "venv/lib/python3.13/site-packages/packaging/requirements.py": 2896326326372719999,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic/v1/schema.py": 10008526732895436361,
+ "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/numpy/_core/records.pyi": 14194354215405544730,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_insert.py": 17383986803728810587,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/rethinkdb.py": 16413299263077970925,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_drop.py": 17940792593116540139,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_head_tail.py": 1906121476322841736,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_register_accessor.py": 16661086720613729974,
+ "venv/lib/python3.13/site-packages/anyio/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/base.py": 13634605726041717070,
+ "venv/lib/python3.13/site-packages/numpy/__init__.pyi": 15820654525292895396,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_random.py": 4179188367630060654,
+ "backend/src/scripts/seed_permissions.py": 2299443594185631497,
+ "venv/lib/python3.13/site-packages/rapidfuzz/_utils.py": 14374663810542207121,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_dropna.py": 17272771246760486947,
+ "venv/lib/python3.13/site-packages/pygments/lexers/graphviz.py": 15677908982985025500,
+ "venv/lib/python3.13/site-packages/referencing/tests/test_jsonschema.py": 9815500901482570619,
+ "venv/lib/python3.13/site-packages/keyring/backends/kwallet.py": 3071915635647280308,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/code.py": 9700811903057180696,
+ "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.cpython-313-x86_64-linux-gnu.so": 9380059465932560412,
+ "venv/lib/python3.13/site-packages/pydantic/v1/__init__.py": 1642038155370734658,
+ "venv/lib/python3.13/site-packages/cffi/__init__.py": 13427266446746498548,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/layout.py": 11554376181083053156,
+ "venv/lib/python3.13/site-packages/numpy/_core/_dtype.pyi": 17662618580381221543,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/recarray_from_file.fits": 15116318600514274152,
+ "venv/lib/python3.13/site-packages/referencing/_attrs.py": 14434891919747863272,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc64_aix.h": 8706347224105630468,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_constructors.py": 17392287676196409733,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_names.py": 10037208029090713121,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_arithmetic.py": 17449383588949771785,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/inference.py": 2786441797589123900,
+ "venv/lib/python3.13/site-packages/pip/_internal/cache.py": 210214424535803946,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_series.py": 10922287546912569276,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/client.py": 17305914656270781911,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_is_monotonic.py": 12769599198035357753,
+ "venv/lib/python3.13/site-packages/uvicorn/supervisors/__init__.py": 15971002342788501945,
+ "venv/lib/python3.13/site-packages/pygments/lexers/carbon.py": 6753624244809529841,
+ "venv/lib/python3.13/site-packages/pygments/lexers/sgf.py": 6802546617450210439,
+ "backend/src/core/scheduler.py": 8479779689131957613,
+ "backend/src/core/superset_client/_dashboards_write.py": 17768282769896196778,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_generics.py": 16438159042939059717,
+ "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.py": 652332294655046106,
+ "venv/lib/python3.13/site-packages/jsonschema/cli.py": 9813914882090789748,
+ "venv/lib/python3.13/site-packages/pandas/api/interchange/__init__.py": 181911269762882069,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_apply.py": 7511915990531229598,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_ccalendar.py": 8819357623337533489,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_check_indexer.py": 2929031395357057009,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_comparison.py": 5348781442514871089,
+ "venv/lib/python3.13/site-packages/jose/backends/__init__.py": 16581763658239070112,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/resultproxy.cpython-313-x86_64-linux-gnu.so": 6011605826065363427,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_network.py": 13159427333040109523,
+ "venv/lib/python3.13/site-packages/numpy/typing/__init__.pyi": 10058149460938883683,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/mod_derived_types.f90": 2556756676983488922,
+ "venv/lib/python3.13/site-packages/pip/_vendor/certifi/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/packages/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/live.py": 8586058300967410643,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_categorical.py": 9923236395692943732,
+ "venv/lib/python3.13/site-packages/psycopg2/_json.py": 9729420372294281405,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.pyi": 2700568594438441246,
+ "venv/lib/python3.13/site-packages/_pytest/setuponly.py": 10959102379908419762,
+ "venv/lib/python3.13/site-packages/pandas/compat/__init__.py": 6077099417711209303,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_dataframe.py": 14945138617962156057,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_bus_messages.py": 4323093138307306385,
+ "venv/lib/python3.13/site-packages/pydantic/class_validators.py": 4643597082531287188,
+ "venv/lib/python3.13/site-packages/sqlalchemy/event/api.py": 987321343916500337,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/dependency.py": 7300594038182867460,
+ "venv/lib/python3.13/site-packages/pydantic/v1/parse.py": 5875950480538559709,
+ "frontend/src/components/MappingTable.svelte": 16339628752309005366,
+ "frontend/src/components/MissingMappingModal.svelte": 14222261650100098814,
+ "backend/src/core/__tests__/test_native_filters.py": 3247249287628984886,
+ "backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py": 5075014721013543720,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_convert.py": 17957207974799052653,
+ "backend/src/api/routes/git/__init__.py": 12363460647192569481,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_categorical.py": 10863578845754547294,
+ "frontend/playwright-report/trace/index.BCnMPevh.js": 8625484717968740943,
+ "venv/lib/python3.13/site-packages/pyasn1/type/tagmap.py": 14075859042659927673,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/twodim_base.pyi": 10156504423258357540,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/row.py": 9763935103055608874,
+ "frontend/src/routes/validation/+page.svelte": 9845194549295283559,
+ "backend/src/plugins/translate/__tests__/test_dictionary_correction.py": 17508858180216288123,
+ "backend/src/plugins/translate/preview.py": 5579180663525515759,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_features.py": 955759654189150497,
+ "venv/lib/python3.13/site-packages/pygments/lexers/slash.py": 8320676560518108343,
+ "backend/src/services/clean_release/manifest_builder.py": 16367921257027024830,
+ "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.pyi": 12043292763005874815,
+ "venv/bin/jsonschema": 16516374846693491442,
+ "backend/src/api/routes/__tests__/test_profile_api.py": 10215800611882169470,
+ "backend/src/services/clean_release/publication_service.py": 7731809712174358922,
+ "backend/src/services/clean_release/preparation_service.py": 9259410398708054305,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_replace.py": 8165088653532047247,
+ "backend/src/plugins/llm_analysis/scheduler.py": 16461360386665667203,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/accumulate.py": 5780225603819849877,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/numba_.py": 15997665748332235683,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_expressions.py": 16378925536309828288,
+ "venv/lib/python3.13/site-packages/idna/compat.py": 9758194415584776667,
+ "venv/lib/python3.13/site-packages/numpy/f2py/__version__.pyi": 9759534743796867731,
+ "backend/src/core/migration/dry_run_orchestrator.py": 1628125044585364194,
+ "backend/src/plugins/git/llm_extension.py": 5713196889309291531,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.pyi": 2700568594438441246,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq_py.py": 16054175754674285311,
+ "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/METADATA": 16498441272591167134,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_conversion.py": 6205112277291935767,
+ "venv/lib/python3.13/site-packages/numpy/lib/introspect.pyi": 12239924839764265507,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/array.py": 1919242530821725197,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadbconnector.py": 14865906347579451546,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/compat.py": 9758194415584776667,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_ext_django_source.py": 15577951591316518967,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/rsa/__init__.py": 14623742580410014505,
+ "venv/lib/python3.13/site-packages/rapidfuzz/utils.py": 5682627611354455144,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_implementation.py": 12245524932757110911,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_model_construction.py": 694471028676746110,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-1.csv": 2202360898679162333,
+ "venv/lib/python3.13/site-packages/pandas/_libs/index.cpython-313-x86_64-linux-gnu.so": 18409579812171549318,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_to_typst.py": 14619529283550788275,
+ "venv/lib/python3.13/site-packages/PIL/_util.py": 17116054813914373606,
+ "venv/lib/python3.13/site-packages/numpy/lib/_ufunclike_impl.pyi": 9854069702366900663,
+ "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/METADATA": 15987199384245264478,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_delete.py": 3485374671877063217,
+ "venv/lib/python3.13/site-packages/greenlet/platform/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/client_auth.py": 3301527187487914220,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_indexing.py": 16623126293364224089,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_missing.py": 3991199131191840903,
+ "venv/lib/python3.13/site-packages/idna-3.11.dist-info/METADATA": 14036738037171597049,
+ "venv/lib/python3.13/site-packages/uvicorn/loops/asyncio.py": 16496916527760969173,
+ "venv/lib/python3.13/site-packages/pygments/plugin.py": 18006138132596504101,
+ "venv/lib/python3.13/site-packages/pygments/lexers/vip.py": 11287963054551122004,
+ "venv/lib/python3.13/site-packages/dateutil/tz/__init__.py": 9617254832690762236,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_indexing.py": 7181087459615188551,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_user_array.py": 8711697474193296376,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_complex.py": 4290059580478881700,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/utils.py": 9959199071030996679,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_dtypes.py": 13065857166166716628,
+ "venv/lib/python3.13/site-packages/anyio/abc/_eventloop.py": 2023190981288767991,
+ "venv/lib/python3.13/site-packages/cffi/cffi_opcode.py": 8411344362428947268,
+ "venv/lib/python3.13/site-packages/keyring/backends/macOS/api.py": 4502902558534812719,
+ "venv/lib/python3.13/site-packages/numpy/f2py/common_rules.py": 7352635707860427145,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-2.csv": 16611724551361692999,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.pyx": 7085380878820747579,
+ "venv/lib/python3.13/site-packages/pygments/lexers/scripting.py": 4167168074165473790,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_period.py": 7727606662611927293,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_describe.py": 11923715539897559626,
+ "venv/lib/python3.13/site-packages/git/compat.py": 16843345645628515492,
+ "frontend/src/components/git/CommitModal.svelte": 12274093894389435426,
+ "frontend/build/favicon.svg": 6451919037497541980,
+ "backend/src/services/maintenance/_banner_renderer.py": 17250656767428031478,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/etcd.py": 4078354986605069279,
+ "venv/lib/python3.13/site-packages/pygments/lexers/supercollider.py": 15306357945850389082,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_freq_attr.py": 17290447066681837965,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/asn1/__init__.py": 4290669519959060720,
+ "backend/git_repos/remote/test-repo.git/hooks/commit-msg.sample": 13435789416588783681,
+ "backend/git_repos/remote/test-repo.git/objects/cf/d2dcbd55735b8cedf21e04e64ac627c6f9a458": 10982669277486885525,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_drop.py": 15751236355035730554,
+ "venv/lib/python3.13/site-packages/pydantic/aliases.py": 14481980467204711659,
+ "venv/lib/python3.13/site-packages/httpx/_auth.py": 1283189552342958900,
"frontend/src/components/storage/FileUpload.svelte": 14890211974307083938,
- "venv/bin/pyrsa-keygen": 8222542582170363672,
- "venv/lib/python3.13/site-packages/pip/_vendor/rich/cells.py": 8299309127027168194,
- "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh17859.f": 13562390882286135024,
- "backend/src/services/clean_release/__tests__/test_audit_service.py": 10901982516436251314,
- "backend/src/services/git/_merge.py": 13573452468406399167,
- "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.py": 14696841109142419143,
- "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mariadb.py": 3109042476851791996,
- "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/RECORD": 12598309574903741388,
+ "backend/src/core/task_manager/__tests__/test_context.py": 9922342013893651977,
+ "backend/src/api/routes/git/_config_routes.py": 9064062564638523731,
+ "frontend/src/routes/tools/debug/+page.svelte": 15220194081518936566,
+ "venv/lib/python3.13/site-packages/numpy/f2py/capi_maps.pyi": 10638891136586198429,
+ "backend/src/plugins/translate/__tests__/test_dictionary_crud.py": 2458404726842277862,
+ "venv/lib/python3.13/site-packages/pandas/io/parsers/__init__.py": 11752833703934347122,
+ "venv/lib/python3.13/site-packages/numpy/fft/_pocketfft_umath.cpython-313-x86_64-linux-gnu.so": 16443444849116065961,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_equals.py": 9903250467264848187,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_core.py": 12712110303898046818,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/certs.py": 13366788049827102313,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_dict.py": 808180749933361743,
+ "venv/lib/python3.13/site-packages/pandas/tests/internals/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/h11/_readers.py": 832030916375670301,
+ "backend/src/api/routes/llm.py": 14720807640771498486,
+ "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/RECORD": 5169907629260560698,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/connection.py": 17044409627448400723,
+ "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.pyi": 15067467792538416274,
+ "venv/lib/python3.13/site-packages/pandas/_libs/indexing.pyi": 90995502095752726,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_array_ops.py": 6709502157317299163,
+ "backend/src/api/routes/assistant/__init__.py": 16856916031113491888,
+ "venv/lib/python3.13/site-packages/psycopg2/extras.py": 7510107741729866600,
+ "frontend/build/_app/immutable/nodes/26.DpPenpwY.js": 16901700715882002351,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_warnings.py": 13071210233876253749,
+ "backend/src/services/clean_release/facade.py": 4588791439430238149,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/dtypes.cpython-313-x86_64-linux-gnu.so": 657138415665704488,
+ "backend/git_repos/remote/test-repo.git/objects/a1/3525f5f44e26d8fbec3226bd488d14793575a2": 3742572048019652365,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.cpython-313-x86_64-linux-gnu.so": 12654188486128938170,
+ "frontend/src/routes/validation/history/+page.svelte": 3920288174017004134,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/__init__.py": 10357835306532281617,
+ "docker/nginx.ssl.conf": 12350396037548059686,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_collections.py": 14307204206312829238,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_size.py": 16658280641516916790,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/backend.py": 9072112660082423691,
+ "frontend/src/routes/admin/settings/+page.svelte": 9726389419291634649,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/provision.py": 8707620698060818654,
+ "backend/tests/test_api_key_model.py": 18059967072469014911,
+ "backend/tests/test_logger.py": 1680169894013597024,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.cpython-313-x86_64-linux-gnu.so": 15960606468596245469,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_accumulations.py": 11428556645065711062,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/cffi/parse.py": 2427019397934437210,
+ "venv/lib/python3.13/site-packages/pandas/api/internals.py": 5188134630996087511,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/util.py": 3591114320020964752,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token.py": 4747545058753492487,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/req_command.py": 2887890799766730546,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/cmac.py": 12011944740750051829,
+ "venv/lib/python3.13/site-packages/websockets/connection.py": 5168795926684067030,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/cli.py": 6382193953727339271,
+ "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/__init__.py": 1798074863773727377,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_assumed_shape.py": 18361009188431483164,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_util.py": 6573034224727513309,
+ "venv/lib/python3.13/site-packages/PIL/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/polynomial.py": 7658234162211356265,
+ "venv/lib/python3.13/site-packages/yaml/scanner.py": 8554164423030397366,
+ "venv/lib/python3.13/site-packages/pygments/styles/zenburn.py": 1031869867933871309,
+ "backend/src/core/utils/superset_context_extractor/_parsing.py": 18406152325228380468,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/token.py": 4161760290367932793,
+ "venv/lib/python3.13/site-packages/_pytest/python_api.py": 12953851690889336092,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/emath.pyi": 3718540478840842664,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_nonunique_indexes.py": 15468078561381939405,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_coercion.py": 3551994404797560483,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py": 18229054440703471493,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/class_validators.py": 2200511838255373813,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/calendarinterval.py": 12481650996882675949,
+ "venv/lib/python3.13/site-packages/numpy/_core/_ufunc_config.py": 7365943844063702766,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ampl.py": 4594260378653369985,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_usd_builtins.py": 8671446144574174964,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/foo.f": 6349567809926050379,
+ "frontend/build/_app/immutable/nodes/24.DAYbKwLH.js": 244590320749686417,
+ "venv/lib/python3.13/site-packages/cffi/api.py": 5325821560978502135,
+ "venv/lib/python3.13/site-packages/numpy/_core/_asarray.py": 3468915833437229425,
+ "venv/lib/python3.13/site-packages/pyyaml-6.0.3.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_rewrite_warning.py": 4895919872954538758,
+ "backend/src/schemas/settings.py": 18238532620797946210,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_low_level.py": 3579024079580951234,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/jwk.py": 6458001384702613165,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_quantile.py": 4225791949463893856,
+ "venv/lib/python3.13/site-packages/pygments/lexers/teal.py": 10004159499175716139,
+ "venv/lib/python3.13/site-packages/anyio/to_process.py": 16627578499791368365,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_api.py": 14120915875574640262,
+ "venv/lib/python3.13/site-packages/pandas/io/spss.py": 864838144958947906,
+ "backend/src/services/clean_release/repositories/policy_repository.py": 9074701224814573817,
+ "backend/src/services/sql_table_extractor.py": 11429348671339263380,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/index.py": 2763962019423787504,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/metadata.py": 1362166613223529108,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_header.py": 3564391095263545879,
+ "backend/src/plugins/translate/__tests__/test_dictionary_prompt_builder.py": 12854863376472707556,
+ "venv/lib/python3.13/site-packages/attr/_cmp.py": 3297594878548179300,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_arithmetic.py": 13304014482504911016,
+ "venv/lib/python3.13/site-packages/_pytest/config/exceptions.py": 3199245296954654462,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/strptime.pyi": 5973671421648618563,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/trustedhost.py": 4285622102799027823,
+ "venv/lib/python3.13/site-packages/click/_winconsole.py": 8133229457213704188,
+ "venv/lib/python3.13/site-packages/requests/help.py": 1885413874621672882,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/_polytypes.pyi": 7528777458251688517,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_append.py": 13152738905565588661,
+ "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/zip-safe": 15240312484046875203,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/requests.py": 6703055041957748929,
+ "venv/lib/python3.13/site-packages/PIL/McIdasImagePlugin.py": 14137545069906812251,
+ "venv/lib/python3.13/site-packages/attr/_cmp.pyi": 14443711863388606665,
+ "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/licenses/LICENSE": 13479831069780783137,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/utils.py": 7707707044867513457,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_julian_date.py": 6868080396693831272,
+ "backend/src/api/routes/assistant/_admin_routes.py": 253209289619444139,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_arraymethod.py": 14421188237635557797,
+ "venv/lib/python3.13/site-packages/pandas/tests/construction/test_extract_array.py": 3100523370314150013,
+ "venv/lib/python3.13/site-packages/more_itertools/more.py": 1631135582441184133,
+ "venv/lib/python3.13/site-packages/_pytest/runner.py": 5772610501857496741,
+ "venv/lib/python3.13/site-packages/jeepney/wrappers.py": 15234251727654692435,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_tooltip.py": 853808724844451770,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_unique.py": 3148372351781648868,
+ "backend/src/plugins/translate/preview_session_serializer.py": 8901687711861433007,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/api.py": 9829629144629841277,
+ "frontend/src/routes/translate/dictionaries/[id]/+page.svelte": 17719561272401762626,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23598Warn.f90": 7589258200398878529,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_multiarray.py": 5928288171180750841,
+ "frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte": 5121541182559165710,
+ "venv/lib/python3.13/site-packages/pandas/tests/libs/__init__.py": 15130871412783076140,
+ "backend/src/api/routes/__tests__/test_clean_release_source_policy.py": 15459112324357199814,
+ "frontend/build/_app/immutable/chunks/BtH-0okm.js": 8437682539386015542,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_dists.py": 16746363359320577809,
+ "frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js": 1278883813018181993,
+ "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/METADATA": 14158024963562115116,
+ "venv/lib/python3.13/site-packages/pydantic/networks.py": 15767095796055034509,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_arithmetic.py": 17427754419626622853,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tan.csv": 6233924374281534211,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlite.py": 16550134594771291234,
+ "venv/lib/python3.13/site-packages/pandas/io/parsers/base_parser.py": 15148258424429418380,
+ "backend/src/api/routes/git/_repo_operations_routes.py": 11164792016063890809,
+ "backend/src/plugins/translate/service.py": 12396293729608729912,
+ "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector.py": 15458248567257759500,
+ "venv/lib/python3.13/site-packages/fastapi/websockets.py": 9910052969532075719,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_stack_unstack.py": 3737891757817696405,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/__init__.py": 13482731985065116750,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pkg_resources/__init__.py": 1677532855362260338,
+ "venv/lib/python3.13/site-packages/yaml/_yaml.cpython-313-x86_64-linux-gnu.so": 16990140871649227895,
+ "venv/lib/python3.13/site-packages/pydantic/v1/generics.py": 1150594223414883339,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tz_localize.py": 13699016868476153393,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/show.py": 11839987586497822300,
+ "venv/lib/python3.13/site-packages/pygments/lexers/r.py": 14263133575134645005,
+ "backend/src/core/mapping_service.py": 5863886462891122323,
+ "venv/lib/python3.13/site-packages/_pytest/config/findpaths.py": 7867603756389940562,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/sparse/accessor.py": 8373575175447947401,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_astype.py": 15384141282611151560,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath.py": 13010939919217862164,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/__init__.py": 14571251344510763303,
+ "venv/lib/python3.13/site-packages/numpy/ma/mrecords.pyi": 8945514863366384484,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/compat/pyarrow.py": 13693379998785127538,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_common.py": 9446944526144164255,
+ "venv/lib/python3.13/site-packages/attr/_typing_compat.pyi": 2823472697859409877,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_get.py": 10255752806860493777,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/cache.py": 1892313355296776523,
+ "venv/lib/python3.13/site-packages/uvicorn/config.py": 17317823506849880916,
+ "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/METADATA": 14070889071949105584,
+ "venv/lib/python3.13/site-packages/pygments/lexers/comal.py": 769727871242464458,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_missing.py": 2976310411820303374,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/reflection.py": 5951113078754792806,
+ "venv/lib/python3.13/site-packages/pycparser/ast_transforms.py": 9032453625977464506,
+ "venv/bin/websockets": 12099863324306500376,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_registry.py": 15377817946543064293,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/connection.py": 8190661510572400096,
+ "venv/bin/pip3.13": 13861749540792881808,
+ "frontend/src/lib/stores/__tests__/taskDrawer.test.js": 9115135514077743547,
+ "frontend/build/_app/immutable/nodes/35.CibKGPSn.js": 8269343134459108819,
+ "venv/lib/python3.13/site-packages/attr/converters.pyi": 17675091788614033166,
+ "backend/src/plugins/translate/__tests__/test_lang_detect.py": 2328877106785068272,
+ "backend/src/plugins/translate/scheduler.py": 13650497976959209825,
+ "backend/git_repos/remote/test-repo.git/objects/48/c3fde4d5fff5bf98e9bcaa5f328b199aa18292": 6121250272621110311,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_quoting.py": 1147992698412929658,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/common.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_dtypes.py": 6831042272921908068,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/backends/openssl/__init__.py": 4870269250323682576,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_copy.py": 12902342280706372953,
+ "frontend/build/_app/immutable/assets/AssistantChatPanel.D4L5jlt0.css": 10724144138366384732,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli/_parser.py": 3540203683732744499,
+ "venv/lib/python3.13/site-packages/pandas/_version.py": 3480474785419232091,
+ "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.pyi": 15498895254516573071,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timezones.py": 8042029178538467146,
+ "venv/lib/python3.13/site-packages/jose/jwe.py": 3325660353225624025,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_aarch64_gcc.h": 8140470539757491899,
+ "venv/lib/python3.13/site-packages/pandas/_libs/testing.pyi": 16691791330088523786,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/resolvers/criterion.py": 2042509334195547606,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_coercion.py": 3339075591248270762,
+ "venv/lib/python3.13/site-packages/pandas/core/window/rolling.py": 6316477981414191778,
+ "venv/lib/python3.13/site-packages/websockets/protocol.py": 6401227903827084901,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/__init__.py": 63497920264089252,
+ "venv/lib/python3.13/site-packages/pandas/io/pickle.py": 5418646169167774144,
+ "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/REQUESTED": 15130871412783076140,
+ "frontend/build/_app/immutable/chunks/B3miH4jD.js": 11736959945545311440,
+ "venv/lib/python3.13/site-packages/pandas/tests/internals/test_internals.py": 2049484047553296860,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/__init__.py": 12793458753561114666,
+ "backend/src/services/clean_release/__tests__/test_policy_engine.py": 7872293927249163831,
+ "backend/src/services/clean_release/exceptions.py": 16765031947674227117,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/shape_base.pyi": 10291383658131961346,
+ "backend/src/services/profile_utils.py": 11110559205027128244,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_initialstub_already_started.py": 5562030563802006923,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/_natype.py": 12013743717306900860,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_bcrypt.py": 11146468670439284889,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/_conditional.py": 14190849361275154667,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_ndarray_backed.py": 10097812802469682233,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/wrappers.py": 315409799569602977,
+ "venv/bin/activate.fish": 5275961582873298085,
+ "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/METADATA": 13633829318759752611,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_longdouble.py": 9337218715436213122,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_categorical.py": 9615571808720893016,
+ "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/RECORD": 1051307407005554409,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/foo_mod.f90": 5765181406654284736,
+ "venv/lib/python3.13/site-packages/numpy/_configtool.pyi": 9670892208858157218,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_sorting.py": 10523740688498427929,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_setops.py": 10550603120090683350,
+ "venv/lib/python3.13/site-packages/pygments/formatter.py": 11156733836937309465,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/highlighter.py": 10615901258492570740,
+ "backend/src/services/__tests__/test_encryption_manager.py": 11651916791559202800,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_ints.py": 5616705208267050659,
+ "venv/lib/python3.13/site-packages/pycparser/plyparser.py": 5251740466238035035,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_polybase.pyi": 3404315099794022355,
+ "venv/lib/python3.13/site-packages/jsonschema/_utils.py": 14237077105384631097,
+ "venv/lib/python3.13/site-packages/pygments/lexers/typoscript.py": 6706632522710582762,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/xml/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_gcs.py": 7733247456252965901,
+ "venv/lib/python3.13/site-packages/websockets/speedups.pyi": 10322382420215791091,
+ "backend/src/plugins/translate/orchestrator_validation.py": 17464651621865127561,
+ "venv/lib/python3.13/site-packages/greenlet/tests/leakcheck.py": 10179165748538820557,
+ "venv/lib/python3.13/site-packages/numpy/__config__.py": 15794735729525094396,
+ "backend/tests/core/migration/test_dry_run_orchestrator.py": 5618205549212894117,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/token_endpoint.py": 6118770923176099889,
+ "venv/lib/python3.13/site-packages/uvicorn/_types.py": 3339389597716220585,
+ "venv/lib/python3.13/site-packages/pip/_internal/exceptions.py": 2252826732781519645,
+ "venv/lib/python3.13/site-packages/numpy/_core/numeric.py": 12261531924304979741,
+ "venv/lib/python3.13/site-packages/pip/_internal/main.py": 13711402795965346761,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/foo_deps.f90": 14350239197565389508,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_repr.py": 16609300578827398344,
+ "backend/src/core/utils/superset_context_extractor/__init__.py": 16372223806424875537,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/openssl/binding.py": 17078280153372356796,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix_py.py": 17041764258638228993,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/token.py": 11655733747403312358,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/validator_creation.py": 2745563768861102999,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/tags.py": 254599446317461188,
+ "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_time.py": 10463741033950978270,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-objarr.npz": 9481735723557962988,
+ "venv/lib/python3.13/site-packages/idna-3.11.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/uvicorn/lifespan/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_log_render.py": 18076931145915444473,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_shape.py": 12667553664122376205,
+ "venv/lib/python3.13/site-packages/pygments/lexers/forth.py": 17623561228839319663,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_apply.py": 11248068903302454630,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_cumulative.py": 11752712818547022872,
+ "frontend/src/components/RepositoryDashboardGrid.svelte": 8427306073875543545,
+ "backend/src/services/git_service.py": 12429116089116885657,
+ "backend/src/api/routes/assistant/_command_parser.py": 4551109710541212154,
+ "venv/lib/python3.13/site-packages/dateutil/tz/_common.py": 9009072600471223066,
+ "backend/tests/test_layout_utils.py": 15634672279171875732,
+ "venv/lib/python3.13/site-packages/_pytest/outcomes.py": 12782895027812738142,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_equals.py": 18261810467289276844,
+ "venv/lib/python3.13/site-packages/pillow.libs/libopenjp2-94e588ba.so.2.5.4": 2483101806045986252,
+ "venv/lib/python3.13/site-packages/pip/_internal/distributions/base.py": 16714704323747942110,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/hi77.f": 10617763407280454334,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/OSA.py": 17817123894903120316,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/models.py": 5656065513234782067,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_api.py": 16743710460729009914,
+ "venv/lib/python3.13/site-packages/pygments/lexers/mips.py": 2078929831513352031,
+ "backend/test_pat_api.py": 4206656943734821967,
+ "backend/alembic_test.db": 14995253579408279707,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/constrain.py": 6513876973118703677,
+ "backend/src/schemas/health.py": 17351928434071690723,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/hybrid.py": 14287665090144592501,
+ "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.pyi": 12275242654430570028,
+ "venv/lib/python3.13/site-packages/pip/_internal/configuration.py": 2563100675379605810,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f90continuation.f90": 17056591497459381871,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_recfunctions.py": 16014503284544747867,
+ "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/METADATA": 14180973198574731599,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/testing.pyi": 16263777835572515739,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_map.py": 6556132946198785761,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_chaining_and_caching.py": 11784574265874608859,
+ "venv/lib/python3.13/site-packages/numpy/_core/multiarray.pyi": 3494871767602648807,
+ "venv/lib/python3.13/site-packages/numpy/_core/_struct_ufunc_tests.cpython-313-x86_64-linux-gnu.so": 13269324887178340397,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/starlette/templating.py": 9242638124487797988,
+ "venv/lib/python3.13/site-packages/urllib3/util/url.py": 15992369651965016538,
+ "frontend/src/lib/api/__tests__/reports_api.test.js": 4759560641984508050,
+ "frontend/src/lib/components/translate/BulkReplaceModal.svelte": 9447617465987205060,
+ "venv/lib/python3.13/site-packages/more_itertools/recipes.py": 5254043689078173976,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/numpy_.py": 16641729409992576358,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_constructors.py": 12118296571694122743,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/flatiter.pyi": 9598576095384661517,
+ "backend/src/api/routes/translate/_schedule_routes.py": 18139325016758974063,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/testing.pyi": 9317922890783549326,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi": 7385072545198817771,
+ "backend/src/plugins/maintenance_banner.py": 13137032570032257498,
+ "backend/src/plugins/migration.py": 10457528901248546685,
+ "venv/lib/python3.13/site-packages/pandas/core/generic.py": 10174952306641057447,
+ "venv/lib/python3.13/site-packages/pillow.libs/libpng16-4a38ea05.so.16.53.0": 13136089038268964667,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/liblber-1c9097e2.so.2.0.200": 2651879839738900594,
+ "venv/lib/python3.13/site-packages/click/shell_completion.py": 5858110451169927373,
+ "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.pyi": 9629457630163613604,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/__init__.py": 8924316361489544973,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_floats.py": 3064615530495290792,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/util.py": 955993052529739164,
+ "venv/lib/python3.13/site-packages/pyasn1/type/useful.py": 10313387611927801339,
+ "backend/src/api/routes/assistant/_resolvers.py": 5636628127798453486,
+ "venv/lib/python3.13/site-packages/pandas/core/methods/to_dict.py": 4653628436393663485,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/bitgen.h": 12421210767114721499,
+ "backend/src/api/auth.py": 16676039157915315566,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_alter_axes.py": 11338712836362534969,
+ "venv/lib/python3.13/site-packages/pygments/lexers/dotnet.py": 17970884907837213099,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_complexcompat.h": 5001035774408914877,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/mod.py": 2054876501774773382,
+ "venv/lib/python3.13/site-packages/fastapi/cli.py": 13972351579061154035,
+ "venv/lib/python3.13/site-packages/iniconfig/_parse.py": 11418441008427032090,
+ "venv/lib/python3.13/site-packages/numpy/_globals.pyi": 12839879732484756979,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_monotonic.py": 14648437502004398715,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_to_csv.py": 10737444103906389448,
+ "venv/lib/python3.13/site-packages/more_itertools/more.pyi": 4844596605492825806,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_apply.py": 8103417303073393969,
+ "venv/lib/python3.13/site-packages/packaging/tags.py": 1999137344425005827,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_pyxlsb.py": 10035587889954731645,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_numba.py": 6409810497251251179,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_compression.py": 8061288329598682752,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/utils.h": 3920393832993063886,
+ "venv/lib/python3.13/site-packages/numpy/_core/overrides.py": 252940520997718714,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/grouper.py": 18110568057754450953,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/candidates.py": 5951912505933673835,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timedeltas.pyi": 3783371827926657291,
+ "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py": 16951268065271931235,
+ "venv/lib/python3.13/site-packages/pygments/styles/solarized.py": 11231143047572616298,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_compare.py": 3079569478684646491,
+ "venv/lib/python3.13/site-packages/pygments/lexers/q.py": 15426466074881683794,
+ "backend/src/core/task_manager/context.py": 11799776870777277331,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/compatibility_tags.py": 15862649917149158291,
+ "backend/src/services/clean_release/repositories/report_repository.py": 8327339942479580975,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunc_config.pyi": 2005481648919369399,
+ "frontend/src/components/TaskHistory.svelte": 4575283937108155085,
+ "venv/lib/python3.13/site-packages/pygments/lexers/maxima.py": 11824576541091274641,
+ "venv/lib/python3.13/site-packages/websockets/legacy/exceptions.py": 16025779645869134942,
+ "venv/lib/python3.13/site-packages/pandas/core/common.py": 14578909424716153057,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/base.py": 5924592154431932923,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/quantile.py": 17341029201525362074,
+ "backend/src/plugins/translate/__tests__/test_dictionary_utils.py": 2896829624338027530,
+ "backend/src/services/clean_release/stages/manifest_consistency.py": 5890428472425990952,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.cpython-313-x86_64-linux-gnu.so": 16927263232848238698,
+ "venv/lib/python3.13/site-packages/jaraco/classes/properties.py": 6976928770004942858,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Indel.pyi": 16372699564794732463,
+ "frontend/src/components/DynamicForm.svelte": 2120031570302269345,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/control.py": 2034518223411945438,
+ "venv/lib/python3.13/site-packages/passlib/tests/sample1.cfg": 9597283806285213340,
+ "venv/lib/python3.13/site-packages/pandas/tseries/holiday.py": 1134358927599488799,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_arrow.py": 10068866425352207113,
+ "venv/lib/python3.13/site-packages/numpy/testing/overrides.py": 11819432487830192978,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/simple.py": 11050636051019777317,
+ "venv/lib/python3.13/site-packages/jeepney/__init__.py": 1063800617763464773,
+ "venv/lib/python3.13/site-packages/pandas/_libs/arrays.pyi": 12629806207276576877,
+ "backend/src/services/clean_release/repositories/manifest_repository.py": 12161285893423159929,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/asyncexitstack.py": 7733356903092860495,
+ "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/LICENSE": 16510279186416777136,
+ "venv/lib/python3.13/site-packages/pygments/lexers/func.py": 12257919753150082714,
+ "frontend/src/routes/datasets/__tests__/DatasetPreview.test.js": 12281160027416292128,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_partial.py": 15129217814262096441,
+ "venv/lib/python3.13/site-packages/gitdb/db/loose.py": 17467413653016810702,
+ "venv/lib/python3.13/site-packages/idna-3.11.dist-info/RECORD": 11541505360973709787,
+ "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/fallback.py": 4260636031748548345,
+ "venv/lib/python3.13/site-packages/anyio/__init__.py": 12752386096259972231,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_slp_switch.py": 16490710972475154509,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/cache.py": 10606522397693824641,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_rename_axis.py": 13193478481758930128,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_npfuncs.py": 13987318550267921389,
+ "venv/lib/python3.13/site-packages/certifi/core.py": 7472627735517449185,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/halffloat.h": 16913381775994652343,
+ "backend/src/plugins/translate/orchestrator_retry.py": 2531207787915962557,
+ "backend/src/models/dataset_review_pkg/_mapping_models.py": 1407462125644004056,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_quantile.py": 11273403743157110261,
+ "backend/src/schemas/dataset_review.py": 7490971410706145392,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_x86_msvc.h": 2465089365642299646,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/multiarray.pyi": 17232959648651278910,
+ "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/RECORD": 15865206372525596795,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/terminal_theme.py": 13727399800263579809,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2cmap.py": 5863341586534531594,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/__init__.py": 4049432353810047365,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_equals.py": 11041884432990762650,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/models.py": 11521700876708601977,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_constructors.py": 11786151805350138436,
+ "venv/lib/python3.13/site-packages/pygments/lexers/elm.py": 14683437310498104916,
+ "venv/lib/python3.13/site-packages/pygments/lexers/textedit.py": 14872291021083255414,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numeric.pyi": 17005748821769179511,
+ "frontend/src/routes/datasets/ColumnsTable.svelte": 14113713230812728863,
+ "backend/src/services/clean_release/stages/data_purity.py": 7015962973560119808,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_to_timestamp.py": 12253372102602993034,
+ "venv/lib/python3.13/site-packages/fastapi/security/open_id_connect_url.py": 3502444317759870079,
+ "venv/lib/python3.13/site-packages/_pytest/terminalprogress.py": 5490989904517343259,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_cpu_dispatcher.py": 2063037275809439611,
+ "venv/lib/python3.13/site-packages/referencing/tests/test_core.py": 8280983300775878144,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.py": 4440659352851541547,
+ "venv/lib/python3.13/site-packages/numpy/random/_generator.cpython-313-x86_64-linux-gnu.so": 15625019745021657670,
+ "venv/lib/python3.13/site-packages/pandas/testing.py": 18352975429944961593,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_numpy_compat.py": 9112925138440787555,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_month.py": 14597470286884431085,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/numpy_/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ul4.py": 9580182474451220952,
+ "backend/src/plugins/translate/dictionary_validation.py": 16674754716565921261,
+ "backend/src/services/dataset_review/orchestrator_pkg/_commands.py": 2554792474786179775,
+ "venv/lib/python3.13/site-packages/rsa/pkcs1_v2.py": 3533398238491175229,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/freeze.py": 3469845570614985559,
+ "frontend/src/lib/api/assistant.js": 12514226537527897950,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/util.py": 4890614159013873000,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_structures.py": 16375837477294135345,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh25286.f90": 1249061697041863692,
+ "venv/lib/python3.13/site-packages/anyio/abc/_tasks.py": 16839170934610571514,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_textreader.py": 388955620768371652,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/_orm_constructors.py": 4276726508722638048,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_cpp_exception.py": 11851283355840567373,
+ "venv/lib/python3.13/site-packages/numpy/random/__init__.py": 11732100564412485633,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.py": 3654583356259850174,
+ "backend/src/core/utils/network.py": 535557448085943960,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_join.py": 2585969863606902743,
+ "backend/src/core/migration/__init__.py": 13075189211840127611,
+ "venv/lib/python3.13/site-packages/pandas/core/resample.py": 13814298871925341617,
+ "venv/lib/python3.13/site-packages/certifi/cacert.pem": 14727832973577663826,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_common.h": 14732581790650403546,
+ "venv/lib/python3.13/site-packages/starlette/middleware/sessions.py": 11719848399661632707,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_readlines.py": 15928258358116399067,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_api.py": 1910541672533352625,
+ "venv/lib/python3.13/site-packages/anyio/_core/_subprocesses.py": 7271614043537119143,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/__init__.py": 3692257288065292607,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_scalar_compat.py": 10068989979144965125,
+ "venv/lib/python3.13/site-packages/pandas/io/json/__init__.py": 12333505155070172626,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arrayterator.pyi": 7439348655567232744,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_version.py": 6317733744899804292,
+ "backend/src/services/git/_branch.py": 1746193863798413085,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_clearing_run_switches.py": 3020294789560975101,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/setuptools_build.py": 13594639612360346306,
+ "backend/tests/test_storage_config.py": 14773544217703363468,
+ "venv/lib/python3.13/site-packages/numpy/_utils/__init__.py": 7731065084036767848,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/tornado.py": 6635576580306890718,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/take.py": 3170415198452493008,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/aiosqlite.py": 9888795404090331319,
+ "venv/lib/python3.13/site-packages/git/refs/log.py": 5175801243332619268,
+ "backend/src/plugins/translate/service_datasource.py": 10240814407336170041,
+ "venv/lib/python3.13/site-packages/pygments/lexers/prolog.py": 599539463980699865,
+ "frontend/src/routes/datasets/review/[id]/__tests__/dataset_review_workspace.ux.test.js": 14106200953934418963,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_timedelta.py": 7742506012012398830,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/plugin_base.py": 2880434680251108786,
+ "venv/lib/python3.13/site-packages/_pytest/scope.py": 7603155109542903644,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_setops.py": 13440916133402971190,
+ "backend/src/core/auth/jwt.py": 11190403692794990534,
+ "venv/lib/python3.13/site-packages/anyio/_core/_testing.py": 14024940365851109155,
+ "venv/lib/python3.13/site-packages/jaraco.classes-3.4.0.dist-info/METADATA": 15970460108484113417,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py": 14824388798676578409,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_to_csv.py": 6678500392137188521,
+ "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/METADATA": 6596896092754256988,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_indexing.py": 2274965639578580723,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/version.py": 6401479036177132374,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/min_max_.py": 13457611930368041821,
+ "venv/lib/python3.13/site-packages/jsonschema/_types.py": 9250091433305395923,
+ "venv/lib/python3.13/site-packages/keyring/core.py": 2764269590123131634,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8693/__init__.py": 11065844267208884531,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/__init__.py": 13841777369501476946,
+ "venv/lib/python3.13/site-packages/dateutil/parser/isoparser.py": 18015430204844361067,
+ "venv/lib/python3.13/site-packages/numpy/fft/tests/test_pocketfft.py": 18025182347224285050,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_public_dtype_api_table.h": 8933016749764021181,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/__init__.py": 1377108808392195313,
+ "venv/lib/python3.13/site-packages/idna/idnadata.py": 200840860629525970,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/vector.py": 9941185556118343263,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_dtypes.py": 2313400030798822026,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/xml/test_xml_dtypes.py": 18293138335799308439,
+ "venv/lib/python3.13/site-packages/PIL/features.py": 3481835375516797487,
+ "venv/lib/python3.13/site-packages/numpy/__init__.cython-30.pxd": 1476688171642957054,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/METADATA": 8985010079096958084,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_datetime_index.py": 15448494560143263150,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_timezones.py": 15157687716502574038,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/importlib/_compat.py": 4677414058216516380,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/_selectable_constructors.py": 84919308502240880,
+ "venv/lib/python3.13/site-packages/pygments/styles/rainbow_dash.py": 12236746494379891602,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_astype.py": 1961831758405941258,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/utils.py": 13421242949994555055,
+ "frontend/build/_app/immutable/chunks/DNOraAy0.js": 868732761380476466,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_utils_handlers.py": 556092537518149789,
+ "venv/lib/python3.13/site-packages/pygments/lexers/igor.py": 6506221273085723501,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/lambdas.py": 13377298868598623228,
+ "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_printing.py": 8859757563354666575,
+ "venv/lib/python3.13/site-packages/websockets/http11.py": 11022534176398053082,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_scalarprint.py": 9482100952562512933,
+ "venv/lib/python3.13/site-packages/fastapi/logger.py": 11590581556317053213,
+ "frontend/src/routes/settings/__tests__/settings_page.integration.test.js": 4898515600493251972,
+ "backend/src/core/utils/superset_context_extractor/_templates.py": 13945363390780279343,
+ "venv/lib/python3.13/site-packages/ecdsa/ecdh.py": 12596317261561755793,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA": 18410956221497090898,
+ "backend/src/plugins/translate/_llm_parse.py": 3278211416813203155,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_freq_attr.py": 1720704043778272895,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_construction.py": 10619501873883861745,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ndarray_misc.py": 8706265665356094801,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/totp.py": 11888568940387752607,
+ "venv/lib/python3.13/site-packages/passlib/handlers/bcrypt.py": 8125664010268654055,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_reduction.py": 1049551473665255648,
+ "backend/src/api/routes/assistant/_dataset_review_dispatch.py": 555136946286235411,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_period_range.py": 9598872514187524706,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_month.py": 8485374160446988786,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/__init__.py": 7062045842767697645,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_infer_objects.py": 6769980076977692890,
+ "venv/lib/python3.13/site-packages/numpy/f2py/symbolic.py": 16854377502491291093,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_results.py": 18145930285449734975,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tlb.py": 1169242051301155885,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/authenticate_client.py": 16886645731942472285,
+ "venv/lib/python3.13/site-packages/starlette/status.py": 16192064443996706569,
+ "venv/lib/python3.13/site-packages/_pytest/timing.py": 14080119171718125986,
+ "frontend/build/_app/immutable/nodes/16.BQspsH4T.js": 16103085405789869452,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/hermite_e.pyi": 13068936038543812082,
+ "backend/tests/test_translate_scheduler.py": 9870953183282058719,
+ "venv/lib/python3.13/site-packages/numpy/core/_internal.py": 14816989375912210674,
+ "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/licenses/LICENSE": 14610443802372107702,
+ "venv/lib/python3.13/site-packages/numpy/lib/array_utils.py": 18135114588643176359,
+ "venv/lib/python3.13/site-packages/packaging/licenses/__init__.py": 15879493360260891293,
+ "backend/src/models/__tests__/test_report_models.py": 1002634514476529590,
+ "frontend/src/routes/datasets/__tests__/split_view.test.js": 6143972529940917004,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_time_grouper.py": 3203729024111501071,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_interaction.py": 12216477658994324787,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/cli/gh_22819.pyf": 14717748358749934995,
+ "backend/src/api/routes/assistant/_dataset_review.py": 4389080462745572364,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dtype.py": 5553691086633215767,
+ "venv/lib/python3.13/site-packages/starlette/responses.py": 14081178833432955042,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_unary.py": 7128845965976836334,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_find_common_type.py": 9581516171321396333,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/__init__.py": 15130871412783076140,
+ "backend/src/models/task.py": 13936135007931808732,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_autocorr.py": 1092316868398391792,
+ "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/RECORD": 1556051687830913019,
+ "venv/lib/python3.13/site-packages/numpy/linalg/__init__.py": 15647756307608142577,
+ "backend/src/services/__init__.py": 15123879863527585264,
+ "backend/tests/core/test_mapping_service.py": 14025593540151022064,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/base.py": 13269563625127294513,
+ "venv/lib/python3.13/site-packages/numpy/_core/_type_aliases.pyi": 15848834171197104301,
+ "venv/lib/python3.13/site-packages/httpx/_transports/asgi.py": 12335675489870745729,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufuncs.py": 12732599294816239111,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/segment.py": 2555584120510872966,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/licenses/LICENSE": 8364608327598414179,
+ "venv/lib/python3.13/site-packages/_pytest/warning_types.py": 10695097290648045427,
+ "venv/lib/python3.13/site-packages/passlib/handlers/sha1_crypt.py": 5752556581809938954,
+ "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/passlib/crypto/des.py": 14699826058580193499,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm32_gcc.h": 3561524604274567339,
+ "venv/lib/python3.13/site-packages/anyio/_core/_streams.py": 6436461519284884601,
+ "venv/lib/python3.13/site-packages/authlib/integrations/httpx_client/oauth2_client.py": 6742098857947604729,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/build_tracker.py": 9389444024234384408,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/misc.py": 6571241778569465264,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/concat.py": 2218848863149192467,
+ "frontend/build/_app/immutable/entry/app.BlZMRWBE.js": 11956739625343860073,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_twodim_base.py": 17623133613018058380,
+ "venv/lib/python3.13/site-packages/passlib/hash.py": 5238710192614935875,
+ "backend/src/api/routes/__tests__/test_assistant_authz.py": 3835028453926095879,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timezones.cpython-313-x86_64-linux-gnu.so": 1137453907225619959,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/_dml_constructors.py": 4497038002189188311,
+ "venv/lib/python3.13/site-packages/ecdsa/test_ellipticcurve.py": 11125783981574901613,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_real.f90": 9097998998863007705,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_scalar_compat.py": 1306236983392218709,
+ "frontend/build/_app/immutable/chunks/krqknA6L.js": 13706362651914504619,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/util.py": 2866856507760047219,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/conftest.py": 13798335354961261346,
+ "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/WHEEL": 5179340427739743287,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_validators.py": 14178329676643700151,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_sorting.py": 10751098438703044961,
+ "venv/lib/python3.13/site-packages/pydantic/env_settings.py": 18250976255197243083,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_matplotlib.py": 12775850858284584296,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/context.py": 1041624619197012753,
+ "venv/lib/python3.13/site-packages/dateutil/zoneinfo/__init__.py": 10261654903106416888,
+ "backend/src/plugins/translate/orchestrator_lang_stats.py": 5713612003349083382,
+ "backend/tests/test_datasets.py": 9766141609165223604,
+ "backend/tests/test_api_key_auth.py": 15854247672009604904,
+ "venv/lib/python3.13/site-packages/numpy/typing/mypy_plugin.py": 1306129775649200113,
+ "backend/src/plugins/translate/orchestrator_config.py": 1227864697811313446,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_tracing.py": 10227316489696807112,
+ "venv/lib/python3.13/site-packages/numpy/random/_common.cpython-313-x86_64-linux-gnu.so": 12834724130890991478,
+ "venv/lib/python3.13/site-packages/pandas/tests/reductions/test_reductions.py": 11624188672428941494,
+ "venv/lib/python3.13/site-packages/cffi/backend_ctypes.py": 2042566833861899211,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/meson.build": 17468163147765825687,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/docstrings.py": 3721650738518391256,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/list/array.py": 8065856342131357421,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/_pip_wrapper.py": 2516476609539242190,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_to_numpy.py": 14845850776625255794,
+ "frontend/playwright-report/index.html": 16542149899775356791,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/decrepit/ciphers/algorithms.py": 2375452080667815941,
+ "frontend/src/lib/stores/__tests__/mocks/env_public.js": 17950613826406014914,
+ "backend/alembic/versions/ed310b33f02c_multi_language_translation_tables.py": 1424919631205944664,
+ "backend/src/api/routes/translate/_correction_routes.py": 9348235443422223333,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi": 14119032813912827271,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/floating.py": 1215586266958421991,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/core/col.py": 4221271461723119525,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_src_pyf.py": 546976622482819095,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_dst.py": 12243642467695371088,
+ "venv/lib/python3.13/site-packages/pygments/styles/paraiso_light.py": 15941591873059208999,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/models.py": 17870758731501836303,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_iteration.py": 15247340610412364508,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_no_deprecated_api.h": 7896028550808252043,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/f2cmap/isoFortranEnvMap.f90": 15768643271492041853,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_sparse_accessor.py": 6774374030220202353,
+ "venv/lib/python3.13/site-packages/uvicorn/loops/uvloop.py": 5385425357504191161,
+ "backend/src/core/task_manager/event_bus.py": 1436794780600195410,
+ "venv/lib/python3.13/site-packages/rapidfuzz/utils.pyi": 7400725037332728015,
+ "backend/tests/test_translate_scheduler_execution.py": 16687335504320865378,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/misc/extended_precision.pyi": 6541258584648209609,
+ "venv/lib/python3.13/site-packages/passlib/utils/compat/_ordered_dict.py": 14248790502300368024,
+ "venv/lib/python3.13/site-packages/pycparser/ply/__init__.py": 5040371336745852622,
+ "backend/git_repos/remote/test-repo.git/hooks/applypatch-msg.sample": 12627299623252391515,
+ "venv/lib/python3.13/site-packages/PIL/ImageWin.py": 13635870584232081323,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/__init__.py": 16532856661318424631,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufuncs.pyi": 14995898537484305307,
+ "venv/lib/python3.13/site-packages/pandas/util/__init__.py": 4070574585004336241,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_unique.py": 16285418015531891530,
+ "backend/src/plugins/translate/_run_service.py": 1705461175389858266,
+ "frontend/src/components/git/GitInitPanel.svelte": 515428146955886062,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/compiler.py": 11662494978292401568,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_datetimelike.py": 15246580603900811749,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/accessors.py": 14394872772838047912,
+ "venv/lib/python3.13/site-packages/greenlet/TStackState.cpp": 16720079760074325527,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/assertion.py": 5287436128235488464,
+ "venv/lib/python3.13/site-packages/packaging/metadata.py": 9168255069163141470,
+ "backend/src/core/superset_client/_layout_utils.py": 1180616937544609564,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/main.py": 9304034369762028739,
+ "venv/lib/python3.13/site-packages/numpy/_configtool.py": 2946953194004101078,
+ "frontend/src/routes/settings/automation/+page.svelte": 13199339263146300897,
+ "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_salsa.py": 1756536674254931838,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/_serialization.py": 2011519400081029270,
+ "venv/lib/python3.13/site-packages/pygments/lexers/thingsdb.py": 6073447481627395832,
+ "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.pyi": 6723628093359375823,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_asfreq.py": 12721047184483392773,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__init__.py": 5895297076117159245,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/anyio/_core/_sockets.py": 10525237827959090532,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_rename.py": 4890779493250245903,
+ "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/LICENSE": 2032205056284080825,
+ "venv/lib/python3.13/site-packages/yaml/parser.py": 18021832376874455801,
+ "venv/lib/python3.13/site-packages/pillow.libs/libharfbuzz-0692f733.so.0.61230.0": 23110287346167671,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_common.py": 2265736743367879051,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/cache.py": 15037055977924167732,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_openssl.py": 10446441599800965961,
+ "venv/lib/python3.13/site-packages/pandas/_libs/missing.pyi": 13543139288840944411,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_one_public_routine.f90": 7957683453180939605,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/_mixins.py": 14293848457775268010,
+ "venv/lib/python3.13/site-packages/passlib/apache.py": 2357244937629445006,
+ "venv/lib/python3.13/site-packages/pandas/_testing/__init__.py": 10127496080404419481,
+ "venv/lib/python3.13/site-packages/git/refs/head.py": 16271128287606894569,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_arithmetic.py": 17043958604607035425,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/__init__.py": 15130871412783076140,
+ "venv/bin/dotenv": 953953349803507198,
+ "frontend/src/lib/components/reports/__tests__/report_card.ux.test.js": 10328656559485751380,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot_multilevel.py": 9830258607305392103,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/__init__.py": 18036348770966744795,
+ "venv/lib/python3.13/site-packages/pygments/console.py": 3540660073442483692,
+ "venv/lib/python3.13/site-packages/anyio/_core/_typedattr.py": 17584691045493791349,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_diff.py": 7420674239386436885,
+ "frontend/src/components/tasks/TaskResultPanel.svelte": 2978429516796744791,
+ "frontend/build/_app/env.js": 8815854342083926790,
+ "venv/lib/python3.13/site-packages/numpy/_core/printoptions.py": 3897105663572772838,
+ "venv/lib/python3.13/site-packages/pandas/core/algorithms.py": 487939626203097713,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/tzconversion.pyi": 10947021928755741366,
+ "venv/lib/python3.13/site-packages/requests/cookies.py": 4997226307650350876,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_where.py": 3272402211717453881,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/__init__.py": 260774374497653876,
+ "backend/src/api/routes/git/_merge_routes.py": 12751818588668193353,
+ "venv/lib/python3.13/site-packages/referencing/_attrs.pyi": 10030665705880994025,
+ "venv/lib/python3.13/site-packages/pydantic/plugin/_loader.py": 792663962985957671,
+ "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/RECORD": 1164466882742493155,
"backend/src/services/clean_release/artifact_catalog_loader.py": 16917420865314497219,
- "backend/tests/test_logger.py": 1310870055962234716,
- "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraypad.py": 4907193085512342162,
- "venv/lib/python3.13/site-packages/urllib3/util/timeout.py": 17922362393077965047,
- "venv/lib/python3.13/site-packages/authlib/consts.py": 14226604841596736870,
- "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-exp.csv": 601782991752922510,
- "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_tz_localize.py": 14495969595744172955,
- "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_groupby_dropna.py": 3620959914439334511,
- "venv/lib/python3.13/site-packages/numpy/core/getlimits.py": 14257687540182552408,
- "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_frame_equal.py": 12459816298158655274,
- "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_interval.py": 2911379732293827726,
+ "venv/lib/python3.13/site-packages/pygments/styles/coffee.py": 17584414468786822371,
+ "backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py": 990102078989024575,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/android.py": 8607703347015852195,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_partial.py": 3151286293440416036,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_weakref.py": 6780204527427742510,
+ "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.py": 16539612003028676816,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/async_timeout.py": 7267209982032642028,
+ "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/greenlet/_greenlet.cpython-313-x86_64-linux-gnu.so": 6036818030377883416,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust.abi3.so": 2537152913308578487,
+ "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/METADATA": 4954909612926293404,
+ "venv/lib/python3.13/site-packages/numpy/_distributor_init.py": 1101690714183863290,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py": 5995058808539530576,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_data.py": 2397937327057341,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/inspect.py": 1401259241736437656,
+ "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_timedelta.py": 364160935264757405,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/methods.py": 8059372834301557565,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/state.py": 10500170103357297551,
+ "venv/lib/python3.13/site-packages/pip/_vendor/dependency_groups/__main__.py": 11917862648584782420,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/reflection.py": 1799734694597531652,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/exceptions.py": 7518613450390473990,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_polynomial.py": 777287409151500309,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_utils.py": 10362977406431569031,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/__init__.py": 8807410829260170597,
+ "venv/lib/python3.13/site-packages/dateutil/tzwin.py": 5149446703746204349,
+ "venv/lib/python3.13/site-packages/urllib3/util/request.py": 9432067988603015849,
+ "venv/lib/python3.13/site-packages/pandas/io/orc.py": 12754290195886557668,
+ "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_normalize.py": 3203921571999101793,
+ "venv/lib/python3.13/site-packages/uvicorn/importer.py": 5449629250971153435,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_vim_builtins.py": 6842381248727719900,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_cumulative.py": 16283954014170928273,
+ "venv/lib/python3.13/site-packages/pygments/lexers/parsers.py": 12372594608244797844,
+ "venv/lib/python3.13/site-packages/gitdb/typ.py": 16374739906244805047,
+ "venv/lib/python3.13/site-packages/pygments/lexers/numbair.py": 17382646010399794697,
+ "venv/lib/python3.13/site-packages/pygments/lexers/lisp.py": 11872331622183590758,
+ "venv/lib/python3.13/site-packages/pygments/lexers/nix.py": 15050086330545600356,
+ "venv/lib/python3.13/site-packages/pygments/lexer.py": 3658450949169647228,
+ "venv/include/site/python3.13/greenlet/greenlet.h": 16216120538647882082,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/__init__.py": 15130871412783076140,
+ "frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js": 16890149311572703440,
+ "frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js": 2673586123384011532,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/xmlrpc.py": 5064964778750366059,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_csky_gcc.h": 12929785267195988209,
+ "venv/lib/python3.13/site-packages/numpy/f2py/cb_rules.py": 11397521081216402594,
+ "venv/lib/python3.13/site-packages/fastapi/security/__init__.py": 1345944646061334046,
+ "venv/lib/python3.13/site-packages/anyio/from_thread.py": 7973678341601453474,
+ "venv/lib/python3.13/site-packages/numpy/strings/__init__.py": 6523674574341354095,
+ "venv/lib/python3.13/site-packages/keyring/errors.py": 4587094338672775040,
+ "venv/lib/python3.13/site-packages/pydantic/v1/errors.py": 11245135449608452720,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/timestamps.cpython-313-x86_64-linux-gnu.so": 13209491675968970365,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_aggregation.py": 16863055892192070549,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_deprecated_kwargs.py": 10379929935087904974,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_f2py2e.py": 8571347023940385644,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log2.csv": 13979868713429167140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_luau_builtins.py": 13690910306072616818,
+ "venv/lib/python3.13/site-packages/pygments/lexers/varnish.py": 3608370156692616959,
+ "venv/lib/python3.13/site-packages/pygments/lexers/solidity.py": 5071425960622305629,
+ "venv/lib/python3.13/site-packages/packaging/_manylinux.py": 8268418900652790584,
+ "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_gen_files.py": 11149423183253618378,
+ "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/METADATA": 2604612822968175379,
+ "frontend/build/_app/immutable/chunks/BAEbOLv3.js": 18043792224008034479,
+ "venv/lib/python3.13/site-packages/pandas/core/accessor.py": 1188716996113179524,
+ "backend/src/services/clean_release/policy_engine.py": 7078053766918689048,
+ "venv/lib/python3.13/site-packages/jose/backends/ecdsa_backend.py": 2684176977865283060,
+ "backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py": 968076476163114767,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/test_indexing.py": 1947969642791009285,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_forward_ref.py": 10623110912945011703,
+ "venv/lib/python3.13/site-packages/greenlet/CObjects.cpp": 3454797518210223926,
+ "backend/src/plugins/llm_analysis/__tests__/test_screenshot_service.py": 359905908083162759,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/string.py": 14718123345899686696,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_stata_builtins.py": 18053452765493556047,
+ "venv/lib/python3.13/site-packages/cffi/cparser.py": 5246372077864988755,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/_writer.py": 15053365792216907149,
+ "venv/lib/python3.13/site-packages/rsa/pkcs1.py": 2576732594642491910,
+ "frontend/src/components/EnvSelector.svelte": 6483243153689240649,
+ "backend/src/core/__tests__/test_config_manager_compat.py": 16202699597948342431,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/appdirs.py": 539688259643447487,
+ "venv/lib/python3.13/site-packages/pip/_vendor/__init__.py": 11734104142988812647,
+ "venv/lib/python3.13/site-packages/urllib3/poolmanager.py": 15431313180245757657,
+ "venv/lib/python3.13/site-packages/numpy/lib/recfunctions.pyi": 10487441680587530350,
+ "backend/src/core/superset_client/__init__.py": 3185082867840025180,
+ "venv/lib/python3.13/site-packages/passlib/handlers/ldap_digests.py": 8658529184965699766,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/type_check.pyi": 1599910480066368464,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_cumulative.py": 15644124412739892167,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_timedelta.py": 17052461094717926538,
+ "backend/src/plugins/translate/service_utils.py": 15103456860964805370,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/exceptions.py": 14982764273485726199,
+ "venv/lib/python3.13/site-packages/pillow.libs/liblcms2-cc10e42f.so.2.0.17": 4221600618602131476,
+ "frontend/src/routes/tools/backups/+page.svelte": 2765328366215862593,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/tools.py": 16466182352694741629,
+ "venv/lib/python3.13/site-packages/numpy/_core/_rational_tests.cpython-313-x86_64-linux-gnu.so": 13475521165331256711,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_pydatetime.py": 16228315407662560992,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/httpsredirect.py": 5775982317459922443,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/win64python2.npy": 11005857803794805939,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/const_vs_enum.py": 12873459583943748931,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/codec.py": 14814999235499530522,
+ "venv/lib/python3.13/site-packages/numpy/_distributor_init.pyi": 1308368231471324581,
+ "venv/lib/python3.13/site-packages/numpy/core/multiarray.py": 18368443598659711836,
+ "venv/lib/python3.13/site-packages/jaraco/functools/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/lib/_shape_base_impl.pyi": 12052895927933479005,
+ "venv/lib/python3.13/site-packages/greenlet/TGreenlet.cpp": 4121171004360760212,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/hermite.pyi": 3573629536236108391,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_construct_object_arr.py": 4725156416161661681,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/request.py": 10484280068366411541,
+ "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.py": 15989335816452913951,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.f": 18215492757907465667,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_fiscal.py": 14652343698825214870,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/__init__.py": 6327819603201859020,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/deprecations.py": 7020540470348910770,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_compat.py": 11481259393140789881,
+ "venv/lib/python3.13/site-packages/pygments/lexers/hexdump.py": 10665271113239513484,
+ "backend/git_repos/remote/test-repo.git/refs/heads/main": 7667767390913789840,
+ "venv/lib/python3.13/site-packages/pydantic/experimental/arguments_schema.py": 8644805798814234457,
+ "frontend/build/_app/immutable/chunks/BEgtrFG1.js": 8322179021947182552,
+ "backend/src/core/auth/repository.py": 15675496219240601253,
+ "frontend/build/_app/immutable/nodes/25.D9n_59tf.js": 16181415213724830381,
+ "venv/lib/python3.13/site-packages/pydantic/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/__init__.py": 16146480198665866916,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_col.py": 14781555956509956371,
+ "venv/lib/python3.13/site-packages/PIL/ExifTags.py": 6869879826623916830,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tablegen.py": 2917626373516779857,
+ "venv/lib/python3.13/site-packages/pydantic/v1/color.py": 14545509649623975912,
+ "venv/lib/python3.13/site-packages/attrs/__init__.py": 9502968706258875910,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/intranges.py": 12536174834761591006,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_neighborhood_iterator_imp.h": 10634781863364525895,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timezones.py": 1962830142478494009,
+ "venv/lib/python3.13/site-packages/pytest/__main__.py": 8747175113746141224,
+ "backend/src/models/storage.py": 14886607138033931307,
+ "backend/src/services/maintenance/_chart_manager.py": 11268757631496775895,
+ "venv/lib/python3.13/site-packages/pygments/lexers/x10.py": 6167378515780115912,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/utils.py": 6147480543268737542,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ambient.py": 18106929781201758080,
+ "venv/lib/python3.13/site-packages/pycparser/_build_tables.py": 569728086093219621,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/converter.py": 9041278869295701566,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/wheel_editable.py": 14352954849821931255,
+ "venv/lib/python3.13/site-packages/pandas/_libs/pandas_datetime.cpython-313-x86_64-linux-gnu.so": 15874094681262240628,
+ "venv/lib/python3.13/site-packages/pandas/tests/libs/test_libalgos.py": 13934861984871432400,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_docs_extraction.py": 5210114991139191634,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_na_scalar.py": 13950899907067372014,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/interfaces.py": 1532245423878428608,
+ "venv/lib/python3.13/site-packages/pygments/lexers/configs.py": 7712797939104760185,
+ "venv/lib/python3.13/site-packages/pygments/lexers/console.py": 18266795648198475028,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/__init__.py": 15130871412783076140,
+ "backend/tests/core/test_git_service_gitea_pr.py": 18003501172717000629,
+ "venv/lib/python3.13/site-packages/pygments/styles/stata_light.py": 16319330015324455277,
+ "backend/alembic/versions/b0c1d2e3f4a5_cascade_ondelete_translate_fks.py": 1764442834210967136,
+ "venv/lib/python3.13/site-packages/keyring/compat/properties.py": 1562771115138037410,
+ "venv/lib/python3.13/site-packages/pandas/tests/computation/test_compat.py": 11655000938111420543,
+ "frontend/src/lib/components/translate/CorrectionCell.svelte": 17398304999652244378,
+ "venv/lib/python3.13/site-packages/authlib/oidc/discovery/models.py": 6924198551176217533,
+ "venv/lib/python3.13/site-packages/numpy/fft/__init__.pyi": 10354990065626209946,
+ "venv/lib/python3.13/site-packages/referencing/tests/test_retrieval.py": 10782087416909177703,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/block.f": 10727418304254548946,
+ "frontend/src/app.html": 10207534912546549080,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_xs.py": 1897144171324167738,
+ "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/WHEEL": 1598805043198466373,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_pivot.py": 334735766122314163,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/type_api.py": 10299750173867399533,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/expression.py": 15511250785671695359,
+ "venv/lib/python3.13/site-packages/attr/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/fastapi/_compat/shared.py": 5249003014594464718,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py": 8530403239168529668,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/secrets.py": 17816662030600756342,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/gh24008.f": 3872245077994936272,
+ "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/RECORD": 4487477737768669516,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/server.py": 885415484558949506,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_ewm.py": 13789842684407148830,
+ "frontend/playwright-report/trace/index.html": 6654608714409350530,
+ "backend/src/plugins/llm_analysis/__init__.py": 9254812131558249924,
+ "venv/lib/python3.13/site-packages/pygments/token.py": 6987328478153445584,
+ "venv/lib/python3.13/site-packages/cryptography/x509/general_name.py": 4481582226129488535,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_extending.py": 10202091354750153497,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64_np126.pkl.gz": 1630203486813146863,
+ "frontend/build/_app/immutable/nodes/36.BNORbvJG.js": 6540996846559400613,
+ "backend/tests/test_smoke_app.py": 15091189356064171349,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_client/integration.py": 13610682193839598457,
+ "venv/lib/python3.13/site-packages/pandas/io/common.py": 12088195203620154171,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/create.py": 16693261531832306870,
+ "venv/lib/python3.13/site-packages/pygments/lexers/other.py": 6893672181003034910,
+ "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/RECORD": 10552906886624188222,
+ "venv/lib/python3.13/site-packages/PIL/TgaImagePlugin.py": 9208942494595222259,
+ "backend/src/services/clean_release/repositories/artifact_repository.py": 7507938934134519998,
+ "venv/lib/python3.13/site-packages/certifi/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/greenlet/TUserGreenlet.cpp": 16258622236210473101,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/response.py": 353446217435156470,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_factorize.py": 5585211699185937865,
+ "venv/lib/python3.13/site-packages/pytest_asyncio/plugin.py": 13414541723622354359,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py": 16768579082462294745,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/cython/setup.py": 17086801293303202021,
+ "venv/lib/python3.13/site-packages/PIL/ImageDraw2.py": 13610162107593278891,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/common.py": 1113935558495455492,
+ "venv/lib/python3.13/site-packages/idna/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.py": 17055498803745289016,
+ "venv/bin/activate": 14735074000123383125,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_py.py": 6518425342376455821,
+ "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/WHEEL": 12146818530001975731,
+ "venv/lib/python3.13/site-packages/typing_inspection-0.4.2.dist-info/METADATA": 14126682758562488244,
+ "venv/lib/python3.13/site-packages/pyasn1/type/univ.py": 7163437624197683039,
+ "backend/src/api/routes/assistant/_llm_planner_intent.py": 1835887541250815399,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/infer.py": 12541904372617915365,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_base_indexer.py": 3129123098288498633,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_base.py": 16710163879060522196,
+ "venv/lib/python3.13/site-packages/numpy/core/overrides.py": 11228841530565061867,
+ "venv/lib/python3.13/site-packages/passlib/pwd.py": 14727089240749133060,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/der/encoder.py": 4790267438222037867,
+ "venv/lib/python3.13/site-packages/numpy/random/_examples/cython/extending_distributions.pyx": 15302775787158991386,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_array_interface.py": 13648006002292914247,
+ "venv/lib/python3.13/site-packages/pip/_internal/vcs/versioncontrol.py": 13742159245132241245,
+ "venv/lib/python3.13/site-packages/pygments/lexers/felix.py": 2334148799642808111,
+ "venv/lib/python3.13/site-packages/pydantic/v1/utils.py": 902648247561165429,
+ "venv/lib/python3.13/site-packages/passlib/handlers/argon2.py": 835074952952017434,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_misc.py": 9190561773853901527,
+ "venv/lib/python3.13/site-packages/anyio/abc/_testing.py": 16484863782452886547,
+ "venv/lib/python3.13/site-packages/numpy/linalg/_linalg.py": 9654828595008925976,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_free.f90": 8821492401453445757,
+ "venv/lib/python3.13/site-packages/git/refs/tag.py": 9979537867501757110,
+ "venv/lib/python3.13/site-packages/git/repo/fun.py": 9019364012746153312,
+ "frontend/src/routes/settings/git/+page.svelte": 13757324397807811651,
+ "venv/lib/python3.13/site-packages/PIL/Hdf5StubImagePlugin.py": 15654153796225833950,
+ "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension_cpp.cpython-313-x86_64-linux-gnu.so": 7659849621107414188,
+ "venv/lib/python3.13/site-packages/jose/backends/rsa_backend.py": 13507186353881931758,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/test_typing.py": 10311989961588249147,
+ "docker/all-in-one.Dockerfile": 10896793266219904099,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/der/__init__.py": 15728752901274520502,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/missing.py": 11241703105777668183,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/interval/test_interval_pyarrow.py": 3849382723890414899,
+ "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/licenses/LICENSE": 3868190977070717994,
+ "venv/lib/python3.13/site-packages/pandas/core/strings/__init__.py": 13025387151657797130,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/__init__.py": 10470644151952252331,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_format.py": 5231304674283854194,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/conftest.py": 5864037534050136837,
+ "frontend/src/routes/dashboards/health/+page.svelte": 11635018493969113169,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/expression.py": 1248029135284283479,
+ "backend/alembic/versions/c4a3a2f74bfe_add_missing_columns_needs_review_.py": 4320606555167902916,
+ "frontend/eslint.config.js": 14296985543214702398,
+ "venv/lib/python3.13/site-packages/httpx/_types.py": 12461152436147308761,
+ "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/METADATA": 2053484635654179443,
+ "backend/src/services/clean_release/repositories/approval_repository.py": 11060626515832882475,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/installation_report.py": 14534544543677907640,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/cron/__init__.py": 14268033439436797364,
+ "venv/lib/python3.13/site-packages/numpy/lib/_scimath_impl.pyi": 8879196542984811747,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/ec_key.py": 5961540064444749833,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_reorder_levels.py": 10996225584998355824,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_interval.py": 14749388246573356959,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_inclusive.py": 1389676378885557519,
+ "backend/src/api/routes/migration.py": 16089356899043357784,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_greenlet.py": 10727595500186011102,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/connection.py": 1539337414493486168,
+ "venv/lib/python3.13/site-packages/keyring/completion.py": 1027436016070040568,
+ "venv/lib/python3.13/site-packages/PIL/XpmImagePlugin.py": 6644626557482464312,
+ "venv/lib/python3.13/site-packages/git/objects/blob.py": 8972374723153211283,
+ "venv/lib/python3.13/site-packages/PIL/_imaging.cpython-313-x86_64-linux-gnu.so": 1425926264271197601,
+ "venv/lib/python3.13/site-packages/pandas/io/parsers/python_parser.py": 7297059565749331767,
+ "backend/git_repos/remote/test-repo.git/objects/00/fcf77cecdf261aef91eda792ab3384a3339922": 1527330822006618217,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/_pytest/_code/source.py": 9488112979192923739,
+ "venv/lib/python3.13/site-packages/pyasn1/type/error.py": 1479878696626082697,
+ "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/__init__.py": 8434616194114282088,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/polynomial_series.pyi": 7112486730197067087,
+ "venv/lib/python3.13/site-packages/pycparser/_c_ast.cfg": 2649342580905806389,
+ "frontend/src/pages/Dashboard.svelte": 16189908777731571070,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/vectorized.cpython-313-x86_64-linux-gnu.so": 5441755022198996487,
+ "backend/src/api/__init__.py": 5287505122015708040,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_encs.py": 9703572751543253904,
+ "backend/src/plugins/translate/orchestrator_aggregator.py": 1906675302571034503,
+ "frontend/src/lib/stores/taskDrawer.js": 16349119158364586930,
+ "venv/lib/python3.13/site-packages/pandas/core/sample.py": 11913688303879867963,
+ "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_intervalindex.py": 5053113227747333759,
+ "backend/git_repos/remote/test-repo.git/objects/4e/227f4d8289ea657ae813b1460f979ae4b676b3": 5659284628452785331,
+ "venv/lib/python3.13/site-packages/attr/setters.py": 12467854389745942025,
+ "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/RECORD": 16558021503346615951,
+ "backend/src/api/routes/maintenance/_router.py": 1368406181799456173,
+ "backend/_convert_defs.py": 208535643309836247,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fromnumeric.pyi": 8671744104085911610,
+ "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pycparser/_ast_gen.py": 5464347629908906775,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_asof.py": 15792528637923603240,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_cte.py": 9274103293201050794,
+ "venv/lib/python3.13/site-packages/PIL/_imagingft.pyi": 1385456134120145584,
+ "backend/src/api/routes/dashboards/_listing_routes.py": 10092152880931335002,
+ "venv/lib/python3.13/site-packages/_pytest/_argcomplete.py": 3586514420674089892,
+ "venv/lib/python3.13/site-packages/PIL/ImageOps.py": 3884310863548175682,
+ "venv/lib/python3.13/site-packages/httpx/__version__.py": 9473642134297828811,
+ "venv/lib/python3.13/site-packages/jeepney/low_level.py": 6546206679858571608,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/base_server.py": 9643197259080504542,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/index.py": 2839270935469791607,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_exceptions.py": 15290185665769490169,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/arithmetic.pyi": 10265823318697442495,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/freeze.py": 8644678595442275485,
+ "venv/lib/python3.13/site-packages/pandas/core/tools/timedeltas.py": 7221393731712061943,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler.py": 1341849861184131135,
+ "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/METADATA": 15876173086384975957,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_ppc_unix.h": 9608771997528633681,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.py": 3762934316884129514,
"venv/lib/python3.13/site-packages/websockets/exceptions.py": 12048063047468402740,
- "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/WHEEL": 2357997949040430835
+ "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/pickleable.py": 7712040860601343075,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/poly1305.py": 10854598965202354516,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/implicit.py": 5400555157488808948,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_astype.py": 8505605634958454768,
+ "venv/lib/python3.13/site-packages/dateutil/__init__.py": 17666544837260663800,
+ "frontend/build/_app/immutable/nodes/13.CDE6GkmM.js": 4106587619847708568,
+ "backend/git_repos/remote/test-repo.git/objects/79/b070ad8af7bbc12169f7660d2a7a72ec7a889a": 8153595714065675791,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth2/authorization_server.py": 2913800420669417152,
+ "backend/src/services/clean_release/compliance_orchestrator.py": 6747364300631405520,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_odfreader.py": 2760916559416783928,
+ "venv/lib/python3.13/site-packages/numpy/core/_dtype.py": 2806449741844148191,
+ "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/apps.py": 4219758952914498116,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_round_trip.py": 14684057343786032776,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/base.py": 12948318231066662045,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/bitwise_ops.pyi": 751490187478960891,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/PIL/_tkinter_finder.py": 14045496501810535432,
+ "venv/lib/python3.13/site-packages/click/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/greenlet/TMainGreenlet.cpp": 9489520001674089404,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/unused_registry.py": 10153622516112471812,
+ "venv/lib/python3.13/site-packages/keyring/testing/backend.py": 14295829193445781542,
+ "venv/lib/python3.13/site-packages/cryptography/exceptions.py": 5173540025160237758,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/RECORD": 17545477863793260029,
+ "venv/lib/python3.13/site-packages/pygments/styles/nord.py": 8469538903422182155,
+ "venv/lib/python3.13/site-packages/smmap/test/test_tutorial.py": 16309370344201290582,
+ "frontend/build/_app/immutable/chunks/DsnmJJEf.js": 17416107759626312632,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py": 10843527833285941674,
+ "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE.PSF": 13208428090829817329,
+ "venv/lib/python3.13/site-packages/itsdangerous/signer.py": 3694661094753475840,
+ "venv/lib/python3.13/site-packages/requests/structures.py": 2668010839316715865,
+ "venv/lib/python3.13/site-packages/pip/__pip-runner__.py": 1138979712722199296,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/types.py": 13384984564922916167,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_m68k_gcc.h": 6580173800099450404,
+ "venv/lib/python3.13/site-packages/referencing/__init__.py": 10093824711214801917,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7591/errors.py": 17581857895562494222,
+ "venv/lib/python3.13/site-packages/numpy/conftest.py": 8971879716683736515,
+ "venv/lib/python3.13/site-packages/websockets/asyncio/compatibility.py": 9716993942839407921,
+ "venv/lib/python3.13/site-packages/numpy/f2py/diagnose.py": 503331864022631297,
+ "venv/lib/python3.13/site-packages/pandas-3.0.1.dist-info/WHEEL": 11630459739183915695,
+ "frontend/build/_app/immutable/chunks/DA0oX2nF.js": 4762485859359244720,
+ "frontend/tests/maintenance-store.test.ts": 7211673236234440419,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_concat.py": 1351478313334379336,
+ "backend/alembic/versions/b1c2d3e4f5a6_add_source_hash_to_translation_records.py": 4775534557742900399,
+ "backend/src/plugins/translate/service_bulk_replace.py": 5355744069308185607,
+ "venv/lib/python3.13/site-packages/pygments/lexers/dax.py": 10868881057512002309,
+ "backend/git_repos/remote/test-repo.git/hooks/pre-receive.sample": 6118492409684431911,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/accesstype.f90": 877982462186396830,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/ufunclike.pyi": 14623308681600207918,
+ "venv/lib/python3.13/site-packages/anyio/_core/_contextmanagers.py": 1258491775823080427,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_factorize.py": 17995673140216929494,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/heuristics.py": 1422768761337195135,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_frame_transform.py": 6759417099641034692,
+ "backend/src/core/task_manager/persistence.py": 9599258324212845325,
+ "venv/lib/python3.13/site-packages/fastapi/routing.py": 466387159689567541,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_fillna.py": 4610666845291315333,
+ "venv/lib/python3.13/site-packages/fastapi/responses.py": 6092572095549573593,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/asyncio.py": 2517623574187179319,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_riscv_unix.h": 8607317131295864391,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/ssl_.py": 644667973700652263,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/conftest.py": 10673264126684571493,
+ "venv/lib/python3.13/site-packages/requests/auth.py": 912521029864094489,
+ "venv/lib/python3.13/site-packages/pygments/lexers/theorem.py": 15666523910367201285,
+ "frontend/build/_app/immutable/chunks/Ct73Sust.js": 3385889491616825090,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_repeat.py": 16971624301893342868,
+ "venv/lib/python3.13/site-packages/websockets/speedups.c": 11800200877763464246,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi": 8666343427862784832,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation": 4826455560768665215,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/zookeeper.py": 4318643109309626098,
+ "venv/lib/python3.13/site-packages/numpy/__init__.py": 2331213407497901634,
+ "venv/lib/python3.13/site-packages/numpy/random/_bounded_integers.pxd": 9126772093305708921,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/printing.py": 8681519649669408795,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_fillna.py": 9297637486401098611,
+ "venv/lib/python3.13/site-packages/PIL/_imagingmath.pyi": 18222325750818585549,
+ "venv/bin/fastapi": 12400009726251862770,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/util.py": 9373891872370603585,
+ "backend/src/plugins/translate/__tests__/test_orchestrator.py": 10313792176402719801,
+ "frontend/build/_app/immutable/nodes/1.DqVrwQJv.js": 13991321400801874043,
+ "venv/lib/python3.13/site-packages/numpy/_core/lib/libnpymath.a": 17555816778997028283,
+ "frontend/src/components/llm/ValidationReport.svelte": 17900215752976182981,
+ "venv/lib/python3.13/site-packages/packaging/version.py": 13470993734108007779,
+ "frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js": 15614617116241362179,
+ "backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py": 7304392396276280230,
+ "backend/git_repos/remote/test-repo.git/hooks/post-update.sample": 4288868784459664203,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/__init__.pyi": 1942236362568669510,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/recfunctions.py": 18330899924171767482,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/util.py": 6088868370298560146,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/wsproto_impl.py": 3072714633272661847,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/modules/gh26920/two_mods_with_no_public_entities.f90": 12296500845667555672,
+ "backend/git_repos/remote/test-repo.git/objects/22/91d2eb86d77accf7401f8952778809cd1aa4d4": 5120428041118096941,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/models.py": 17356033861792227817,
+ "backend/src/models/translate.py": 15158235523537226249,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/integer.py": 7775055011080964709,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/METADATA": 6557531107125553027,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_size.py": 14032390806503440750,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/factory.py": 3042005457138956499,
+ "venv/lib/python3.13/site-packages/pillow.libs/libavif-01e67780.so.16.3.0": 13947441788826399574,
+ "venv/lib/python3.13/site-packages/cffi/vengine_cpy.py": 10684192171370688079,
+ "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_skew.py": 5276102682005383261,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py": 15060063324909302240,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_mixed.py": 3476101699679108025,
+ "venv/lib/python3.13/site-packages/pygments/lexers/snobol.py": 414946539602526513,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/userinfo.py": 17201158389976619872,
+ "venv/lib/python3.13/site-packages/pip/_vendor/certifi/__main__.py": 8412594868333244844,
+ "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/LICENSE": 12064892310002036996,
+ "frontend/src/routes/admin/roles/+page.svelte": 7687872545536151950,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numerictypes.py": 5719374287454872555,
+ "venv/lib/python3.13/site-packages/pandas/_libs/interval.cpython-313-x86_64-linux-gnu.so": 8964760352224019544,
+ "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/RECORD": 17341460504914308184,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/sum_.py": 7062070517544958546,
+ "frontend/src/components/Toast.svelte": 1736760619841085958,
+ "backend/src/plugins/translate/prompt_builder.py": 11939931262286362350,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_factorize.py": 861897342553280506,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_equals.py": 9405821443172167066,
+ "venv/lib/python3.13/site-packages/h11/__init__.py": 222801976520197308,
+ "venv/lib/python3.13/site-packages/keyring/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_keywords.py": 11487954623214475915,
+ "venv/lib/python3.13/site-packages/passlib/tests/sample1b.cfg": 2872366861156549016,
+ "venv/lib/python3.13/site-packages/pandas/tests/resample/test_resample_api.py": 3278209206670699265,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_custom_business_day.py": 2200008998040663785,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/profiling.py": 16030397164203895281,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_scilab_builtins.py": 17453812809700086888,
+ "frontend/src/components/storage/FileList.svelte": 6226735853135032532,
+ "frontend/src/components/backups/BackupManager.svelte": 15318298322895797591,
+ "venv/lib/python3.13/site-packages/numpy/random/_mt19937.pyi": 15904463104068500379,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_direct.py": 12680113511641199070,
+ "venv/lib/python3.13/site-packages/pydantic/v1/version.py": 2758971830527526972,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_matmul.py": 16169282225324014901,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_split_partition.py": 2715491071550545667,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_explode.py": 18263694040596159591,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/json.py": 4660603129768960095,
+ "frontend/src/components/tasks/TaskLogPanel.svelte": 10382066588776421689,
+ "venv/lib/python3.13/site-packages/apscheduler/jobstores/base.py": 11386927749822539057,
+ "venv/lib/python3.13/site-packages/passlib/tests/__main__.py": 16477180140297957650,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_series.py": 2980850649986213051,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_numba.py": 1668304729617150075,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/__init__.py": 15130871412783076140,
+ "backend/src/services/validation_run_service.py": 5527352359336135164,
+ "venv/lib/python3.13/site-packages/git/index/typ.py": 11661540784850363024,
+ "backend/src/services/clean_release/__tests__/test_manifest_builder.py": 4923613189073397440,
+ "venv/lib/python3.13/site-packages/pandas/core/config_init.py": 16537122488227845090,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nth.py": 17151595277666975085,
+ "venv/lib/python3.13/site-packages/pydantic/types.py": 785880062468926292,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_reductions.py": 3575617237516305456,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize_cpp.cpython-313-x86_64-linux-gnu.so": 7490281502544276964,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/client.py": 18443944554871937480,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/hkdf.py": 8539232219382152238,
+ "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/METADATA": 10707390829735099042,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/modules.py": 9023244176010175562,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/fromnumeric.py": 3792079757208879362,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_index_tricks.py": 4676293127859087991,
+ "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/RECORD": 6349071557579241461,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_fields.py": 2692892815545218335,
+ "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/WHEEL": 18203500019759199992,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/utils.py": 10346859893683522113,
+ "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.c": 9318655518998644962,
+ "backend/src/models/git.py": 9387561498910534118,
+ "venv/lib/python3.13/site-packages/pydantic/v1/annotated_types.py": 12925825196690299531,
+ "backend/src/core/cot_logger.py": 9539001363130629806,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/twisted.py": 2695602672085615762,
+ "venv/lib/python3.13/site-packages/packaging/_elffile.py": 9546225990833172494,
+ "frontend/src/routes/datasets/MetricsTable.svelte": 4644516916752609053,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/json.py": 17692639396786690144,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/named_types.py": 6099185243355915896,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test__iotools.py": 6260912730310453037,
+ "backend/src/plugins/storage/__init__.py": 5046554941488079204,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/panel.py": 17832701246248000383,
+ "venv/lib/python3.13/site-packages/pandas/core/missing.py": 13332302791063948992,
+ "backend/tests/core/test_migration_engine.py": 11015960127863747154,
+ "venv/lib/python3.13/site-packages/starlette/concurrency.py": 9835859079437525910,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.py": 13853220736499979380,
+ "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/RECORD": 12733654377842895588,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/persistence.py": 17908437937265384125,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_setops.py": 15196593522537569500,
+ "venv/lib/python3.13/site-packages/PIL/_imagingmorph.pyi": 18222325750818585549,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_combine_first.py": 11425059090050867171,
+ "venv/lib/python3.13/site-packages/_pytest/hookspec.py": 387790426108810884,
+ "venv/lib/python3.13/site-packages/PIL/BlpImagePlugin.py": 7209218638257731375,
+ "venv/lib/python3.13/site-packages/pygments/lexers/promql.py": 8929925488296216854,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_all_methods.py": 18227706645906325527,
+ "backend/test_app.db": 2486636812009447051,
+ "dist/docker/backend.0.1.0.tar.xz": 3591917885965226179,
+ "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/RECORD": 3288669175908898843,
+ "venv/lib/python3.13/site-packages/passlib/handlers/cisco.py": 15004707325761459775,
+ "venv/lib/python3.13/site-packages/typing_extensions.py": 8402965285733247527,
+ "venv/lib/python3.13/site-packages/numpy/lib/npyio.pyi": 3212440968296555560,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/AB.inc": 10441778083831997423,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/columns.py": 8488246354818721406,
+ "venv/lib/python3.13/site-packages/secretstorage/exceptions.py": 16701299261122689924,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/groupby.py": 5536922766239875007,
+ "venv/lib/python3.13/site-packages/_pytest/pytester.py": 5423287282155948827,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_inf.py": 8659210689723088321,
+ "venv/lib/python3.13/site-packages/pandas/io/_util.py": 13608922148814398500,
+ "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pydantic_core-2.41.5.dist-info/WHEEL": 15858869568085970864,
+ "frontend/src/lib/ui/index.ts": 6883965364006817450,
+ "backend/src/services/clean_release/repositories/audit_repository.py": 1431160646630812395,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_ufunc.py": 5025605639221470838,
+ "venv/lib/python3.13/site-packages/h11/_writers.py": 8585823094975171480,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pyproject_hooks/_impl.py": 16610770935842519289,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_infer_datetimelike.py": 17304541521108700317,
+ "backend/src/plugins/translate/_token_budget.py": 13508548690925198562,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/from_dataframe.py": 8278998381856028462,
+ "venv/lib/python3.13/site-packages/pytest-9.0.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.pyi": 14233146512272397376,
+ "venv/lib/python3.13/site-packages/numpy/_core/_operand_flag_tests.cpython-313-x86_64-linux-gnu.so": 12296711931541109624,
+ "venv/lib/python3.13/site-packages/pandas/core/_numba/kernels/var_.py": 12699521091170347311,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_operators.py": 12686786829906210592,
+ "venv/lib/python3.13/site-packages/pluggy/_version.py": 7195758686717994475,
+ "frontend/src/components/llm/__tests__/provider_config.integration.test.js": 2807487384272452401,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_msvc.h": 14580207065003376324,
+ "frontend/build/_app/immutable/nodes/7.CqIp9Pt6.js": 8474213930858732275,
+ "backend/src/services/clean_release/repository.py": 2475446738311184132,
+ "venv/lib/python3.13/site-packages/PIL/MspImagePlugin.py": 3034490726971829439,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_crackfortran.py": 10278720705326601943,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_nlargest_nsmallest.py": 11049656379959696695,
+ "backend/src/api/routes/git_schemas.py": 10492336192775355750,
+ "venv/lib/python3.13/site-packages/anyio/abc/_streams.py": 8089057973257658396,
+ "backend/src/api/routes/translate/_run_list_routes.py": 11620203305409913352,
+ "venv/lib/python3.13/site-packages/_pytest/mark/__init__.py": 9343015549300275714,
+ "venv/lib/python3.13/site-packages/_pytest/pathlib.py": 9719734558816066453,
+ "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.py": 15854257948148516490,
+ "venv/lib/python3.13/site-packages/numpy/_core/numeric.pyi": 17785360553418386488,
+ "venv/lib/python3.13/site-packages/numpy/_core/_methods.pyi": 9155045948490225716,
+ "venv/lib/python3.13/site-packages/git/refs/remote.py": 4391983355222612205,
+ "venv/lib/python3.13/site-packages/smmap-5.0.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/client.py": 7314311571224771,
+ "venv/lib/python3.13/site-packages/pygments/lexers/esoteric.py": 16839499623020685146,
+ "venv/lib/python3.13/site-packages/rsa/py.typed": 11041940105507257053,
+ "venv/lib/python3.13/site-packages/pandas/_libs/internals.cpython-313-x86_64-linux-gnu.so": 2008633361686956377,
+ "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/_pytest/legacypath.py": 7512065138259788426,
+ "venv/lib/python3.13/site-packages/pygments/lexers/rdf.py": 14488319292387226505,
+ "venv/lib/python3.13/site-packages/pygments/formatters/__init__.py": 8009871891954370829,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/legacy/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_args.py": 5821040955806257450,
+ "backend/src/plugins/translate/dictionary_filter.py": 18047895364995512274,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/copy_internals.py": 1245428320513062166,
+ "venv/lib/python3.13/site-packages/numpy/f2py/use_rules.py": 17277594393032382485,
+ "venv/lib/python3.13/site-packages/starlette/middleware/base.py": 16850428285382256618,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/dml.py": 17308908394336670576,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_function.py": 7048185308307653546,
+ "backend/alembic/versions/a5b6c7d8e9f0_set_null_ondelete_for_task_records_env_fk.py": 17528129825127496932,
+ "venv/lib/python3.13/site-packages/numpy/matlib.pyi": 8017902013455539981,
+ "venv/lib/python3.13/site-packages/ecdsa/curves.py": 812969717084691115,
+ "venv/lib/python3.13/site-packages/numpy/lib/_datasource.pyi": 5894423389796456573,
+ "venv/lib/python3.13/site-packages/numpy/testing/_private/utils.py": 3646474165295296669,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/align.py": 6078666505647454830,
+ "venv/lib/python3.13/site-packages/rapidfuzz/process.pyi": 6959881293311340830,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/text.py": 6096215585499446070,
+ "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.pyi": 12566839271245057531,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np126.pkl.gz": 9677994062701347206,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo77.f": 16250175448122328648,
+ "venv/lib/python3.13/site-packages/passlib/utils/__init__.py": 11704122205941631503,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_get_value.py": 389530025760539462,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_isin.py": 11330491145602008796,
+ "venv/lib/python3.13/site-packages/anyio/abc/_resources.py": 8330687082933028623,
+ "venv/lib/python3.13/site-packages/pandas/io/parsers/readers.py": 7899068668225389287,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/provision.py": 2676876852726658063,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.pyx": 17138729833735744777,
+ "backend/src/services/resource_service.py": 12557244514401781887,
+ "backend/src/services/clean_release/repositories/compliance_repository.py": 2888085832526178946,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_indexing.py": 6039808271042864401,
+ "backend/src/plugins/translate/__tests__/test_text_cleaner.py": 5456979246104056266,
+ "venv/lib/python3.13/site-packages/typing_extensions-4.15.0.dist-info/METADATA": 317417773265681256,
+ "venv/lib/python3.13/site-packages/websockets/http.py": 9406523480132204760,
+ "venv/lib/python3.13/site-packages/jose/jws.py": 11592462993417182096,
+ "venv/lib/python3.13/site-packages/numpy/lib/_arrayterator_impl.py": 4037074830103951000,
+ "venv/lib/python3.13/site-packages/starlette/config.py": 16509394679506300256,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/ciphers/modes.py": 6832635056228445650,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/console.py": 3540660073442483692,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_array.py": 11271807719833350332,
+ "frontend/playwright-report/trace/assets/defaultSettingsView-D31xz8zv.js": 1301407320635785789,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_2_compat.h": 6512969159139431485,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_sorted.py": 1899608688401238388,
+ "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/licenses/LICENSE": 11199044866758471950,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/padding.py": 7470483648602195268,
+ "venv/lib/python3.13/site-packages/pygments/lexers/json5.py": 9736695186548899403,
+ "venv/lib/python3.13/site-packages/numpy/_core/getlimits.pyi": 15746478550640231553,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/lib_utils.py": 4612923732868929770,
+ "venv/lib/python3.13/site-packages/numpy/f2py/rules.pyi": 1342380029484127983,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/direct_url.py": 4619204214785230341,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/interval/test_contains.py": 17630310725250553247,
+ "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/METADATA": 3814104793342833872,
+ "venv/lib/python3.13/site-packages/pygments/styles/lilypond.py": 12486578704132023691,
+ "venv/lib/python3.13/site-packages/pandas/core/sparse/__init__.py": 15130871412783076140,
+ "backend/src/services/clean_release/stages/no_external_endpoints.py": 5083253025896929417,
+ "backend/git_repos/remote/test-repo.git/objects/6a/f2b28e314c04fb4e03476c12d6491213591512": 4526311953587849385,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/__init__.pyi": 8708830448398500675,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_signature.py": 17075003201648027250,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_getitem.py": 11882213323878588707,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_compat.py": 6032546839876195115,
+ "backend/src/plugins/translate/metrics.py": 11628699537333742678,
+ "venv/lib/python3.13/site-packages/numpy/testing/_private/extbuild.py": 4984721349618127021,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_reindex.py": 12459492712890114705,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_style.py": 14810883299259169406,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/meta-data": 11957232619107868023,
+ "backend/alembic/versions/2a7b8c9d0e1f_add_target_languages_to_translation_jobs.py": 7201017059554918882,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_histograms.py": 47631283818191049,
+ "venv/lib/python3.13/site-packages/numpy/f2py/__version__.py": 8588600299261398598,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/publicmod.f90": 2174121054736811903,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Jaro_py.py": 11991492232381887787,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_validate_kwargs.py": 10173906126211473463,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/cer/encoder.py": 3261739474564948330,
+ "venv/lib/python3.13/site-packages/rapidfuzz-3.14.3.dist-info/WHEEL": 2823347510103459191,
+ "venv/lib/python3.13/site-packages/passlib/handlers/roundup.py": 3844280972451753019,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/string_.py": 14865733321317939478,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_offsets_properties.py": 2340780879864207500,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_ratio.py": 940213488194452623,
+ "venv/lib/python3.13/site-packages/pydantic/__init__.py": 11536052293866174672,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_index.py": 1551768441102117466,
+ "venv/lib/python3.13/site-packages/pip/_internal/vcs/git.py": 17060377178521307324,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/json.py": 6429651405841289922,
+ "venv/lib/python3.13/site-packages/PIL/ContainerIO.py": 7551929914241379005,
+ "frontend/e2e/e2e-nohealth.mjs": 5921562935931064381,
+ "venv/lib/python3.13/site-packages/referencing/jsonschema.py": 14596871117484757502,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_query_eval.py": 17613800806748649144,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_finalize.py": 12539815426478689538,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_amd64_unix.h": 16679226724722970205,
+ "venv/lib/python3.13/site-packages/attrs/setters.py": 5775359015245600592,
+ "backend/src/services/clean_release/audit_service.py": 13892224612412540989,
+ "backend/src/core/auth/api_key.py": 15898549010462339946,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_accuracy.py": 3904008607472505376,
+ "backend/tests/test_constants_audit_fixes.py": 18298690956132739779,
+ "backend/src/plugins/translate/executor.py": 15866803979457728942,
+ "backend/git_repos/remote/test-repo.git/hooks/fsmonitor-watchman.sample": 14381968406977928721,
+ "venv/lib/python3.13/site-packages/click/testing.py": 15973659312284678327,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_setops.py": 8622608042929141013,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api_latest.c": 5472633890472031814,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_style.py": 10405592363651914796,
+ "venv/lib/python3.13/site-packages/pillow.libs/libtiff-295fd75c.so.6.2.0": 17866578820357536656,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd.py": 7577408467041941595,
+ "venv/lib/python3.13/site-packages/pandas/_libs/hashing.pyi": 5241441378073929968,
+ "venv/lib/python3.13/site-packages/numpy/random/_common.pxd": 3402284125943848851,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_missing.py": 6224750552277937853,
+ "venv/lib/python3.13/site-packages/pandas/io/sas/sas_constants.py": 14492427939536692313,
+ "venv/lib/python3.13/site-packages/pygments/lexers/modeling.py": 15714077241620129689,
+ "backend/src/api/routes/git/_deps.py": 11478430655620147674,
+ "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/WHEEL": 8600534672961461758,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7521/__init__.py": 635200170992032966,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/serialize.py": 11139432164346742421,
+ "backend/src/services/superset_lookup_service.py": 131886522963644068,
+ "frontend/src/types/backup.ts": 1741234034896689348,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/jwe_algs.py": 2479791018067637690,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/moments/test_moments_consistency_expanding.py": 12504275097476819918,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_s3.py": 17425535047477778484,
+ "venv/lib/python3.13/site-packages/pygments/lexers/asc.py": 10744437946030875496,
+ "frontend/src/routes/tools/mapper/+page.svelte": 11733240042848459104,
+ "venv/lib/python3.13/site-packages/keyring/backend_complete.bash": 16589214602970214174,
+ "venv/lib/python3.13/site-packages/numpy/ma/tests/test_subclassing.py": 17318983445227658412,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh17797.f90": 17319074662077763768,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_astype.py": 8633811117672837999,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/arithmetic.py": 3209727509456212551,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mssql/pymssql.py": 6650008663791598065,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/plugin/pytestplugin.py": 1591034895268415944,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/controller.py": 5450931608244830335,
+ "backend/src/plugins/translate/__tests__/test_executor.py": 9030484360469714630,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_type_check.py": 3935091606923106753,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/appengine.py": 16194997685865850655,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/missing.py": 14589973874359353799,
+ "venv/lib/python3.13/site-packages/fastapi/param_functions.py": 14585101566697773072,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_classes.py": 1440926036579216168,
+ "venv/lib/python3.13/site-packages/pandas/api/typing/__init__.py": 6438268275857060114,
+ "backend/alembic.ini": 8897071018956157084,
+ "backend/src/services/git/_merge.py": 13573452468406399167,
+ "backend/git_repos/remote/test-repo.git/hooks/pre-push.sample": 8029776382195911768,
+ "venv/lib/python3.13/site-packages/numpy.libs/libgfortran-040039e1-0352e75f.so.5.0.0": 13946067868274850557,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_complex/foo77.f": 7353666717928699883,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_coercion.py": 7261787308019145312,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/__init__.py": 11526998905763262175,
+ "venv/lib/python3.13/site-packages/numpy/f2py/setup.cfg": 17974180080760231128,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_constructors.pyi": 164538008396001632,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.pyi": 5786150108623563787,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_cell_widths.py": 5724379364993806351,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/fields.py": 10090313990429695520,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_formats.py": 13500155167624433622,
+ "venv/lib/python3.13/site-packages/pygments/lexers/web.py": 11104721221615804497,
+ "venv/lib/python3.13/site-packages/numpy/f2py/src/fortranobject.c": 2519219289444051739,
+ "venv/lib/python3.13/site-packages/PIL/ImagePath.py": 18323293175183057101,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/METADATA": 6438256145634479451,
+ "venv/lib/python3.13/site-packages/cffi-2.0.0.dist-info/METADATA": 5628172948035858892,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tal.py": 447505725492547461,
+ "frontend/src/routes/translate/+page.svelte": 15284819686967093613,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reset_index.py": 5946666595195952693,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/pyinstaller-smoke.py": 13570990531070630950,
+ "frontend/src/lib/stores/__tests__/mocks/stores.js": 12764819706469057535,
+ "backend/src/services/clean_release/enums.py": 5838176998590033780,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_count.py": 9186538441380080087,
+ "venv/lib/python3.13/site-packages/pygments/lexers/php.py": 17636450950688953288,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_mangle_dupes.py": 15613858733226279352,
+ "venv/lib/python3.13/site-packages/pydantic/plugin/__init__.py": 16803973597469216174,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Levenshtein_py.py": 11350239659973489646,
+ "backend/src/api/routes/__tests__/test_migration_routes.py": 12273917934344716029,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/claims.py": 12645788445743898136,
+ "venv/lib/python3.13/site-packages/pip/_internal/index/__init__.py": 14829074315307489628,
+ "venv/lib/python3.13/site-packages/dateutil/_version.py": 8279235793001245767,
+ "backend/src/api/routes/translate/_router.py": 18140665710457768874,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7009/__init__.py": 1923528231486706442,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/datetime.py": 6816292030061301011,
+ "venv/lib/python3.13/site-packages/pillow.libs/libwebpdemux-747f2b49.so.2.0.17": 7615380692384566654,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/connection_pool.py": 8159971229245441880,
+ "venv/lib/python3.13/site-packages/tzlocal-5.3.1.dist-info/RECORD": 15574202654585730126,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_legendre.py": 18266595775500927868,
+ "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/METADATA": 10810011740984652381,
+ "venv/lib/python3.13/site-packages/h11-0.16.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/utils.py": 8633356372647820801,
+ "venv/lib/python3.13/site-packages/pillow.libs/libwebpmux-7f11e5ce.so.3.1.2": 13105940093474848953,
+ "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.cpython-313-x86_64-linux-gnu.so": 17652852308919396403,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/LCSseq.pyi": 16372699564794732463,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_getitem.py": 8414677531950073373,
+ "venv/lib/python3.13/site-packages/pandas/tests/computation/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_cython_aggregations.py": 10818895573637904764,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/io.py": 11072022722163954973,
+ "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/RECORD": 7914594107698271488,
+ "frontend/src/components/auth/ProtectedRoute.svelte": 9152870722988000278,
+ "frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js": 16008187945694980240,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE.APACHE": 11041304845352917971,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libselinux-0922c95c.so.1": 16516617710645376769,
+ "frontend/src/routes/datasets/__tests__/inline_edit.test.js": 17712409018171053453,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_groupby.py": 2738671407653333726,
+ "frontend/build/_app/immutable/chunks/Dul6iTE7.js": 10339509389374345579,
+ "backend/src/api/routes/__tests__/test_reports_openapi_conformance.py": 17231166761215151699,
+ "backend/src/api/routes/__tests__/conftest.py": 3768471623650776808,
+ "venv/lib/python3.13/site-packages/numpy/testing/print_coercion_tables.pyi": 3814281717779245045,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_quantile.py": 17110581927381599978,
+ "venv/lib/python3.13/site-packages/pygments/lexers/maple.py": 7402467573829618534,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_reindex_like.py": 13803156447991282315,
+ "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/LICENSE": 16174281248426886206,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_chunksize.py": 7107619871245389835,
+ "venv/lib/python3.13/site-packages/apscheduler/job.py": 1858376671986108667,
+ "backend/src/core/auth/oauth.py": 2441694487419087464,
+ "venv/lib/python3.13/site-packages/git/repo/__init__.py": 6173604284490891047,
+ "venv/lib/python3.13/site-packages/pygments/lexers/special.py": 4972294202790455038,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_partial_slicing.py": 16219611534574666182,
+ "backend/tests/test_logging_audit_fixes.py": 6972807998099938509,
+ "venv/lib/python3.13/site-packages/pandas/_libs/ops.cpython-313-x86_64-linux-gnu.so": 10490009128553397250,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_float.py": 10455718110956856820,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/_spdx.py": 17182188548503720124,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/conversion.pyi": 16976386782787920450,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_client/__init__.py": 14186136918454802843,
+ "frontend/src/lib/components/layout/sidebarNavigation.js": 14306348671588504207,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_datetime.py": 7862725028865965163,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets.py": 10923534235697247269,
+ "venv/lib/python3.13/site-packages/pygments/filter.py": 16846063190466267618,
+ "venv/bin/pyrsa-verify": 6762739642629904442,
+ "frontend/build/_app/immutable/chunks/CETQmtx2.js": 6702904950123068169,
+ "backend/src/models/dataset_review_pkg/_execution_models.py": 13278357366267031549,
+ "venv/lib/python3.13/site-packages/jeepney/io/threading.py": 525625939662612746,
+ "venv/lib/python3.13/site-packages/passlib/tests/_test_bad_register.py": 5446848310854472376,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_reshape.py": 5572426834735088916,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_concat.py": 4472503149811617440,
+ "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/METADATA": 3188324716322823755,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_duplicated.py": 6659959750254523427,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_append.py": 9644955836191900614,
+ "frontend/src/routes/+error.svelte": 9437886843842311915,
+ "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/style.py": 10665998898253460114,
+ "venv/lib/python3.13/site-packages/passlib/tests/__init__.py": 16543763165305017760,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_regression.py": 9375525053479844400,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/util.py": 1520899420719605380,
+ "frontend/build/_app/immutable/chunks/gRGygy_f.js": 17282722948808474320,
+ "backend/src/core/__tests__/test_throttled_scheduler.py": 3526995607557121417,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_can_hold_element.py": 5406431247116557833,
+ "venv/lib/python3.13/site-packages/passlib/ifc.py": 14479133654556657428,
+ "venv/lib/python3.13/site-packages/rsa/prime.py": 10820898885044917095,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-log10.csv": 13441294827017400897,
+ "venv/lib/python3.13/site-packages/pandas/core/tools/numeric.py": 8510988912136285022,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_qcut.py": 8972418112914954758,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/http_proxy.py": 14037211594707072958,
+ "venv/lib/python3.13/site-packages/cryptography/x509/extensions.py": 10197248868682803019,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_indexing.py": 81180636019259296,
+ "venv/lib/python3.13/site-packages/authlib/jose/__init__.py": 317573635113539563,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.py": 1590647503660777156,
+ "venv/lib/python3.13/site-packages/git/index/fun.py": 18338379518768926372,
+ "venv/lib/python3.13/site-packages/pygments/lexers/apdlexer.py": 14222752852221009085,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_numeric.py": 9417128508433693658,
+ "frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js": 7736587487210851851,
+ "venv/lib/python3.13/site-packages/sqlalchemy/types.py": 15819795572817819102,
+ "frontend/playwright-report/trace/assets/urlMatch-BYQrIQwR.js": 8070494174996726626,
+ "venv/lib/python3.13/site-packages/pygments/lexers/prql.py": 1159462562014166646,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_index_equal.py": 10617870815989304510,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/useless_applicator_schemas.py": 8395157526634674143,
+ "venv/lib/python3.13/site-packages/numpy/_utils/_pep440.pyi": 6796322258258182775,
+ "venv/lib/python3.13/site-packages/passlib/hosts.py": 11171402820797380938,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/putmask.py": 10934101690788549526,
+ "backend/alembic/script.py.mako": 7041141123739810216,
+ "venv/bin/httpx": 6651007446865716794,
+ "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/WHEEL": 7795541085444298627,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_ssl_constants.py": 14834514243239777933,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/html_table.tpl": 17198355067645888735,
+ "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/WHEEL": 14929202952940710322,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_masm.obj": 2884737706935637437,
+ "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_py.py": 6428078990080243608,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/annotation.py": 15855576199737688124,
+ "venv/lib/python3.13/site-packages/pandas/io/api.py": 8275376846208437741,
+ "venv/lib/python3.13/site-packages/yaml/cyaml.py": 9157893742065554693,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/generate_legacy_storage_files.py": 11015954144633661960,
+ "venv/lib/python3.13/site-packages/pygments/lexers/algebra.py": 9651893228421050246,
+ "venv/pyvenv.cfg": 2513607356761047446,
+ "venv/lib/python3.13/site-packages/pygments/lexers/markup.py": 10311057264960923433,
+ "venv/lib/python3.13/site-packages/pygments/lexers/mime.py": 7768464764849718825,
+ "backend/src/plugins/translate/preview_llm_client.py": 14412557858942627249,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/RECORD": 7844752443022514265,
+ "venv/lib/python3.13/site-packages/cryptography/x509/verification.py": 1079694784860492682,
+ "venv/lib/python3.13/site-packages/numpy/char/__init__.py": 4428218097234308768,
+ "backend/src/core/task_manager/models.py": 11636421249104836957,
+ "venv/lib/python3.13/site-packages/secretstorage/collection.py": 17903258621904912493,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_missing.py": 7034102519042351965,
+ "venv/lib/python3.13/site-packages/dateutil/tz/win.py": 8427821225251397364,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/__init__.py": 8093984834068317399,
+ "venv/lib/python3.13/site-packages/numpy/lib/_arraysetops_impl.py": 5583478355093966990,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/random.pyi": 9425735458050148191,
+ "frontend/src/lib/ui/Card.svelte": 8508366526326051165,
+ "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/licenses/LICENSE": 16147999986886816451,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_repr.py": 1758478941817868344,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_logical/foo90.f90": 12508663906609241323,
+ "venv/lib/python3.13/site-packages/starlette/exceptions.py": 15978811612997200737,
+ "venv/lib/python3.13/site-packages/numpy/lib/_stride_tricks_impl.pyi": 9243829615414967057,
+ "backend/src/services/maintenance/_orchestrators.py": 995360865260101856,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/pylock.py": 16697828625021519459,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py": 3369246520501764730,
+ "venv/lib/python3.13/site-packages/_pytest/tracemalloc.py": 5530234062530858720,
+ "venv/lib/python3.13/site-packages/numpy/ma/__init__.pyi": 1855615156913010107,
+ "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.pyi": 6534825471013879522,
+ "venv/lib/python3.13/site-packages/urllib3/_base_connection.py": 14495079097019980154,
+ "venv/lib/python3.13/site-packages/jaraco/context/__init__.py": 10975097417056278427,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/__init__.py": 3015263524218708013,
+ "frontend/src/routes/storage/backups/+page.svelte": 9728305121470326167,
+ "venv/lib/python3.13/site-packages/PIL/GimpPaletteFile.py": 2040459799887417392,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_value_counts.py": 15633881149834196174,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_php_builtins.py": 2344562378679281201,
+ "backend/src/services/clean_release/mappers.py": 16365217670331724280,
+ "frontend/src/lib/ui/LanguageSwitcher.svelte": 15175441556916164874,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/ops.py": 18250656489649699560,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/__init__.pyi": 17469792319379909312,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/arrow/array.py": 12658302948819867972,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/strategy_options.py": 16342048970907383117,
+ "venv/lib/python3.13/site-packages/bcrypt/_bcrypt.abi3.so": 8691731321358529264,
+ "frontend/playwright-report/trace/xtermModule.DYP7pi_n.css": 9346562810570076139,
+ "venv/lib/python3.13/site-packages/authlib/common/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/_string_helpers.py": 17192211156810267818,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/__init__.py": 371829636800613137,
+ "venv/lib/python3.13/site-packages/pygments/__main__.py": 13200500591994479045,
+ "venv/lib/python3.13/site-packages/rapidfuzz/_feature_detector_cpp.cpython-313-x86_64-linux-gnu.so": 16337157355618216738,
+ "venv/lib/python3.13/site-packages/urllib3/util/ssl_match_hostname.py": 7411350247004265632,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/validator.py": 14200019408839159476,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_api.py": 13319208721442328400,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/ndarrayobject.h": 7320510589635636690,
+ "venv/lib/python3.13/site-packages/PIL/PpmImagePlugin.py": 7107324729714470853,
+ "venv/lib/python3.13/site-packages/passlib/win32.py": 5311393450489898748,
+ "venv/lib/python3.13/site-packages/python_multipart/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/nimrod.py": 8457135214131458774,
+ "docker/frontend.Dockerfile": 11291701046055590331,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/__init__.py": 1229691061011958769,
+ "backend/src/plugins/llm_analysis/service.py": 8630918629937474981,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_fsspec.py": 6936167344144998172,
+ "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/session.py": 5126234270435358377,
+ "venv/lib/python3.13/site-packages/authlib/common/encoding.py": 52296066492753953,
+ "venv/lib/python3.13/site-packages/pydantic/v1/fields.py": 3948219773415054006,
+ "frontend/src/routes/+layout.svelte": 729110825767878269,
+ "frontend/build/_app/immutable/chunks/Dn-Kr3zV.js": 11981784044886973393,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_inference.py": 16402427186697071465,
+ "frontend/build/_app/immutable/assets/9.tn0RQdqM.css": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_bus.py": 4260827599660763641,
+ "venv/lib/python3.13/site-packages/pandas/_testing/_hypothesis.py": 12298650110193262367,
+ "venv/lib/python3.13/site-packages/numpy/random/bit_generator.pyi": 15790738442952696034,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_repeat.py": 9155935990114743583,
+ "venv/lib/python3.13/site-packages/charset_normalizer/constant.py": 3070316197495651997,
+ "backend/src/core/plugin_base.py": 5063738955101125652,
+ "venv/lib/python3.13/site-packages/websockets/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/WHEEL": 18203500019759199992,
+ "venv/lib/python3.13/site-packages/rapidfuzz/fuzz_cpp.cpython-313-x86_64-linux-gnu.so": 14187094676876471848,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/response.py": 15004896908941411698,
+ "venv/lib/python3.13/site-packages/starlette/routing.py": 16063812008141874150,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_cumulative.py": 6346947559103505068,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_format.py": 9331389900588353667,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_py.py": 13809503317864539103,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_return_character.py": 17168707712220699738,
+ "venv/lib/python3.13/site-packages/PIL/JpegImagePlugin.py": 10621639599916796689,
+ "venv/lib/python3.13/site-packages/PIL/ImtImagePlugin.py": 17599267755504817169,
+ "venv/lib/python3.13/site-packages/urllib3/http2/connection.py": 1661620860881397554,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/pager.py": 18072372651585577904,
+ "venv/lib/python3.13/site-packages/pygments/lexers/verifpal.py": 9190813166686923928,
+ "venv/lib/python3.13/site-packages/ecdsa/ellipticcurve.py": 15624510849346629163,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/measure.py": 18327922742808984428,
+ "venv/lib/python3.13/site-packages/attr/exceptions.py": 11532465891810816417,
+ "frontend/build/_app/immutable/nodes/40.B6yQkigH.js": 5534402906319190952,
+ "backend/src/services/clean_release/approval_service.py": 14346840951852454312,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_libgroupby.py": 9985769511561272200,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_arithmetic.py": 11620920548943067949,
+ "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_records.py": 18167578114159312327,
+ "frontend/src/components/llm/DocPreview.svelte": 14349224708133169902,
+ "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/__init__.py": 6489437464172324468,
+ "venv/lib/python3.13/site-packages/_pytest/recwarn.py": 15312759837838083596,
+ "venv/lib/python3.13/site-packages/pydantic/experimental/missing_sentinel.py": 1637241331832367709,
+ "backend/src/plugins/storage/plugin.py": 8516872254456553013,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/selection_prefs.py": 14700113736620314923,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/associationproxy.py": 7421910137064160936,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libkrb5-fcafa220.so.3.3": 5620628698712971642,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/spinner.py": 5564789578696016201,
+ "venv/lib/python3.13/site-packages/gitdb/test/test_stream.py": 18159319442241857857,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9207/parameter.py": 2793853093222900337,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/base_key.py": 10402800587070352851,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/grants/util.py": 18279366777506483176,
+ "venv/lib/python3.13/site-packages/annotated_doc/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/computation/test_eval.py": 2921337784087808487,
+ "venv/lib/python3.13/site-packages/pandas/io/sas/sas_xport.py": 16525568795475918874,
+ "venv/lib/python3.13/site-packages/pygments/lexers/clean.py": 17772169928835025327,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/errors.py": 2147619440137604907,
+ "backend/src/api/routes/assistant/_llm_planner.py": 7325833916307204752,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/test_insert.py": 9195027887301180927,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/usecols/test_usecols_basic.py": 16382444980424010514,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/__init__.py": 8632038387100622009,
+ "venv/lib/python3.13/site-packages/pandas/core/sparse/api.py": 9094651265692218821,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/base.py": 5491727479625093183,
+ "venv/lib/python3.13/site-packages/numpy/doc/ufuncs.py": 11706048944901534664,
+ "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/RECORD": 11976403473353722969,
+ "venv/lib/python3.13/site-packages/PIL/PixarImagePlugin.py": 12061717157676819554,
+ "venv/lib/python3.13/site-packages/pandas/_libs/sas.cpython-313-x86_64-linux-gnu.so": 16309838137741124637,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/array_constructors.py": 6727209833819502644,
+ "venv/lib/python3.13/site-packages/pip/_internal/locations/_distutils.py": 13559457590971821771,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/functions.py": 16567226076808693246,
+ "venv/lib/python3.13/site-packages/charset_normalizer-3.4.4.dist-info/METADATA": 4975169119201255384,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/__ufunc_api.c": 11535375410441493281,
+ "venv/lib/python3.13/site-packages/pandas/core/indexers/utils.py": 5861072573716897447,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/asymmetric/x448.py": 3960540415600165213,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/__init__.py": 15130871412783076140,
+ "frontend/src/lib/ui/Icon.svelte": 18238812161544525261,
+ "frontend/src/routes/settings/MigrationSettings.svelte": 12844990967512238268,
+ "venv/lib/python3.13/site-packages/fastapi/openapi/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6750/validator.py": 11486125578281617670,
+ "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo.f": 5690596225005490325,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/reshape.py": 5387892304726762127,
+ "venv/lib/python3.13/site-packages/pandas/io/sas/__init__.py": 8095743504390517992,
+ "venv/lib/python3.13/site-packages/PIL/PSDraw.py": 1927169421822446045,
+ "backend/src/plugins/translate/__tests__/test_preview.py": 13201708414970983394,
+ "venv/lib/python3.13/site-packages/passlib/apps.py": 4633269405597895766,
+ "backend/tests/conftest.py": 5565151856098492311,
+ "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA": 16700674024421191168,
+ "venv/lib/python3.13/site-packages/numpy/lib/_histograms_impl.py": 13446184230476677032,
+ "venv/lib/python3.13/site-packages/pandas/io/clipboards.py": 5183212433608887727,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/format.py": 3364941338174434661,
+ "frontend/build/_app/immutable/chunks/BddPqa-e.js": 3040470451817822725,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_docs.py": 17898499890274685198,
+ "backend/src/services/__tests__/test_rbac_permission_catalog.py": 2963458864311994307,
+ "venv/lib/python3.13/site-packages/urllib3/util/__init__.py": 2848870790459558599,
+ "backend/src/models/clean_release.py": 4198911944577810567,
+ "venv/lib/python3.13/site-packages/pip/_internal/pyproject.py": 6155748929233245415,
+ "backend/src/services/reports/__init__.py": 11818812865847046400,
+ "backend/src/plugins/translate/superset_executor.py": 5480256123348033488,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_isoc.py": 4923640657296076239,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/prompt.py": 9561640601516933380,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_values.py": 834951665649981397,
+ "venv/lib/python3.13/site-packages/keyring-25.7.0.dist-info/licenses/LICENSE": 3868190977070717994,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/authorization_code.py": 4958605540994687737,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_regression.py": 16266600037241221681,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema.py": 14454690938977069049,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/datetimes/test_constructors.py": 3440572832185940666,
+ "venv/lib/python3.13/site-packages/PIL/JpegPresets.py": 12342262642420923471,
+ "frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js": 3080911695504204499,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cos.csv": 12896264205153363031,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/random.py": 12722750410117529986,
+ "venv/lib/python3.13/site-packages/pandas/_libs/window/indexers.pyi": 9911899303567570646,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/WHEEL": 7414522633964952515,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_assign.py": 2647902466315482406,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/dictionary.py": 9599439750713575741,
+ "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/functions.py": 14107377669163193871,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/palette.py": 17383863392192572184,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/util.py": 4815334059917765852,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_namespace_utils.py": 5237766366340181382,
+ "venv/lib/python3.13/site-packages/pydantic/v1/typing.py": 13467331592583800299,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraypad.pyi": 12178766981280242620,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_character.py": 850554362222586199,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/streaming.py": 13202773554072937140,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/test_freq_attr.py": 7685756734926749093,
+ "venv/lib/python3.13/site-packages/rpds/__init__.pyi": 12037474523494903587,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_replace.py": 8784361132920473760,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated": 11193150813314469394,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/mysqldb.py": 2138006249556140141,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_extension.py": 17245018204352082978,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/gzip.py": 436886407566263171,
+ "venv/lib/python3.13/site-packages/numpy/lib/user_array.pyi": 1968484998382771986,
+ "venv/lib/python3.13/site-packages/jsonschema/benchmarks/subcomponents.py": 10365594934527289233,
+ "venv/lib/python3.13/site-packages/numpy/core/arrayprint.py": 9652368112174245943,
+ "venv/lib/python3.13/site-packages/PIL/_imagingcms.cpython-313-x86_64-linux-gnu.so": 15198265718775753589,
+ "venv/lib/python3.13/site-packages/PIL/_typing.py": 17407980360703360848,
+ "venv/lib/python3.13/site-packages/PIL/PngImagePlugin.py": 5076219228736706283,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/constants.pyi": 15633065380510755171,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/timeseries.py": 17641722582848932332,
+ "venv/lib/python3.13/site-packages/passlib/tests/tox_support.py": 9200774792427691602,
+ "backend/src/models/profile.py": 12524181549230399253,
+ "venv/lib/python3.13/site-packages/numpy/f2py/f90mod_rules.pyi": 18290764713161282980,
+ "venv/lib/python3.13/site-packages/passlib/handlers/pbkdf2.py": 16686685453577026643,
+ "venv/lib/python3.13/site-packages/cffi/error.py": 8147505969912539538,
+ "venv/lib/python3.13/site-packages/uvicorn/middleware/wsgi.py": 9179913252056394958,
+ "backend/test_auth.db": 18214842050920965999,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/period.py": 1181348384346239378,
+ "venv/lib/python3.13/site-packages/passlib/context.py": 10362592407593745107,
+ "venv/lib/python3.13/site-packages/anyio/_core/_tasks.py": 14104828341875599130,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/data/py2-np0-objarr.npy": 1615546603475261360,
+ "venv/lib/python3.13/site-packages/numpy/f2py/cfuncs.pyi": 8232620851756907417,
+ "venv/lib/python3.13/site-packages/starlette/convertors.py": 17839747154274354605,
+ "venv/lib/python3.13/site-packages/jose/utils.py": 1926138853970725083,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_truncate.py": 6478126371906156409,
+ "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/licenses/LICENSE": 3868190977070717994,
+ "venv/lib/python3.13/site-packages/pygments/styles/lightbulb.py": 12433916113773598760,
+ "frontend/src/routes/settings/+page.svelte": 13008569925433466788,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/test_constructors.py": 9478848417896027917,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/chararray.pyi": 17340224970247832290,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/moments/conftest.py": 6137462119729731945,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/conftest.py": 9673372914396625461,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_jsonschema_test_suite.py": 12733761462141495972,
+ "venv/lib/python3.13/site-packages/fastapi/security/utils.py": 2616633862993539558,
+ "venv/lib/python3.13/site-packages/PIL/ImageTransform.py": 7825940907094338808,
+ "venv/lib/python3.13/site-packages/attr/setters.pyi": 6670509359139243236,
+ "venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp": 15599148954148720463,
+ "venv/lib/python3.13/site-packages/numpy/lib/_npyio_impl.pyi": 6576645822227068922,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/implicit.py": 7379110378465568776,
+ "venv/lib/python3.13/site-packages/anyio/abc/_sockets.py": 15042495744291042062,
+ "venv/bin/pyrsa-encrypt": 5858278204727417482,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_equals.py": 6429101196875333574,
+ "frontend/src/routes/settings/__tests__/settings_page.ux.test.js": 14507112961464496362,
+ "frontend/src/services/toolsService.js": 1568142461283466080,
+ "venv/lib/python3.13/site-packages/authlib/common/urls.py": 13627272625165922482,
+ "venv/lib/python3.13/site-packages/numpy/lib/npyio.py": 6782361985454523908,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_matrix_linalg.py": 2858987911347541177,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/string/test_astype.py": 10171766562093740708,
+ "venv/lib/python3.13/site-packages/ecdsa/test_pyecdsa.py": 14542286382742044648,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/typst.tpl": 5055419073126793137,
+ "frontend/src/lib/components/MaintenanceEventsTable.svelte": 1697386217337210174,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_sql_builtins.py": 5906655440517434734,
+ "venv/lib/python3.13/site-packages/PIL/MpoImagePlugin.py": 644327650732339301,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_repr.py": 13147587049887075335,
+ "venv/lib/python3.13/site-packages/requests/_internal_utils.py": 4091305333167213279,
+ "venv/lib/python3.13/site-packages/python_multipart/multipart.py": 5677735019292537174,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/__init__.py": 9820770319106921495,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/arrayobject.h": 4345432890284821918,
+ "backend/alembic/versions/543d43d752b8_migrate_old_dictionary_entries_and_.py": 10988663686444687907,
+ "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/RECORD": 10036839994791510159,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/nonce.py": 18219168479887197733,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arrayterator.py": 1646530870049791291,
+ "venv/lib/python3.13/site-packages/websockets/uri.py": 264376168984862773,
+ "frontend/src/lib/stores/assistantChat.js": 16716458796178537885,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/hotp.py": 18325640697829098192,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-sinh.csv": 12358602501260667480,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/shape.py": 13410030168622484801,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_ddl.py": 3690189094298044728,
+ "venv/lib/python3.13/site-packages/pygments/styles/bw.py": 869630132791421268,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_reductions.py": 14432782234851468060,
+ "venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py": 932468678264370661,
+ "frontend/build/_app/immutable/chunks/Ck4a7ANl.js": 3561562300210641559,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/download.py": 7533669665002975823,
+ "venv/lib/python3.13/site-packages/_pytest/helpconfig.py": 3033477806668470951,
+ "venv/lib/python3.13/site-packages/referencing/typing.py": 8296636464219681747,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ufunclike.py": 12077553320554633586,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo90.f90": 58572216018544419,
+ "venv/lib/python3.13/site-packages/pandas/api/typing/aliases.py": 11194270368147942988,
+ "venv/lib/python3.13/site-packages/PIL/MpegImagePlugin.py": 7726254767528154514,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/color.py": 15062855556511243610,
+ "venv/lib/python3.13/site-packages/keyring/util/__init__.py": 9635016046220094473,
+ "venv/lib/python3.13/site-packages/ecdsa/test_malformed_sigs.py": 2606295770491528880,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo90.f90": 2435648607844815947,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_x64_msvc.h": 17581467060937454503,
+ "venv/lib/python3.13/site-packages/fastapi/__main__.py": 10755252341326986079,
+ "venv/lib/python3.13/site-packages/fastapi/_compat/v2.py": 15078491685917047095,
+ "venv/lib/python3.13/site-packages/authlib/deprecate.py": 3563885283090710443,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/install.py": 17631777189475433503,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/ssh.py": 16262079536832961001,
+ "venv/lib/python3.13/site-packages/anyio/_core/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/anyio/_backends/_trio.py": 4764555436057754985,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_normalize.py": 7378656958631172603,
+ "venv/lib/python3.13/site-packages/numpy/f2py/__main__.py": 12567751646090102167,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_sort_values.py": 15072305514178699398,
+ "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/WHEEL": 3749476255729626245,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/char.pyi": 1639810799219814643,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/tests/test_laguerre.py": 7475592201750602042,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_label_or_level_utils.py": 3423644585913150841,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_read.py": 8825002468745406134,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_multiindex.py": 13723677252432338937,
+ "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/INSTALLER": 17282701611721059870,
+ "frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js": 10120412205695269578,
+ "venv/lib/python3.13/site-packages/numpy/random/__init__.pyi": 13833571330152615376,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_constructors.py": 2439700578107653984,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-cbrt.csv": 8929553891827331780,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/style.py": 12654125988995362593,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/compiler.py": 13924519162400330589,
+ "venv/lib/python3.13/site-packages/uvicorn/lifespan/on.py": 2866195356090164296,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_formats.py": 5259100336852479395,
+ "venv/lib/python3.13/site-packages/PIL/PcfFontFile.py": 8867692961463798279,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py": 6167729964577005634,
+ "frontend/src/lib/api/translate/target-schema.js": 10665479411127476571,
+ "frontend/src/services/__tests__/gitService.test.js": 2011135397906862721,
+ "venv/lib/python3.13/site-packages/numpy/random/mtrand.cpython-313-x86_64-linux-gnu.so": 16146459667121787202,
+ "backend/src/services/clean_release/dto.py": 16033619016556005561,
+ "venv/lib/python3.13/site-packages/pygments/styles/algol_nu.py": 6229131016121450375,
+ "frontend/src/lib/components/assistant/__tests__/assistant_confirmation.integration.test.js": 12582020574293031526,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/__init__.py": 12266077985828139928,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/live_render.py": 14619617939683800204,
+ "venv/lib/python3.13/site-packages/passlib/crypto/__init__.py": 16409196868630049365,
+ "venv/lib/python3.13/site-packages/passlib/tests/utils.py": 15403198680231294263,
+ "venv/lib/python3.13/site-packages/pygments/lexers/data.py": 9365024327689738663,
+ "venv/lib/python3.13/site-packages/pygments/lexers/haskell.py": 8011341851439354724,
+ "venv/lib/python3.13/site-packages/python_multipart/__init__.py": 10290895261363712562,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_retain_attributes.py": 16210262356844956764,
+ "frontend/src/lib/components/reports/ReportCard.svelte": 7009840605870276729,
+ "venv/lib/python3.13/site-packages/websockets/legacy/client.py": 4032878587330592478,
+ "venv/lib/python3.13/site-packages/gitdb/test/__init__.py": 18393574323937353933,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/index_command.py": 15798187258841839292,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/ber/__init__.py": 15728752901274520502,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/jwe.py": 10478268710546063196,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/__init__.py": 71159121705871510,
+ "dist/docker/backend.0.1.1.tar.xz": 932529191402352855,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli_w/__init__.py": 12849371269359608058,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7515/__init__.py": 2791238481813240414,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/uninstall.py": 11003472265011262515,
+ "venv/lib/python3.13/site-packages/numpy/core/shape_base.py": 17925759824894973734,
+ "venv/lib/python3.13/site-packages/starlette/datastructures.py": 12097180838087229563,
+ "venv/lib/python3.13/site-packages/greenlet/TThreadStateCreator.hpp": 9887867766190459665,
+ "venv/lib/python3.13/site-packages/pandas/core/window/expanding.py": 14141093310397856286,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_timeseries_window.py": 1973365560758236222,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/JaroWinkler_py.py": 16189204441438239231,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/__init__.py": 3795218871212151351,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/base.py": 16888506204910366302,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/period/test_asfreq.py": 6162659555626011770,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_isocbind.py": 15031197044862908440,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/deprecation.py": 7435269308988385470,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/base.py": 14908084548919567658,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/dtypes/test_dtypes_basic.py": 10917162988625838981,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_to_offset.py": 3929599794655343911,
+ "venv/lib/python3.13/site-packages/pandas/_libs/sparse.pyi": 12526865400413362140,
+ "venv/lib/python3.13/site-packages/numpy/_core/umath.pyi": 11775804030935134661,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_sequence.py": 3721630758772772345,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_numpy_version.py": 849232015288488204,
+ "venv/lib/python3.13/site-packages/jeepney/io/common.py": 15160647397460834508,
+ "venv/lib/python3.13/site-packages/pandas/io/excel/_odswriter.py": 17220892094904423676,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_common.py": 2223069451949206319,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/_has_cy.py": 11979732417254560424,
+ "venv/lib/python3.13/site-packages/sqlalchemy/pool/__init__.py": 4337679908168515343,
+ "venv/lib/python3.13/site-packages/jeepney-0.9.0.dist-info/METADATA": 15225661995655327539,
+ "venv/lib/python3.13/site-packages/starlette/middleware/httpsredirect.py": 16837082808103815044,
+ "venv/lib/python3.13/site-packages/attrs/converters.py": 13109003765349201809,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/packages.py": 11689856177725665974,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_setitem.py": 14920902525192671548,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/websockets/websockets_impl.py": 15673691977157706075,
+ "frontend/src/routes/maintenance/+page.svelte": 5467232163447861441,
+ "frontend/src/pages/Settings.svelte": 14062925006358678049,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/test_logical_ops.py": 4438104524064299182,
+ "backend/src/api/routes/__tests__/test_clean_release_api.py": 8153144254371183034,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/resource_protector.py": 9147671710440653567,
+ "backend/src/plugins/translate/orchestrator_exec.py": 965301343860940811,
+ "backend/tests/scripts/test_clean_release_cli.py": 14028295526033195944,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_shift.py": 8547819448301023303,
+ "venv/lib/python3.13/site-packages/numpy/_core/multiarray.py": 4484782354376574355,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/command_context.py": 9426036980437931533,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_sql.py": 3901697517087276687,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/__init__.py": 96341051676048910,
+ "venv/bin/pytest": 2593802493707545818,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_core_functionalities.py": 10449747865888948579,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/_version.py": 15336513445621042105,
+ "venv/lib/python3.13/site-packages/pandas/api/__init__.py": 1145864207387918302,
+ "venv/lib/python3.13/site-packages/pandas/api/indexers/__init__.py": 17431573013142626187,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_clip.py": 11111183698178681331,
+ "venv/lib/python3.13/site-packages/urllib3/py.typed": 12220177918227495093,
+ "venv/lib/python3.13/site-packages/pygments/styles/staroffice.py": 11694998942433220413,
+ "backend/src/services/git/_base.py": 18009686862342149948,
+ "venv/lib/python3.13/site-packages/attr/__init__.pyi": 13203080513025719049,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/column.py": 9498044216416177656,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_as_unit.py": 8492383355919959393,
+ "venv/lib/python3.13/site-packages/keyring/backends/chainer.py": 12526770797516553385,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/attributes.py": 5068814626384132900,
+ "venv/lib/python3.13/site-packages/pydantic/generics.py": 15019381413806459410,
+ "frontend/build/_app/immutable/nodes/11.C2Q0x739.js": 15308213278050514327,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_three_greenlets2.py": 11100501798741918610,
+ "venv/lib/python3.13/site-packages/starlette/middleware/trustedhost.py": 8302185291610019926,
+ "venv/lib/python3.13/site-packages/ecdsa/test_curves.py": 6577762025900435885,
+ "venv/lib/python3.13/site-packages/dotenv/ipython.py": 15904966766060247908,
+ "venv/lib/python3.13/site-packages/_pytest/mark/structures.py": 12237146603608917650,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/mixed/foo_fixed.f90": 8079594129222364031,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/test_timestamp.py": 10308799534491190078,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/_typing.py": 17589387690638097975,
+ "venv/lib/python3.13/site-packages/yaml/composer.py": 13619070314468518566,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/test_series_transform.py": 18159263102656491974,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_take.py": 17628004130770326677,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9068/token_validator.py": 2932866595454490527,
+ "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/WHEEL": 2357997949040430835,
+ "frontend/src/lib/api/translate/jobs.js": 9613844538417291513,
+ "venv/lib/python3.13/site-packages/numpy/_core/fromnumeric.pyi": 13945478633722616250,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/fields.pyi": 15420142722808118826,
+ "venv/lib/python3.13/site-packages/pygments/lexers/oberon.py": 15220143799603451830,
+ "frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js": 966219842574639412,
+ "frontend/src/components/DashboardGrid.svelte": 49663074759987369,
+ "frontend/build/_app/immutable/nodes/14.DRir6aHV.js": 16259183276893641425,
+ "backend/src/core/superset_client/_datasets_preview.py": 15457586484984946621,
+ "venv/lib/python3.13/site-packages/anyio/streams/__init__.py": 15130871412783076140,
+ "backend/src/services/maintenance/_dashboard_scanner.py": 1401108008906511280,
+ "backend/src/plugins/translate/events.py": 7105758998894297601,
+ "venv/lib/python3.13/site-packages/urllib3/util/timeout.py": 17922362393077965047,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi": 2777456956260371820,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_concatenate_chunks.py": 9693420220003544490,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/sqlite/pysqlcipher.py": 11225173272050906977,
+ "venv/lib/python3.13/site-packages/fastapi/_compat/model_field.py": 392699021682253569,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcrypto-2e26a48f.so.3": 3658133521245392852,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/unicode_comment.f90": 11326797716215117266,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/replace.py": 1708865864686705833,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/traversals.py": 1188980668212022868,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_categorical_equal.py": 7942323667866280872,
+ "venv/lib/python3.13/site-packages/pygments/lexers/rego.py": 16022844238903541738,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arraysetops.pyi": 1782641795267171928,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_iterator.py": 13869355993837330406,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7592/endpoint.py": 18260428408051728802,
+ "frontend/src/routes/+page.svelte": 5863865830077771796,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/regexopt.py": 16073437303824961930,
+ "frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte": 2392958189014264590,
+ "venv/lib/python3.13/site-packages/websockets/__init__.py": 4916307256304054040,
+ "venv/lib/python3.13/site-packages/sqlalchemy-2.0.45.dist-info/RECORD": 9461427699726982537,
+ "venv/lib/python3.13/site-packages/rsa/parallel.py": 4968566722541778371,
+ "venv/lib/python3.13/site-packages/pygments/lexers/blueprint.py": 6370363226580199085,
+ "frontend/src/lib/components/layout/TopNavbar.svelte": 16154704878262712977,
+ "frontend/build/_app/immutable/nodes/8.xOR7dmBp.js": 6245655214318207283,
+ "backend/src/api/routes/admin.py": 14496518311272057274,
+ "venv/lib/python3.13/site-packages/PIL/ImageSequence.py": 16459886231802763032,
+ "frontend/src/assets/svelte.svg": 13872699371039797074,
+ "venv/lib/python3.13/site-packages/numpy/version.pyi": 5075382895829889457,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/WHEEL": 6514509858522675228,
+ "venv/lib/python3.13/site-packages/authlib/__init__.py": 8957417237987377675,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/data_stmts.f90": 6123192245816905092,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/managers.py": 13547912653290063698,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_constructors.py": 11065058462752831997,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/warnings_and_errors.py": 11172336980866895356,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/transform/test_transform.py": 5674175311567817854,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_masked.py": 5380551301916549925,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/css.py": 11288129826285529457,
+ "venv/lib/python3.13/site-packages/authlib/common/errors.py": 16082974228565515177,
+ "venv/lib/python3.13/site-packages/rsa/util.py": 13423880475585138638,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/typing.py": 17638587764345605306,
+ "venv/lib/python3.13/site-packages/PIL/ImageMode.py": 2361901066832921091,
+ "venv/lib/python3.13/site-packages/git/util.py": 7424113599506269603,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/common/gh19161.f90": 7691871466158049079,
+ "frontend/src/lib/stores/maintenance.svelte.js": 17672315346665850067,
+ "frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte": 17593699210431624897,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/boolean/test_comparison.py": 11333735187162513512,
+ "venv/lib/python3.13/site-packages/attrs/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/api/extensions/__init__.py": 882327406374020760,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/chebyshev.pyi": 5269136485429780038,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/expressions.py": 10684284531040203747,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_groupby.py": 15721254196883995634,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/discovery.py": 12479996594187326798,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/__init__.py": 1856412417337875350,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/array_like.pyi": 1968570015765106620,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-tanh.csv": 6674536825156196036,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_chained_assignment_deprecation.py": 7694137945143129474,
+ "venv/lib/python3.13/site-packages/more_itertools/recipes.pyi": 16788810745659802820,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/signature.py": 3614545297259098566,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/serialization/base.py": 16052592982063844259,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libssl-81ffa89e.so.3": 13913673119166658781,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/__init__.py": 1586148254475575526,
+ "venv/lib/python3.13/site-packages/numpy/lib/_twodim_base_impl.pyi": 15509415708991012734,
+ "venv/lib/python3.13/site-packages/numpy/lib/_version.py": 15294708923334674060,
+ "venv/lib/python3.13/site-packages/authlib/consts.py": 14226604841596736870,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_win_type.py": 18105114803686556748,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_api.py": 6439927798101672423,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_s390_unix.h": 5161826643658505126,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_melt.py": 15663807247682146566,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/__init__.py": 5060190599837877599,
+ "venv/lib/python3.13/site-packages/_pytest/config/__init__.py": 12787579251203510616,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distlib/scripts.py": 8759605303886441976,
+ "venv/lib/python3.13/site-packages/pandas/io/html.py": 2727247063231114153,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/__init__.py": 3969805865048730851,
+ "venv/lib/python3.13/site-packages/PIL/IptcImagePlugin.py": 14329453455296600824,
+ "venv/lib/python3.13/site-packages/numpy/lib/_format_impl.py": 1809069379864985298,
+ "venv/lib/python3.13/site-packages/_pytest/capture.py": 17850967053989495422,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_constructors.py": 979131987837682435,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/sfc64-testset-1.csv": 5708101386018266998,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/url.py": 9692934100602135106,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_backend.py": 1472021608501071055,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/api.py": 13134394673408254097,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ec.pyi": 9835891299056543360,
+ "venv/lib/python3.13/site-packages/numpy/ctypeslib/_ctypeslib.py": 12636954896699095212,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_value_counts.py": 9352540710376306520,
+ "venv/lib/python3.13/site-packages/pandas/_libs/algos.cpython-313-x86_64-linux-gnu.so": 15706331654215762588,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_html.py": 12040484325988635032,
+ "venv/lib/python3.13/site-packages/pandas/tests/generic/test_generic.py": 1297407268239966429,
+ "venv/lib/python3.13/site-packages/uvicorn/supervisors/watchfilesreload.py": 13062440477475586751,
+ "frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js": 6358696236009732713,
+ "frontend/src/lib/components/translate/TranslationPreview.svelte": 9514416214545061268,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/twisted.py": 16059862619165885730,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_cli.py": 3173259257428855556,
+ "frontend/build/_app/immutable/chunks/DkSc7bnI.js": 16633882293462436801,
+ "frontend/build/_app/immutable/chunks/CHelQZPK.js": 13538277300205681632,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/__init__.py": 3673322722277252961,
+ "backend/src/core/superset_client/_dashboards_list.py": 18014687561732553425,
+ "backend/src/services/validation_service.py": 4040391162969506763,
+ "backend/src/plugins/translate/preview_token_estimator.py": 254295902082954386,
+ "frontend/src/lib/api/translate/dictionaries.js": 13928848549982189213,
+ "frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js": 7841254655898186872,
+ "frontend/build/_app/immutable/chunks/D2LDFDH5.js": 1513005501777757570,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_extended_precision.py": 4201820494689784136,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/markup.py": 5413800947725916538,
+ "backend/src/services/health_service.py": 7707107506464919176,
+ "venv/lib/python3.13/site-packages/fastapi/params.py": 14263655860695381481,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/funcfortranname.f": 9330535808093475892,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/rsa_key.py": 7092106298733667895,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_matlib.py": 14395481530627870882,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/core": 10616484054735611337,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/native/encoder.py": 120921270972591880,
+ "venv/lib/python3.13/site-packages/python_multipart/exceptions.py": 5971058243218049183,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/arithmetic.pyi": 467927803068643024,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/modeline.py": 6194365452131561478,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/merge.py": 300205528811693975,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft202012/vocabularies/applicator": 6616723520993329538,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/link.py": 7172346414535657925,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/routines/subrout.pyf": 4660465266594480405,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_list_accessor.py": 8613662386779664039,
+ "venv/lib/python3.13/site-packages/attrs/filters.py": 6844006230924162452,
+ "venv/lib/python3.13/site-packages/authlib/integrations/base_client/framework_integration.py": 3935346152156572025,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/conftest.py": 4124267277224879990,
+ "venv/lib/python3.13/site-packages/pydantic_core/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/test_nat.py": 7400568652984772972,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/baked.py": 6911138208603240867,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mutable.py": 9323088483998280629,
+ "venv/lib/python3.13/site-packages/yaml/dumper.py": 11376022992370902766,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/__init__.py": 14522970260621605208,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_version.pyi": 3636944488233043883,
+ "venv/lib/python3.13/site-packages/urllib3/util/util.py": 12490259045660543460,
+ "venv/lib/python3.13/site-packages/authlib/oidc/discovery/well_known.py": 8259335680633926377,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/numeric/test_astype.py": 4854809596041987380,
+ "venv/lib/python3.13/site-packages/uvicorn/lifespan/off.py": 16254524872582859561,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/ciphers.pyi": 18143251582901996072,
+ "venv/lib/python3.13/site-packages/jeepney/io/asyncio.py": 13239992245695516007,
+ "venv/lib/python3.13/site-packages/numpy/_core/_add_newdocs_scalars.pyi": 1826323011169529229,
+ "venv/lib/python3.13/site-packages/numpy/_core/_exceptions.py": 5570375156851166818,
+ "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/__init__.py": 4390908730288159455,
+ "venv/lib/python3.13/site-packages/numpy/version.py": 1497063540123613501,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/numeric.py": 14451517189908259173,
+ "venv/lib/python3.13/site-packages/authlib/jose/errors.py": 15231759002942436632,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/masked_reductions.py": 633644255158859565,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_bin_groupby.py": 14831211659124136806,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraypad.py": 4907193085512342162,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_case_when.py": 4133174129660834805,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_data_list.py": 1131520422778420758,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/twofactor/__init__.py": 18069619555394133945,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/schema.py": 8358664670620586363,
+ "venv/lib/python3.13/site-packages/PIL/_imagingmorph.cpython-313-x86_64-linux-gnu.so": 11171810899664471137,
+ "venv/lib/python3.13/site-packages/numpy/core/defchararray.py": 11371045148957547088,
+ "venv/lib/python3.13/site-packages/httpcore/_synchronization.py": 10997080307461682786,
+ "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/RECORD": 3649834117451110628,
+ "venv/lib/python3.13/site-packages/pygments/styles/onedark.py": 17580335614588531275,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/blocks.py": 6448406236246476333,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_openedge_builtins.py": 4979988747924637739,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.cpython-313-x86_64-linux-gnu.so": 6726636942028566415,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/__init__.py": 13682931764896414722,
+ "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_resolution.py": 9651416588266430520,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/merge/test_join.py": 4213933887062089605,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_datetime.py": 4179112383995346046,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/test_runtime.py": 12534621594420844770,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_datetimelike.py": 5317270578347271174,
+ "venv/lib/python3.13/site-packages/pygments/lexers/procfile.py": 3860651022061090738,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_arrow_compat.py": 12986187285988432338,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/pg8000.py": 6580512354643849828,
+ "venv/lib/python3.13/site-packages/numpy/random/_pcg64.cpython-313-x86_64-linux-gnu.so": 5759445712745875888,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7518/__init__.py": 8558541715982163200,
+ "venv/lib/python3.13/site-packages/ecdsa-0.19.1.dist-info/METADATA": 13428590545328703138,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_astype.py": 4975959187621745360,
+ "venv/lib/python3.13/site-packages/numpy/core/function_base.py": 12696640832638144604,
+ "venv/lib/python3.13/site-packages/pandas/tests/config/__init__.py": 15130871412783076140,
+ "backend/src/plugins/translate/preview_prompt_helpers.py": 14303328860208074708,
+ "backend/git_repos/remote/test-repo.git/objects/ee/59553241ef084b83d3351ba4c33caf2ed9a840": 11587106407031972706,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_copy.py": 11335108864615756235,
+ "venv/lib/python3.13/site-packages/pygments/lexers/matlab.py": 1880915927722177654,
+ "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/RECORD": 16342326945648353387,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_update.py": 12293424926920594944,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/scalars.pyi": 17683675356659300769,
+ "venv/lib/python3.13/site-packages/jeepney/io/__init__.py": 2568357146184259175,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/generator_pcg64_np121.pkl.gz": 4708588000144933291,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iat.py": 3570464615146398178,
+ "venv/lib/python3.13/site-packages/pygments/lexers/mosel.py": 1877592344012288438,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_googlesql_builtins.py": 12251289884604745945,
+ "backend/src/services/dataset_review/__init__.py": 3695054675894579272,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/misc.py": 17461379236189029253,
+ "backend/git_repos/remote/test-repo.git/objects/3e/05ec6ef6504483c4bc7d00f0d0272c38ec661f": 11182016264585388842,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/literal.py": 5641382379370828704,
+ "venv/lib/python3.13/site-packages/charset_normalizer/cd.py": 8687667152597941021,
+ "venv/lib/python3.13/site-packages/passlib/handlers/mysql.py": 11165762635383041460,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_interp_fillna.py": 5530041283991655415,
+ "backend/alembic/versions/a7b1c2d3e4f5_add_provider_id_to_validation_policies.py": 7446022200459040057,
+ "venv/lib/python3.13/site-packages/pytest_asyncio-1.3.0.dist-info/REQUESTED": 15130871412783076140,
+ "backend/src/api/routes/environments.py": 6175447476823722833,
+ "venv/lib/python3.13/site-packages/certifi/__main__.py": 13417658012431779061,
+ "venv/lib/python3.13/site-packages/pandas/io/sas/sasreader.py": 12766780210114366112,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_longtable.tpl": 12723621983797415444,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_logical_ops.py": 16166386974005224415,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_period.py": 6047041810867211174,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/indexing.py": 18009437216172136227,
+ "frontend/src/routes/dashboards/+page.svelte": 5522148689707175338,
+ "frontend/vite.config.js": 3769019895915732131,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_diff.py": 2216748778018882333,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_value_attrspec.py": 7741590618654448240,
+ "venv/lib/python3.13/site-packages/ecdsa/test_jacobi.py": 1249543655136186433,
+ "venv/lib/python3.13/site-packages/anyio/to_thread.py": 12767326212338028587,
+ "venv/lib/python3.13/site-packages/_pytest/assertion/rewrite.py": 2425990712758915831,
+ "venv/lib/python3.13/site-packages/httpcore-1.0.9.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_inspect.py": 10573558345297891848,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/list/test_list.py": 4538625980063375611,
+ "venv/lib/python3.13/site-packages/py.py": 16248211404003181569,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_cat.py": 15988884721768567895,
+ "venv/lib/python3.13/site-packages/dateutil/tz/tz.py": 5258008267965780817,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_lua_builtins.py": 12653747099659257203,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/themes.py": 6451091097727599550,
+ "frontend/src/lib/api/translate/__tests__/test-target-schema.test.js": 16872327388398551554,
+ "venv/lib/python3.13/site-packages/pip/__main__.py": 574438877257676911,
+ "frontend/src/lib/auth/__tests__/permissions.test.js": 14871965971459735540,
+ "venv/lib/python3.13/site-packages/ecdsa/rfc6979.py": 11564966030899162026,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/http/h11_impl.py": 1419719055394402145,
+ "venv/lib/python3.13/site-packages/websockets/legacy/protocol.py": 762692033188392424,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/indexing/test_take.py": 1216902953519121176,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/constructors/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/graphql.py": 2307854666015224677,
+ "backend/src/plugins/translate/_lang_detect.py": 2125979777533490081,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_indexing.py": 14717641281147152159,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/clsregistry.py": 1589692649837935355,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/isocintrin/isoCtests.f90": 6208802899442270399,
+ "venv/lib/python3.13/site-packages/click/core.py": 16793133181718891193,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_round.py": 1299086932398824299,
+ "venv/lib/python3.13/site-packages/ecdsa/ecdsa.py": 9770689913380927623,
+ "venv/lib/python3.13/site-packages/pyasn1/type/namedval.py": 8273171503516887681,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimelike_/test_nat.py": 18428782698385974380,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/common/test_common_basic.py": 1945891789924713537,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_orc.py": 1248059610437937895,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/fixtures/sql.py": 13315906751371033170,
+ "venv/lib/python3.13/site-packages/dotenv/parser.py": 17651523026132242005,
+ "venv/lib/python3.13/site-packages/itsdangerous/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/base.py": 10514193453447954780,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/constants.pyi": 4415188581374004936,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/bulk_persistence.py": 2307818727114646866,
+ "frontend/src/services/gitService.js": 15727247604802461729,
+ "backend/src/plugins/translate/__tests__/test_dictionary_import.py": 17094877730934121606,
+ "backend/src/api/routes/git/_gitea_routes.py": 3966408809424419232,
+ "backend/src/plugins/translate/preview_prompt_builder.py": 15837150631111510351,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_value_counts.py": 12340872812120847127,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_indexerrors.py": 4434868847540549873,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/unix.py": 13808187640638677050,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/lock.py": 14782882714168174465,
+ "venv/lib/python3.13/site-packages/_pytest/__init__.py": 3769333500910148571,
+ "venv/lib/python3.13/site-packages/pygments/styles/colorful.py": 15708848112363953394,
+ "frontend/playwright-report/data/cc5452f8d8c308a176676866ee06628a569362aa.zip": 18382826147717299104,
+ "venv/lib/python3.13/site-packages/pandas/plotting/__init__.py": 13230487326686617492,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nbit_base_example.pyi": 8571452382806614924,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/base.py": 14734745827490220667,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/period/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/gitdb/stream.py": 3035738824550231197,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/descriptor_props.py": 7044852927393650707,
+ "frontend/src/components/git/GitManager.svelte": 12767660311913624739,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_sparse.py": 14343335524508450058,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ldap.py": 17455983150181177257,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/generic.py": 17755579497690180620,
+ "frontend/src/lib/components/health/PolicyForm.svelte": 17995152707951193436,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.cpython-313-x86_64-linux-gnu.so": 12473903676666680134,
+ "venv/lib/python3.13/site-packages/pydantic/experimental/pipeline.py": 9493054841465227788,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/toml.py": 2225382735669153136,
+ "venv/lib/python3.13/site-packages/passlib/crypto/scrypt/_builtin.py": 74545289993348593,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_apache.py": 12515001998770565375,
+ "venv/lib/python3.13/site-packages/starlette/websockets.py": 13834731343216764204,
+ "venv/lib/python3.13/site-packages/pandas/core/roperator.py": 2587829042468916489,
+ "venv/lib/python3.13/site-packages/cffi/model.py": 13544803366359102016,
+ "venv/lib/python3.13/site-packages/pandas/tests/config/test_config.py": 4630144191929135452,
+ "venv/lib/python3.13/site-packages/gitdb/__init__.py": 15381521749253695923,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_partial_indexing.py": 4132091154215910029,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_spinners.py": 15873416546130487469,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_get_numeric_data.py": 11747933921770969706,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/result.py": 12262298207886620908,
+ "venv/lib/python3.13/site-packages/keyring/backends/macOS/__init__.py": 1010937986753403630,
+ "venv/lib/python3.13/site-packages/git/repo/base.py": 13975465345838683533,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/http/httptools_impl.py": 10367325397209016951,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh17859.f": 13562390882286135024,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/test_methods.py": 12694335778731418517,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_between_time.py": 14266333058913745751,
+ "venv/lib/python3.13/site-packages/pygments/formatters/latex.py": 7514533384468139434,
+ "frontend/src/components/tools/DebugTool.svelte": 8095371084479333656,
+ "venv/lib/python3.13/site-packages/pyasn1/__init__.py": 8089201217593738032,
+ "venv/lib/python3.13/site-packages/pygments/lexers/perl.py": 17014528337020572681,
+ "backend/src/api/routes/profile.py": 8666418382456481533,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/__init__.py": 16211693040174992594,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/plugin.py": 16042078006552521613,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/httpcore/_sync/socks_proxy.py": 4418971149260853240,
+ "venv/lib/python3.13/site-packages/pygments/lexers/jvm.py": 897669925284011089,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_indexing.py": 16291207621268530224,
+ "frontend/build/_app/immutable/chunks/rzyp_Wbp.js": 10559672264716197308,
+ "backend/src/scripts/clean_release_cli.py": 777127038463156812,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/automap.py": 4672057253309608464,
+ "backend/git_repos/remote/test-repo.git/objects/4f/4e0958b3a42eff67a2b8cfd084d05c43e54716": 6040513978194442637,
+ "venv/lib/python3.13/site-packages/annotated_doc/__init__.py": 6834198874252778425,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/cast/test_promote.py": 16601872688404846307,
+ "frontend/src/lib/stores/health.js": 3621667160018048028,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_period.py": 15671388508498441412,
+ "backend/src/plugins/translate/orchestrator.py": 6762154654706349158,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_tzconversion.py": 7205566353454584259,
+ "venv/lib/python3.13/site-packages/git/objects/__init__.py": 2110615482320355676,
+ "backend/src/plugins/backup.py": 1465877198420371496,
+ "venv/lib/python3.13/site-packages/pyasn1-0.6.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/PIL/ImageQt.py": 6607270889359138659,
+ "backend/src/services/clean_release/report_builder.py": 14118825155100404762,
+ "backend/src/services/dataset_review/repositories/session_repository.py": 4897386456198762089,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7516/__init__.py": 11121941644106061453,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/table.py": 16856253349556498073,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_constructors.py": 9815164146739254076,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libcom_err-2abe824b.so.2.1": 12870528025628871295,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/status.py": 2214590120238144582,
+ "frontend/src/lib/stores/environmentContext.js": 9960741825828562980,
+ "venv/lib/python3.13/site-packages/pydantic/version.py": 3699343596421001359,
+ "venv/lib/python3.13/site-packages/pycparser/yacctab.py": 18018314512916353707,
+ "frontend/src/lib/components/MaintenanceSettingsPanel.svelte": 8672462648876875400,
+ "venv/lib/python3.13/site-packages/numpy/lib/_nanfunctions_impl.py": 11621577915097515056,
+ "venv/lib/python3.13/site-packages/pandas/util/_exceptions.py": 14426860079366867683,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_apps.py": 10454136535890937237,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_align.py": 6050248183327934780,
+ "venv/lib/python3.13/site-packages/pandas/tseries/frequencies.py": 2262381949755250516,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/configuration.py": 1608697090566485893,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/einsumfunc.pyi": 200771351328522379,
+ "frontend/src/lib/components/health/HealthMatrix.svelte": 18141816318382901531,
+ "venv/lib/python3.13/site-packages/_pytest/terminal.py": 885450969703476729,
+ "venv/lib/python3.13/site-packages/numpy/core/__init__.py": 10397294636564169377,
+ "venv/lib/python3.13/site-packages/greenlet/TGreenlet.hpp": 6993553444981671786,
+ "venv/lib/python3.13/site-packages/pygments/lexers/css.py": 517586374264113606,
+ "venv/lib/python3.13/site-packages/charset_normalizer/legacy.py": 1706599349563920562,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7519/jwt.py": 9642615960197748105,
+ "venv/lib/python3.13/site-packages/charset_normalizer/md.py": 2029760700380476138,
+ "venv/lib/python3.13/site-packages/_pytest/nodes.py": 515939386237558331,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/styles/__init__.py": 9482393721453335937,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh23533.f": 12558972205518833024,
+ "venv/lib/python3.13/site-packages/numpy/_core/memmap.py": 4093510602708416858,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.pyi": 13110894861187422750,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/test_rolling_skew_kurt.py": 15225601437354712351,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_sample.py": 16877779557071324115,
+ "venv/lib/python3.13/site-packages/gitdb/db/pack.py": 13460574575424209609,
+ "venv/lib/python3.13/site-packages/numpy/_core/strings.py": 3623885046208831106,
+ "venv/lib/python3.13/site-packages/numpy/linalg/_umath_linalg.pyi": 7674087576653964854,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/period.cpython-313-x86_64-linux-gnu.so": 14468234464367691795,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py": 1246582552828542841,
+ "venv/lib/python3.13/site-packages/greenlet/tests/__init__.py": 1181423074160870921,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh25211.f": 1486878017876900890,
+ "venv/lib/python3.13/site-packages/git/diff.py": 6691274015605451565,
+ "venv/lib/python3.13/site-packages/authlib-1.6.6.dist-info/licenses/LICENSE": 13322127602069971876,
+ "backend/src/models/maintenance.py": 7247376865754977732,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/info.py": 215303194287834907,
+ "backend/:memory:test_main": 8120796031785944903,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/cer/__init__.py": 15728752901274520502,
+ "venv/lib/python3.13/site-packages/httpx/_api.py": 6697370469329778523,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/_libs/ops_dispatch.cpython-313-x86_64-linux-gnu.so": 5284769758475394095,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/metrics_cpp_avx2.cpython-313-x86_64-linux-gnu.so": 2991745295485163924,
+ "venv/lib/python3.13/site-packages/pip/_vendor/distro/distro.py": 12494639376332486204,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_formats.py": 2601044064677727807,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/provider.py": 16463243654123731993,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/direct_url_helpers.py": 6075890513530296650,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_indexing.py": 8943385096811168079,
+ "venv/lib/python3.13/site-packages/_pytest/stepwise.py": 3527630676691417317,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_timedeltas.py": 1175883320586860493,
+ "venv/lib/python3.13/site-packages/anyio-4.12.0.dist-info/METADATA": 3643456577199395707,
+ "venv/lib/python3.13/site-packages/pandas/io/json/_json.py": 1393095374713367445,
+ "backend/src/plugins/git/__init__.py": 2144831474780401625,
+ "venv/lib/python3.13/site-packages/attr/_version_info.pyi": 7141309436445210354,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/xml/conftest.py": 17514079438846557943,
+ "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/integration.py": 3085827906490477329,
+ "venv/lib/python3.13/site-packages/passlib/handlers/oracle.py": 12959175637015399815,
+ "frontend/build/_app/immutable/nodes/4.CcWcsp3l.js": 17995715878844731568,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/conftest.py": 25473177671450048,
+ "venv/lib/python3.13/site-packages/pygments/lexers/bare.py": 18266858932333619451,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/npy_os.h": 7883047506449405400,
+ "venv/lib/python3.13/site-packages/bcrypt/__init__.py": 11415155211917181362,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/claims.py": 2035724920423374302,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/lib_version.pyi": 18093228021414910594,
+ "venv/lib/python3.13/site-packages/pygments/lexers/qvt.py": 1895735583818227972,
+ "venv/lib/python3.13/site-packages/pandas/_libs/byteswap.cpython-313-x86_64-linux-gnu.so": 17856848989827220388,
+ "venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py": 10408538054406276433,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet.cpp": 3281107194043468270,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/file_proxy.py": 17695135735211897444,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/hook-numpy.py": 5221550291012182443,
+ "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp.py": 16797760903996739079,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/tile.py": 17137524194129840833,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/_utils.py": 11574890848475750509,
+ "venv/lib/python3.13/site-packages/pydantic/v1/tools.py": 1995883197897112278,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_concat.py": 16549010224568175202,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/offsets.pyi": 13173581775000480811,
+ "venv/lib/python3.13/site-packages/pandas/tests/window/moments/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_array_from_pyobj.py": 9596224861290975079,
+ "venv/lib/python3.13/site-packages/sqlalchemy/engine/interfaces.py": 4890958419958257958,
+ "venv/lib/python3.13/site-packages/pygments/styles/algol.py": 3040373291664740876,
+ "frontend/src/lib/Counter.svelte": 3616557554460116236,
+ "frontend/build/_app/immutable/chunks/Cs7qTEqk.js": 15866070137921022262,
+ "venv/lib/python3.13/site-packages/cffi/recompiler.py": 17809252277700094304,
+ "backend/src/services/git/_status.py": 13381104725964137243,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/declarative_asn1.pyi": 16934250836612138541,
+ "venv/lib/python3.13/site-packages/rsa/asn1.py": 3861968161559322784,
+ "venv/lib/python3.13/site-packages/pandas/util/_decorators.py": 14780166101442507665,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Prefix.py": 4672871351134074735,
+ "venv/lib/python3.13/site-packages/pandas/_libs/tslibs/ccalendar.pyi": 15789956857032062129,
+ "venv/lib/python3.13/site-packages/attr/validators.pyi": 15579625896285277321,
+ "venv/lib/python3.13/site-packages/pydantic_settings-2.13.0.dist-info/METADATA": 3448868793744358515,
+ "venv/lib/python3.13/site-packages/urllib3/exceptions.py": 9687187566231423953,
+ "frontend/build/_app/immutable/chunks/DSxK3NUv.js": 8639953729041066468,
+ "venv/lib/python3.13/site-packages/pandas/core/indexes/frozen.py": 1419685664276640120,
+ "backend/src/api/routes/mappings.py": 2467003850993962558,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/filters/__init__.py": 2992007913496948339,
+ "venv/lib/python3.13/site-packages/pydantic/tools.py": 8931184638883701008,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate.py": 16723865897349422996,
+ "venv/lib/python3.13/site-packages/urllib3/connectionpool.py": 7493427857878469165,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/warnings_and_errors.pyi": 9019577563960071498,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_join.py": 11910166566689889389,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_insert.py": 15536994417338770457,
+ "venv/lib/python3.13/site-packages/fastapi/staticfiles.py": 4094330072433302614,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_csound_builtins.py": 14530739818491398298,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/crackfortran/gh2848.f90": 5799106109999071412,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/mysql/json.py": 14755215397454910426,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_windows_renderer.py": 1076842273781909680,
+ "venv/lib/python3.13/site-packages/pygments/styles/_mapping.py": 11752660241391232497,
+ "venv/lib/python3.13/site-packages/jsonschema/validators.py": 3832874295500213309,
+ "venv/lib/python3.13/site-packages/pluggy/_hooks.py": 6941854999025808196,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_astype.py": 16700461036658228009,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/einsumfunc.py": 9944042006439149561,
+ "venv/lib/python3.13/site-packages/pandas/compat/numpy/function.py": 18405870240333383757,
+ "venv/lib/python3.13/site-packages/PIL/FtexImagePlugin.py": 8196606399875185931,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/invalid.py": 10186546927135277579,
+ "venv/lib/python3.13/site-packages/numpy/polynomial/polyutils.py": 12355826783958402233,
+ "venv/lib/python3.13/site-packages/websockets-15.0.1.dist-info/METADATA": 14608873187265321271,
+ "venv/lib/python3.13/site-packages/_pytest/raises.py": 8188402179490363767,
+ "venv/lib/python3.13/site-packages/numpy/random/_philox.cpython-313-x86_64-linux-gnu.so": 9916143171057774705,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth1/__init__.py": 13749066369790839334,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/uuid/test_uuid.py": 13955678427426850807,
+ "venv/lib/python3.13/site-packages/pip-25.1.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/keyring/credentials.py": 14515496037842724455,
+ "venv/lib/python3.13/site-packages/cffi/_cffi_include.h": 13094899814611950155,
+ "venv/lib/python3.13/site-packages/pandas/io/sas/sas7bdat.py": 17851617851457266799,
+ "venv/lib/python3.13/site-packages/pygments/lexers/erlang.py": 11757064262773184741,
+ "frontend/src/lib/components/StartMaintenanceForm.svelte": 11114259982483681666,
+ "venv/lib/python3.13/site-packages/numpy/core/getlimits.py": 14257687540182552408,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_arithmetic.py": 15071337112968886738,
+ "frontend/src/routes/storage/repos/+page.svelte": 2273592022555593164,
+ "backend/src/core/superset_client/_user_projection.py": 15240732089847883635,
+ "venv/lib/python3.13/site-packages/pandas/core/flags.py": 4690844374637430013,
+ "build.sh": 5842665574427443016,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_value_counts.py": 13270420637302622174,
+ "frontend/src/lib/api.js": 7712788935523484149,
+ "venv/lib/python3.13/site-packages/PIL/PalmImagePlugin.py": 13008868719182630239,
+ "venv/lib/python3.13/site-packages/pip/_vendor/tomli/__init__.py": 12906995259233516197,
+ "venv/lib/python3.13/site-packages/httpx/_transports/wsgi.py": 11981127094916412794,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nlargest.py": 14518132768753249360,
+ "venv/lib/python3.13/site-packages/pandas/core/array_algos/datetimelike_accumulations.py": 14719894187829729175,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/pyopenssl.py": 11839715589709210412,
+ "venv/lib/python3.13/site-packages/pip/_vendor/idna/idnadata.py": 1169745920682458213,
+ "venv/lib/python3.13/site-packages/charset_normalizer/models.py": 9917300217816275821,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/common.py": 16314033415206173235,
+ "backend/src/services/clean_release/repositories/publication_repository.py": 1097065694003039928,
+ "venv/lib/python3.13/site-packages/typing_inspection/typing_objects.py": 16856718240972376883,
+ "venv/lib/python3.13/site-packages/PIL/_webp.pyi": 18222325750818585549,
+ "venv/lib/python3.13/site-packages/iniconfig/_version.py": 8497474654470220170,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_index.py": 10837492069089787028,
+ "venv/lib/python3.13/site-packages/annotated_doc-0.0.4.dist-info/RECORD": 7320381591791379627,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_arm64_masm.obj": 11967637259540485652,
+ "venv/lib/python3.13/site-packages/numpy/lib/_function_base_impl.pyi": 2628035888703031029,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_nested_sequence.py": 7827259347937485408,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/string/fixed_string.f90": 8654788371538544793,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_umath_complex.py": 11732242536199439023,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_common.py": 3559416690270529904,
+ "frontend/src/routes/+layout.ts": 8392799000856778740,
+ "venv/lib/python3.13/site-packages/sqlalchemy/pool/impl.py": 4687705587963980337,
+ "venv/lib/python3.13/site-packages/starlette/middleware/authentication.py": 15211131264936212938,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex.tpl": 8820045022551446255,
+ "venv/lib/python3.13/site-packages/jeepney/tests/test_bindgen.py": 8637878018232418583,
+ "venv/lib/python3.13/site-packages/numpy/f2py/rules.py": 9322914583460630877,
+ "backend/git_repos/remote/test-repo.git/objects/17/66251d8cb2693136e09ea3def3e776559cb722": 1137762010493457272,
+ "venv/lib/python3.13/site-packages/sqlalchemy/event/legacy.py": 13465911776953636949,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_x32_unix.h": 9165722966153119887,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi": 10784666243744187693,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_numba.py": 18148155441554555618,
+ "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/WHEEL": 2357997949040430835,
+ "frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte": 12995972702842177800,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/__version__.py": 14138134075118474134,
+ "venv/lib/python3.13/site-packages/_pytest/_py/error.py": 2257336434271433543,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_tz_localize.py": 4937713043686953098,
+ "frontend/src/components/git/BranchSelector.svelte": 2850678079887313044,
+ "venv/lib/python3.13/site-packages/git/objects/tree.py": 10239027037919781330,
+ "frontend/playwright-report/trace/snapshot.html": 11716473056415565262,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_interpolate.py": 6154072863387383113,
+ "venv/lib/python3.13/site-packages/pandas/tests/api/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic/error_wrappers.py": 11273827025986230629,
+ "venv/lib/python3.13/site-packages/greenlet-3.3.0.dist-info/licenses/LICENSE": 4123064337800029995,
+ "venv/lib/python3.13/site-packages/numpy/_array_api_info.pyi": 13283968924732680159,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/install/__init__.py": 10456333337205488584,
+ "venv/lib/python3.13/site-packages/ecdsa/keys.py": 10281170640484982154,
+ "venv/lib/python3.13/site-packages/pygments-2.19.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/default_comparator.py": 47118577003622736,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/licenses/numpy/_core/src/umath/svml/LICENSE": 9584102918819171104,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/schemas/draft201909/vocabularies/format": 12697928260201325593,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/random/libdivide.h": 5314232500579481313,
+ "venv/lib/python3.13/site-packages/pillow-12.1.1.dist-info/zip-safe": 15240312484046875203,
+ "frontend/e2e/tests/live-project-check.e2e.js": 4657915737640702974,
+ "venv/lib/python3.13/site-packages/passlib-1.7.4.dist-info/zip-safe": 15240312484046875203,
+ "venv/lib/python3.13/site-packages/pandas/core/nanops.py": 18291534943985310005,
+ "venv/lib/python3.13/site-packages/PIL/QoiImagePlugin.py": 17663704273100331654,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_nlargest.py": 1423106021399469694,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/scoping.py": 18223258186431020473,
+ "venv/lib/python3.13/site-packages/numpy/_core/function_base.pyi": 8343632640078378312,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_constructors.py": 13890224577680389718,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/ma.pyi": 6467636381637286867,
+ "frontend/src/lib/api/datasetReview.js": 11780670121350173465,
+ "frontend/build/_app/immutable/nodes/2.CzvoUmY2.js": 5644623930213002650,
+ "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/RECORD": 7363618870628306370,
+ "venv/lib/python3.13/site-packages/pip/_vendor/cachecontrol/_cmd.py": 14954780419054588164,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_function.py": 644452398244782315,
+ "venv/lib/python3.13/site-packages/click/parser.py": 13988544851350599869,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_extint128.py": 11074657869101074458,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/orderinglist.py": 10162099108656794338,
+ "venv/lib/python3.13/site-packages/urllib3/http2/probe.py": 4069929463671970243,
+ "backend/src/services/clean_release/candidate_service.py": 12771065368619689666,
+ "venv/lib/python3.13/site-packages/starlette/schemas.py": 697416731579555195,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/methods/test_rank.py": 5398520257852104723,
+ "frontend/svelte.config.js": 8473636210766821560,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/test_support.pyi": 3893434234020223151,
+ "venv/lib/python3.13/site-packages/numpy/ma/testutils.pyi": 3899348061346041413,
+ "venv/lib/python3.13/site-packages/pandas/_testing/_io.py": 14264259716673715185,
+ "frontend/tailwind.config.js": 13139381085024634801,
+ "backend/conftest.py": 16521922883434363388,
+ "venv/lib/python3.13/site-packages/pandas/_testing/compat.py": 10172779814048259850,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/refresh_token.py": 17927903035152872556,
+ "venv/lib/python3.13/site-packages/numpy/core/fromnumeric.py": 2136433423902202138,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/urls.py": 8698341051522816167,
+ "venv/lib/python3.13/site-packages/annotated_types/test_cases.py": 5123395674810472016,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/test_old_base.py": 191359377446257900,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/philox-testset-2.csv": 7063857529719738394,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/base.py": 6348888156686452825,
+ "venv/lib/python3.13/site-packages/packaging/__init__.py": 5479277484104486860,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_both.f90": 13943066317159236257,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timedelta/test_formats.py": 18080627205081311773,
+ "venv/lib/python3.13/site-packages/PIL/ImImagePlugin.py": 15452956038794399492,
+ "venv/lib/python3.13/site-packages/pygments/__init__.py": 14493583771211110135,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_update.py": 9098258267671647783,
+ "venv/lib/python3.13/site-packages/authlib/integrations/sqla_oauth2/__init__.py": 12911374670789466961,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/hashes.py": 17310331665429541812,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_integer/foo77.f": 12000068001851270396,
+ "venv/lib/python3.13/site-packages/passlib/crypto/_blowfish/__init__.py": 3521833849634327520,
+ "venv/lib/python3.13/site-packages/jaraco_functools-4.4.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/_pytest/reports.py": 13930709338396699351,
+ "backend/src/core/logger.py": 11870126816969695787,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/char.pyi": 13143560686049627445,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame.py": 16757570551941104401,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_shares_memory.py": 2911029123657970431,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/indexing/test_delitem.py": 14336697139511118920,
+ "venv/lib/python3.13/site-packages/git/refs/__init__.py": 16246686106073400519,
+ "venv/lib/python3.13/site-packages/PIL/ImageEnhance.py": 3218405223202808764,
+ "backend/src/api/routes/dashboards/_action_routes.py": 10305887713397749487,
+ "venv/lib/python3.13/site-packages/click/_textwrap.py": 14586282603215052310,
+ "frontend/build/_app/immutable/nodes/17.CGMpcAVz.js": 10821941490965601406,
+ "backend/src/plugins/mapper.py": 12075913231649127940,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/tool_support.py": 4926732415520779988,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/instrumentation.py": 14882045449667214075,
+ "venv/lib/python3.13/site-packages/cryptography/utils.py": 18088508841978595788,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py": 17873236864291624476,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_strings.py": 17398806130402098912,
+ "frontend/src/lib/stores/__tests__/mocks/state.js": 10691107564567912815,
+ "venv/lib/python3.13/site-packages/fastapi/dependencies/utils.py": 7687214523082385505,
+ "venv/lib/python3.13/site-packages/pygments/styles/paraiso_dark.py": 3976779833379189837,
+ "frontend/playwright-report/trace/sw.bundle.js": 10879347794748701702,
+ "venv/lib/python3.13/site-packages/keyring/backends/null.py": 12740996416911604870,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc7517/asymmetric_key.py": 14948661854506285135,
+ "venv/lib/python3.13/site-packages/jose/backends/native.py": 50023158618000658,
+ "venv/lib/python3.13/site-packages/apscheduler/triggers/combining.py": 1264860868414723829,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_protocols.py": 5019018645804313814,
+ "venv/lib/python3.13/site-packages/PIL/PdfParser.py": 13710342183037972042,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_iloc.py": 7586049606891014270,
+ "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/meson.build": 8784756284679859367,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_pytables_missing.py": 12154582133989896069,
+ "venv/lib/python3.13/site-packages/websockets/__main__.py": 11948055520555854616,
+ "venv/lib/python3.13/site-packages/websockets/speedups.cpython-313-x86_64-linux-gnu.so": 10941658763526595989,
+ "venv/lib/python3.13/site-packages/pandas/io/clipboard/__init__.py": 3656451154829206939,
+ "venv/lib/python3.13/site-packages/jaraco/classes/meta.py": 15930255620248873425,
+ "venv/lib/python3.13/site-packages/passlib/ext/django/models.py": 12386223748379294996,
+ "venv/lib/python3.13/site-packages/git/db.py": 6680123567509774609,
+ "venv/lib/python3.13/site-packages/jsonschema/_legacy_keywords.py": 16481666133229715822,
+ "venv/lib/python3.13/site-packages/git/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/styles/default.py": 13992125975366109635,
+ "venv/lib/python3.13/site-packages/pygments/lexers/gcodelexer.py": 13712494327007684318,
+ "frontend/build/_app/immutable/chunks/DrLlT35Y.js": 13372359563307010137,
+ "backend/src/models/dataset_review_pkg/_semantic_models.py": 6371476812115351221,
+ "venv/lib/python3.13/site-packages/pluggy/_callers.py": 1042673447718196223,
+ "backend/alembic/env.py": 7020161137665650592,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/test_ipython_compat.py": 12632271159842988561,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/test_threading.py": 6656552495241857519,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_api.py": 10514120091521589282,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_tolist.py": 8343058000369672317,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/resource_protector.py": 3563910821279222695,
+ "venv/lib/python3.13/site-packages/pygments/lexers/testing.py": 17148598391210353576,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/concat.py": 12151675567885981464,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/req_dependency_group.py": 10505346210114745037,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_day.py": 6371851881186970754,
+ "venv/lib/python3.13/site-packages/pygments/lexers/openscad.py": 13045825115225232396,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_seed_sequence.py": 7687465232954593311,
+ "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/RECORD": 9964194961227523130,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein.py": 17993169044119596860,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/utils.py": 11401792151107207834,
+ "venv/lib/python3.13/site-packages/urllib3/filepost.py": 3814725067598042920,
+ "venv/lib/python3.13/site-packages/pandas/core/indexers/objects.py": 409599993084996593,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/conftest.py": 15090201792072045503,
+ "venv/lib/python3.13/site-packages/keyring/backends/fail.py": 5792496235026678021,
+ "venv/lib/python3.13/site-packages/pydantic/v1/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/pyproject.py": 12684373765476932108,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/wait.py": 6196757964348666082,
+ "venv/lib/python3.13/site-packages/ecdsa/_version.py": 17707102226558781833,
+ "venv/lib/python3.13/site-packages/pip/_internal/commands/wheel.py": 16397273591245583356,
+ "venv/lib/python3.13/site-packages/click/exceptions.py": 9734955259447933725,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/timedeltas/test_cumulative.py": 8178093067175155877,
+ "venv/lib/python3.13/site-packages/multipart/decoders.py": 11346752866822986212,
+ "venv/lib/python3.13/site-packages/git/objects/submodule/__init__.py": 12958523219496107878,
+ "backend/src/plugins/translate/preview_review.py": 5584592578627646560,
+ "venv/lib/python3.13/site-packages/PIL/ImageDraw.py": 12919304671639673744,
+ "venv/lib/python3.13/site-packages/urllib3/util/connection.py": 15511685694589961094,
+ "venv/lib/python3.13/site-packages/psycopg2_binary-2.9.11.dist-info/licenses/LICENSE": 5757922580822401219,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/_elffile.py": 5728213398707817049,
+ "backend/git_repos/remote/test-repo.git/objects/22/c0ea49cea7e5138fb91b25b1bc0e101ae6e017": 17630871400599334193,
+ "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/WHEEL": 14550174241288068152,
+ "frontend/src/routes/datasets/StatsBar.svelte": 4241697609925045735,
+ "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/RECORD": 16874983218652404911,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_parsing.py": 2228959015420278458,
+ "venv/lib/python3.13/site-packages/pygments/styles/tango.py": 12389250878249075539,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/excel.py": 797619981868084011,
+ "venv/lib/python3.13/site-packages/websockets/sync/messages.py": 15699091325918681038,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_quarter.py": 11099677280196239755,
+ "backend/src/api/routes/maintenance/_schemas.py": 16377052636841886346,
+ "venv/lib/python3.13/site-packages/pandas/_libs/properties.pyi": 9268470215750269699,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7523/auth.py": 13542332344403032059,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_parquet.py": 11050150015772440923,
+ "venv/lib/python3.13/site-packages/itsdangerous-2.2.0.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/PIL/ImageText.py": 15322496455608242001,
+ "venv/lib/python3.13/site-packages/git/refs/reference.py": 2038789918710608481,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py": 16386268386376675175,
+ "venv/lib/python3.13/site-packages/smmap/test/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/dns.py": 17149871769553794654,
+ "frontend/playwright-report/data/36557793d7fda8ef412a553a55389600452506f9.png": 8526067803082440263,
+ "backend/src/models/dataset_review_pkg/_finding_models.py": 13502025287982574359,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_handlers_argon2.py": 11345706437113628133,
+ "venv/lib/python3.13/site-packages/anyio/_core/_fileio.py": 4507100568401692983,
+ "venv/lib/python3.13/site-packages/gitpython-3.1.46.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/__init__.py": 5732822354953774657,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7636/__init__.py": 913610541217778747,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/object/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic/v1/env_settings.py": 6194387033830177219,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_time_series.py": 5205199092955498507,
+ "venv/lib/python3.13/site-packages/python_dotenv-1.2.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pydantic/datetime_parse.py": 196119761382305574,
+ "venv/lib/python3.13/site-packages/pandas/_libs/_cyutility.cpython-313-x86_64-linux-gnu.so": 3372660143512868174,
+ "venv/lib/python3.13/site-packages/pandas/core/dtypes/common.py": 10996276696597806957,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_transpose.py": 17983160984979323393,
+ "venv/lib/python3.13/site-packages/PIL/ImageStat.py": 18442709639217312689,
+ "venv/lib/python3.13/site-packages/pandas/tests/libs/test_lib.py": 6721066015604956469,
+ "venv/lib/python3.13/site-packages/pygments/lexers/compiled.py": 8215290039991205531,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_oauth2/authorization_server.py": 17967809814827547139,
+ "venv/lib/python3.13/site-packages/numpy/_core/include/numpy/_numpyconfig.h": 18150055639397773687,
+ "venv/lib/python3.13/site-packages/pandas/core/base.py": 10262717073058743378,
+ "venv/lib/python3.13/site-packages/annotated_types/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/filters/__init__.py": 835924536855006596,
+ "venv/lib/python3.13/site-packages/dotenv/__main__.py": 16883579879172186355,
+ "venv/lib/python3.13/site-packages/httpx/_utils.py": 4836536051177895209,
+ "venv/lib/python3.13/site-packages/httpx-0.28.1.dist-info/RECORD": 17594742868855466393,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/nested_sequence.pyi": 11245460325970663922,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/_initialize.pyi": 6616985736007157309,
+ "venv/lib/python3.13/site-packages/pip/_internal/self_outdated_check.py": 991029278889407558,
+ "venv/lib/python3.13/site-packages/numpy/lib/_arraypad_impl.pyi": 2186875333484796630,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_ops.py": 16346030307660048773,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/__init__.py": 8705044848308260480,
+ "venv/lib/python3.13/site-packages/fastapi/datastructures.py": 727178955746650271,
+ "venv/lib/python3.13/site-packages/pydantic_settings/sources/providers/dotenv.py": 5872848911499749500,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/aead.pyi": 13061638961405460334,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/integer/test_indexing.py": 5063545640498065297,
+ "venv/lib/python3.13/site-packages/iniconfig-2.3.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pygments/modeline.py": 6194365452131561478,
+ "venv/lib/python3.13/site-packages/pygments/lexers/kuin.py": 2818054539831699366,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/date/__init__.py": 16789767433439616593,
+ "venv/lib/python3.13/site-packages/pandas/_libs/writers.pyi": 10494773026133244183,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/hooks.py": 8580161128344266243,
+ "venv/lib/python3.13/site-packages/pygments/lexers/webidl.py": 8097260111959278117,
+ "venv/lib/python3.13/site-packages/passlib/handlers/sha2_crypt.py": 8171587560325812664,
+ "venv/lib/python3.13/site-packages/pygments/sphinxext.py": 2768161754523156130,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_conversion.py": 9159276697339089788,
+ "venv/lib/python3.13/site-packages/attrs-25.4.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/base.py": 17992335652981439676,
+ "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/RECORD": 7266315886702289726,
+ "venv/lib/python3.13/site-packages/websockets/sync/router.py": 10335595955948355382,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_simd_module.py": 7122050193390298178,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/callback/gh26681.f90": 1515497186927052106,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/test_find_replace.py": 262184394614748386,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/config.py": 10707678943298497676,
+ "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/RECORD": 9803861100978586236,
+ "venv/lib/python3.13/site-packages/PIL/XbmImagePlugin.py": 12256750478268246137,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/assumed_shape/precision.f90": 5518911932373565642,
+ "venv/lib/python3.13/site-packages/git/objects/submodule/util.py": 8621897576747443758,
+ "venv/lib/python3.13/site-packages/pygments/lexers/csound.py": 2175454840368374515,
+ "frontend/src/routes/datasets/review/review-workspace-helpers.js": 8577563379877694502,
+ "venv/lib/python3.13/site-packages/jeepney/bus_messages.py": 5871341372541525842,
+ "backend/src/core/utils/async_network.py": 7880952036357722891,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_filters.py": 17271344092069736999,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/__init__.py": 18140261896107421679,
+ "venv/lib/python3.13/site-packages/authlib/integrations/starlette_client/__init__.py": 9083396324667433335,
+ "venv/lib/python3.13/site-packages/httpcore/_models.py": 2501866419898326733,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_deprecations.py": 16124509063246256847,
+ "backend/src/services/__tests__/test_llm_provider.py": 14345242680566878510,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/test_union_categoricals.py": 6843679254735807,
+ "venv/lib/python3.13/site-packages/pygments/lexers/rebol.py": 10460732731157940232,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_at_time.py": 15352346149584081864,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/abstract_interface/gh18403_mod.f90": 6219951399575860362,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_warnings.py": 3154249157134620649,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_concat.py": 10207975532842927134,
+ "frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js": 16164320505605430516,
+ "backend/tests/test_translate_jobs.py": 14073962595360719355,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_assert_series_equal.py": 1223890028205011021,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_generator.py": 14156412320760444199,
+ "venv/lib/python3.13/site-packages/uvicorn/loops/__init__.py": 15130871412783076140,
+ "backend/src/plugins/translate/_run_source.py": 11569137727611732019,
+ "frontend/src/routes/settings/notifications/+page.svelte": 11507547877108528071,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/decl_class.py": 6328411894571735935,
+ "venv/lib/python3.13/site-packages/starlette/middleware/__init__.py": 9524277524025372856,
+ "venv/lib/python3.13/site-packages/pandas/_libs/json.pyi": 10989301892466547548,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/interval/test_interval.py": 18040371224712437126,
+ "venv/lib/python3.13/site-packages/requests-2.32.5.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/anyio/streams/tls.py": 4191898645554875562,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/repr.py": 839417422880281122,
+ "venv/lib/python3.13/site-packages/python_dateutil-2.9.0.post0.dist-info/WHEEL": 5990830714395966792,
+ "venv/lib/python3.13/site-packages/greenlet/greenlet_msvc_compat.hpp": 12504008513945919250,
+ "venv/lib/python3.13/site-packages/passlib/crypto/digest.py": 15890463288512025688,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/path_registry.py": 8410829659513707067,
+ "venv/lib/python3.13/site-packages/pygments/lexers/automation.py": 8021926838024836904,
+ "backend/tests/core/test_defensive_guards.py": 12897956916491464449,
+ "venv/lib/python3.13/site-packages/pygments/lexers/bibtex.py": 14652372822443154388,
+ "venv/lib/python3.13/site-packages/yaml/error.py": 5626374410579058436,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_openpyxl.py": 9542840527483618681,
+ "venv/lib/python3.13/site-packages/numpy/lib/format.pyi": 11752225430594536662,
+ "venv/lib/python3.13/site-packages/pandas/tests/reductions/__init__.py": 16150188643076000414,
+ "models": 14346352665111990852,
+ "venv/lib/python3.13/site-packages/starlette/testclient.py": 16088848330558215194,
+ "venv/lib/python3.13/site-packages/numpy/linalg/__init__.pyi": 18409133021422984774,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/sparse/test_combine_concat.py": 3201068805128232483,
+ "venv/lib/python3.13/site-packages/jsonschema/tests/test_utils.py": 8668650648802195016,
+ "venv/lib/python3.13/site-packages/pycparser/ply/lex.py": 3393278208465358140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/stata.py": 7249891970174867363,
+ "venv/lib/python3.13/site-packages/pandas/tests/interchange/test_spec_conformance.py": 16448324304809345527,
+ "backend/src/services/git/__init__.py": 18353922816391181902,
+ "venv/lib/python3.13/site-packages/numpy/_core/defchararray.py": 15550230459945996915,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_flags.py": 411845322592830527,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/oracle/oracledb.py": 7158791242292470472,
+ "backend/src/services/reports/type_profiles.py": 9186322444310801411,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/test_spss.py": 4865360315909532603,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_parameter.py": 15173522343126004527,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_datetime.py": 13781712980921881470,
+ "backend/src/plugins/translate/__tests__/test_orthogonal_fixes.py": 12993935170413202399,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_utils_md4.py": 15270721044910698449,
+ "venv/lib/python3.13/site-packages/referencing-0.37.0.dist-info/licenses/COPYING": 14459782230785388765,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_mem_overlap.py": 4202716587079637350,
+ "venv/lib/python3.13/site-packages/anyio/streams/stapled.py": 9733127303038397237,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test__datasource.py": 1747755531265478106,
+ "venv/lib/python3.13/site-packages/numpy/matrixlib/tests/test_multiarray.py": 3592197154340095431,
+ "venv/lib/python3.13/site-packages/pandas/tests/scalar/timestamp/methods/test_to_pydatetime.py": 1129954411080617001,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_categorical.py": 8844412630511751140,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/decimal/__init__.py": 4761936067832638585,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/wheel.py": 10473287225032326206,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/api.py": 14632030170441237968,
+ "backend/src/plugins/search.py": 13705421801923369220,
+ "venv/lib/python3.13/site-packages/_pytest/_code/__init__.py": 6211607282116942091,
+ "venv/lib/python3.13/site-packages/pandas/_libs/sparse.cpython-313-x86_64-linux-gnu.so": 2051484129454294720,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_loadtxt.py": 17562784940619942447,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/categorical/test_category.py": 3944898528119364040,
+ "venv/lib/python3.13/site-packages/httpx/_transports/mock.py": 13564349939188292363,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/tree.py": 4991806303236874829,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_cl_builtins.py": 16540712925368297957,
+ "venv/lib/python3.13/site-packages/PIL/GribStubImagePlugin.py": 14954946414134984896,
+ "venv/lib/python3.13/site-packages/greenlet/slp_platformselect.h": 10428201768098464386,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/DamerauLevenshtein_py.py": 1933257612725836484,
+ "venv/lib/python3.13/site-packages/pandas/_libs/__init__.py": 17117112389651696580,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/einsumfunc.pyi": 8902765738896588686,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_filter.py": 2388681477981649268,
+ "venv/lib/python3.13/site-packages/pandas/tests/apply/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ruby.py": 6898093948224302592,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/integration.py": 12670848015915724967,
+ "backend/alembic/README": 17625003422504608299,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_tsql_builtins.py": 829193091321611630,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/methods/test_to_timestamp.py": 17572983799929378095,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/__init__.py": 13584649922093198724,
+ "venv/lib/python3.13/site-packages/pygments/lexers/minecraft.py": 10133579583270214110,
+ "venv/lib/python3.13/site-packages/pydantic_settings/version.py": 17263591404988984480,
+ "frontend/src/lib/api/translate/corrections.js": 3619404083693055292,
+ "venv/lib/python3.13/site-packages/tzlocal/win32.py": 1949985224569608978,
+ "venv/lib/python3.13/site-packages/bcrypt-4.0.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/passlib/utils/handlers.py": 10182859005870689026,
+ "venv/lib/python3.13/site-packages/cryptography/x509/name.py": 15338066443257445241,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/lazy_wheel.py": 12936988990566680659,
+ "venv/lib/python3.13/site-packages/numpy/lib/mixins.pyi": 15597536290223628777,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/pcg64dxsm-testset-1.csv": 9129730764673472086,
+ "frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte": 8577281635452165836,
+ "venv/lib/python3.13/site-packages/pandas/io/json/_normalize.py": 15938855324762935595,
+ "backend/src/plugins/git_plugin.py": 5910855495971245586,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_round.py": 14996007456708990295,
+ "venv/lib/python3.13/site-packages/pip/_internal/req/constructors.py": 17485271035479378662,
+ "venv/lib/python3.13/site-packages/pandas/core/strings/accessor.py": 14021462534679430426,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/pkg_resources.py": 14271077832999370068,
+ "venv/lib/python3.13/site-packages/pandas/tests/dtypes/test_missing.py": 1963705411068820866,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/string_/test_string_arrow.py": 10008395772220468318,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_mips_unix.h": 17373389962405490482,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_datetime64.py": 16272266806084058743,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/test_block_internals.py": 17935662848672401507,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/auto.py": 10488908050307887802,
+ "backend/src/api/routes/storage.py": 3921659652525719249,
+ "venv/lib/python3.13/site-packages/anyio/streams/buffered.py": 8916188172110578587,
+ "backend/src/core/superset_client/_dashboards_filters.py": 17625905985676889586,
+ "venv/lib/python3.13/site-packages/anyio/_core/_synchronization.py": 7050001375718876608,
+ "venv/lib/python3.13/site-packages/rapidfuzz/process_cpp_impl.cpython-313-x86_64-linux-gnu.so": 11767771662042404251,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/parameters.py": 247312908510013930,
+ "backend/src/services/dataset_review/orchestrator.py": 15350066045014880242,
+ "venv/lib/python3.13/site-packages/apscheduler/schedulers/blocking.py": 3483388533957772681,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/errors.py": 12935154705443176852,
+ "venv/lib/python3.13/site-packages/numpy/lib/__init__.pyi": 1537495515469182226,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_pct_change.py": 10313980265441433173,
+ "venv/lib/python3.13/site-packages/ecdsa/test_rw_lock.py": 1572802971060634697,
+ "venv/lib/python3.13/site-packages/uvicorn/__main__.py": 6086938803696646644,
+ "venv/lib/python3.13/site-packages/gitdb/test/test_example.py": 3039934065817753241,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc9101/registration.py": 14639972512303032712,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/virtualenv.py": 14416705841810221305,
+ "frontend/public/vite.svg": 13568221685541582385,
+ "frontend/src/components/tasks/LogFilterBar.svelte": 1342324464094667837,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_character/foo77.f": 4046503346951676582,
+ "frontend/build/_app/immutable/nodes/15.Dfk1Lz29.js": 1026201780612355026,
+ "backend/src/services/clean_release/__tests__/test_stages.py": 15550789367780507193,
+ "backend/alembic/versions/aa1b2c3d4e5f_drop_deprecated_translate_columns.py": 15433357059529111004,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/period/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pydantic-2.12.5.dist-info/licenses/LICENSE": 1641332741515411734,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/ber/encoder.py": 8912119133548489544,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_halfyear.py": 587199217232946404,
+ "backend/src/services/__tests__/test_health_service.py": 16470443406586362974,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/models.py": 16636119441941357281,
+ "venv/lib/python3.13/site-packages/pygments/lexers/smalltalk.py": 6113431347120223592,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/util.py": 2176177435997659667,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/test_randomstate.py": 11205714006000849926,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/boolean.py": 8821671562937866269,
+ "venv/lib/python3.13/site-packages/pygments/unistring.py": 18037463865539157041,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_ujson.py": 12184194085993665945,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/assertions.py": 5556667947376168765,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/missing.py": 9493665944764255854,
+ "frontend/playwright.config.js": 802586619504012017,
+ "frontend/build/_app/immutable/chunks/CC_MCBkD.js": 11709343780956289454,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/emoji.py": 9166774203918731896,
+ "venv/lib/python3.13/site-packages/_pytest/setupplan.py": 7496801885995567141,
+ "venv/lib/python3.13/site-packages/pandas/_libs/arrays.cpython-313-x86_64-linux-gnu.so": 8634234308863090562,
+ "venv/lib/python3.13/site-packages/pandas/tests/tslibs/test_array_to_datetime.py": 3467480435568672840,
+ "venv/lib/python3.13/site-packages/numpy/linalg/tests/test_deprecations.py": 14624516389510242394,
+ "venv/lib/python3.13/site-packages/greenlet/tests/test_generator_nested.py": 12822240347707346718,
+ "dist/docker/frontend.0.1.1.tar.xz": 14558310887004056908,
+ "venv/lib/python3.13/site-packages/dotenv/cli.py": 7952654621986067973,
+ "venv/lib/python3.13/site-packages/ecdsa/_compat.py": 13034064768731879065,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/holiday/test_calendar.py": 12313641252472031631,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/util.py": 10640907133050862176,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/interval/test_indexing.py": 14552860427542050771,
+ "venv/lib/python3.13/site-packages/yaml/emitter.py": 6036657460416912844,
+ "frontend/src/lib/stores/__tests__/assistantChat.test.js": 11108218971449015168,
+ "frontend/src/routes/settings/FeaturesSettings.svelte": 14192374301379217586,
+ "venv/lib/python3.13/site-packages/pydantic/functional_validators.py": 5835339743072048940,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/data/umath-validation-set-arctanh.csv": 8620268345075425735,
+ "venv/lib/python3.13/site-packages/pycparser/lextab.py": 16045770806700381661,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe_protocol.py": 12857147443873820285,
+ "venv/lib/python3.13/site-packages/rapidfuzz/fuzz.py": 1094797446508902066,
+ "venv/lib/python3.13/site-packages/numpy/lib/_type_check_impl.pyi": 2667658052734929089,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/jose/drafts/_jwe_enc_cryptodome.py": 15753279711312689193,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/test_datetimelike.py": 10294379314868108649,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/numpy/_pyinstaller/tests/__init__.py": 13331622784664204066,
+ "venv/lib/python3.13/site-packages/anyio/abc/__init__.py": 11428476337116642278,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/suite/test_types.py": 4083297168618981717,
+ "venv/lib/python3.13/site-packages/pydantic/deprecated/config.py": 12280996227531856230,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc8628/__init__.py": 6532094538918910232,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/nditer.pyi": 2351219156711800159,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_cython.py": 2933400021016349431,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_vbscript_builtins.py": 9882134558469491349,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications/_core.py": 14812112544772987164,
+ "venv/lib/python3.13/site-packages/pygments/lexers/grammar_notation.py": 9009644754106884095,
+ "frontend/src/routes/datasets/review/ReviewWorkspaceLeftSidebar.svelte": 9009994851177005358,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/multiarray.py": 3224049574922696945,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/test_index_as_string.py": 13421551616136437100,
+ "venv/lib/python3.13/site-packages/numpy/random/tests/data/__init__.py": 15130871412783076140,
+ "backend/src/services/dataset_review/clarification_pkg/_helpers.py": 16131390986170241319,
+ "frontend/e2e/tests/enterprise-clean-setup.e2e.js": 6434855878266981931,
+ "venv/lib/python3.13/site-packages/authlib/integrations/django_oauth1/authorization_server.py": 6858244712625056421,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/fft.pyi": 14454280827038327842,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/_internal_utils.py": 4091305333167213279,
+ "venv/lib/python3.13/site-packages/secretstorage/item.py": 15486045386471912693,
+ "venv/lib/python3.13/site-packages/pip/_vendor/packaging/licenses/__init__.py": 2635182244050911910,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_join.py": 17874591841487372992,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/_psycopg_common.py": 4111797647365870137,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_loc.py": 17839380711970027363,
+ "venv/lib/python3.13/site-packages/starlette/formparsers.py": 9019779181100355515,
+ "venv/lib/python3.13/site-packages/websockets/auth.py": 499195617702591757,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/client.py": 7237359250450222680,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/inout.f90": 1521999519583206538,
+ "venv/lib/python3.13/site-packages/yaml/tokens.py": 2279161238859232338,
+ "venv/lib/python3.13/site-packages/pandas/api/executors/__init__.py": 16954693181142010028,
+ "venv/lib/python3.13/site-packages/dateutil/easter.py": 14631233890122048084,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_skiprows.py": 8764515842253490735,
+ "venv/lib/python3.13/site-packages/fastapi-0.127.1.dist-info/REQUESTED": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/authlib/oauth1/rfc5849/authorization_server.py": 4427151727224472650,
+ "venv/lib/python3.13/site-packages/pip/_internal/vcs/mercurial.py": 335201628064585213,
+ "venv/lib/python3.13/site-packages/cffi/_imp_emulation.py": 17246725564704952212,
+ "venv/lib/python3.13/site-packages/pip/_internal/metadata/base.py": 13444129650880426353,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/client_credentials.py": 256154392957334831,
+ "venv/lib/python3.13/site-packages/ecdsa/test_der.py": 7117444285097824495,
+ "venv/lib/python3.13/site-packages/pip/_vendor/msgpack/exceptions.py": 11303331612406662162,
+ "venv/lib/python3.13/site-packages/numpy/ma/core.py": 338350463523585845,
+ "venv/lib/python3.13/site-packages/numpy/_core/_simd.pyi": 13553578040186939249,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_deprecations.py": 6015734648984591027,
+ "venv/lib/python3.13/site-packages/pandas/core/interchange/dataframe.py": 16525846817331842080,
+ "venv/lib/python3.13/site-packages/pandas/core/arrays/__init__.py": 10460719978124302175,
+ "venv/lib/python3.13/site-packages/pandas/tests/plotting/frame/test_frame_subplots.py": 4596089143375088346,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/pytables/test_store.py": 1500300322083708794,
+ "venv/lib/python3.13/site-packages/click/__init__.py": 9261629899056870564,
+ "venv/lib/python3.13/site-packages/pandas/_libs/reshape.cpython-313-x86_64-linux-gnu.so": 10639750501333255943,
+ "venv/lib/python3.13/site-packages/sqlalchemy/testing/provision.py": 17812733620485633975,
+ "venv/lib/python3.13/site-packages/pyasn1/type/namedtype.py": 1859990775875190116,
+ "venv/lib/python3.13/site-packages/git/objects/tag.py": 7954808535585493300,
+ "venv/lib/python3.13/site-packages/dateutil/relativedelta.py": 5903095963079475484,
+ "frontend/src/lib/stores/activity.js": 10599836924066718828,
+ "frontend/build/_app/immutable/chunks/0SSHfn-s.js": 1512028033550082311,
+ "frontend/src/lib/components/reports/ReportsList.svelte": 17367781544989044334,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/auth.py": 8455258275234626534,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_sort_index.py": 13517883160584591966,
+ "backend/src/core/migration_engine.py": 4215834818829537236,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/_py_collections.py": 16825222625411635946,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_infer_objects.py": 16868563755487479303,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/status_codes.py": 9143625681947330756,
+ "venv/lib/python3.13/site-packages/passlib/handlers/md5_crypt.py": 7669328623914474137,
+ "venv/lib/python3.13/site-packages/certifi/__init__.py": 9045580998764948967,
+ "venv/lib/python3.13/site-packages/jeepney/io/tests/test_asyncio.py": 2820168745710754136,
+ "venv/lib/python3.13/site-packages/bcrypt/__about__.py": 11196369962175692786,
+ "venv/lib/python3.13/site-packages/packaging-26.0.dist-info/licenses/LICENSE": 4274653168153720331,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_context_deprecated.py": 7876919198015151018,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/mypy/names.py": 705261158040926128,
+ "venv/lib/python3.13/site-packages/jsonschema_specifications-2025.9.1.dist-info/WHEEL": 2357997949040430835,
+ "venv/lib/python3.13/site-packages/pandas/core/strings/object_array.py": 17631047188839635539,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/interfaces.py": 5371646629319169153,
+ "venv/lib/python3.13/site-packages/git/objects/fun.py": 15014209679156260865,
+ "venv/lib/python3.13/site-packages/pygments/lexers/tcl.py": 10343667975436015855,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/test_nditer.py": 8341339612899904236,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/tools.py": 6437315459200419827,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/build/metadata_editable.py": 12494407279914732338,
+ "venv/lib/python3.13/site-packages/pygments/lexers/trafficscript.py": 776604244051744646,
+ "backend/src/core/migration/risk_assessor.py": 4161499861941446814,
+ "venv/lib/python3.13/site-packages/pip/_internal/operations/prepare.py": 13514839972066861359,
+ "frontend/src/routes/settings/LoggingSettings.svelte": 5172094246995863925,
+ "backend/src/core/task_manager/__init__.py": 15991802770215124472,
+ "venv/lib/python3.13/site-packages/numpy/random/lib/libnpyrandom.a": 1802449692091040396,
+ "venv/lib/python3.13/site-packages/annotated_doc/main.py": 3384049281532298500,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/ranges/test_setops.py": 17350958906336246626,
+ "venv/lib/python3.13/site-packages/uvicorn/protocols/__init__.py": 15130871412783076140,
+ "backend/src/api/routes/validation.py": 13836068409484617547,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/methods/test_to_frame.py": 2169381747938271444,
+ "backend/src/plugins/translate/__init__.py": 12400577052797809611,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/processors.cpython-313-x86_64-linux-gnu.so": 18139875206371157315,
+ "venv/lib/python3.13/site-packages/numpy/rec/__init__.pyi": 1782063765067823837,
+ "venv/lib/python3.13/site-packages/dateutil/utils.py": 7067026915090881998,
+ "venv/lib/python3.13/site-packages/pandas/tests/arithmetic/test_object.py": 9215781825358309147,
+ "backend/src/services/reports/__tests__/test_report_service.py": 2262310201779987221,
+ "venv/lib/python3.13/site-packages/numpy/fft/tests/test_helper.py": 5362180645056413158,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_combine_first.py": 3100691245280812910,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/categorical/test_take.py": 3281943380342853080,
+ "backend/src/services/git/_remote_providers.py": 7497094824437995253,
+ "venv/lib/python3.13/site-packages/apscheduler/executors/debug.py": 14072221218785494847,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/incfile.f90": 4348588746493647387,
+ "venv/lib/python3.13/site-packages/git/exc.py": 14278238357119816365,
+ "venv/lib/python3.13/site-packages/pip/_internal/network/download.py": 5256731341219268693,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_dataclasses.py": 15256193972947054890,
+ "venv/lib/python3.13/site-packages/rsa-4.9.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/python_multipart-0.0.21.dist-info/WHEEL": 7454950858448014158,
+ "venv/lib/python3.13/site-packages/pandas/tests/copy_view/index/test_periodindex.py": 13430003945574795792,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/_py_util.py": 12836989066113400538,
+ "venv/lib/python3.13/site-packages/pandas/tests/tools/test_to_datetime.py": 3499461736474530062,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/requests.py": 1102963893193914979,
+ "venv/lib/python3.13/site-packages/greenlet/__init__.py": 3447613556981242475,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_ticks.py": 11649965080303468085,
+ "venv/lib/python3.13/site-packages/cryptography-46.0.3.dist-info/RECORD": 12555714734722889695,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Postfix.pyi": 2700568594438441246,
+ "venv/lib/python3.13/site-packages/pandas/tests/reshape/concat/test_series.py": 17126297747681689408,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/json/test_json_table_schema_ext_dtype.py": 13021437050542691118,
+ "venv/lib/python3.13/site-packages/starlette-0.50.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/sqlalchemy/ext/asyncio/result.py": 8306497889916212025,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_nunique.py": 8450574751331186943,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/formats/style/test_bar.py": 7791068963246005463,
+ "venv/lib/python3.13/site-packages/jaraco/functools/__init__.pyi": 2872039192528394677,
+ "venv/lib/python3.13/site-packages/pip/_internal/utils/_log.py": 13011536737418204268,
+ "venv/lib/python3.13/site-packages/numpy/lib/_index_tricks_impl.py": 13574106461973044500,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/accessors/test_str_accessor.py": 4066094997616994612,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/_collections.py": 7772437080414835462,
+ "venv/lib/python3.13/site-packages/pygments/lexers/vyper.py": 6477559246065994199,
+ "venv/lib/python3.13/site-packages/pip/_internal/models/search_scope.py": 9282393652860589543,
+ "venv/lib/python3.13/site-packages/websockets/version.py": 5853118844880112885,
+ "venv/lib/python3.13/site-packages/httpcore/_backends/trio.py": 8394426709857317737,
+ "venv/lib/python3.13/site-packages/pygments/lexers/arrow.py": 6699009974224818979,
+ "frontend/playwright-report/trace/playwright-logo.svg": 4728037962520658573,
+ "venv/lib/python3.13/site-packages/jaraco_context-6.0.2.dist-info/WHEEL": 16097436423493754389,
+ "venv/lib/python3.13/site-packages/pip/_vendor/requests/cookies.py": 4997226307650350876,
+ "venv/lib/python3.13/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE": 14316979437290727897,
+ "venv/lib/python3.13/site-packages/rpds_py-0.30.0.dist-info/licenses/LICENSE": 14524289631770661180,
+ "venv/lib/python3.13/site-packages/annotated_types-0.7.0.dist-info/RECORD": 11904769847385571600,
+ "venv/lib/python3.13/site-packages/pydantic/dataclasses.py": 12384956801113860889,
+ "venv/lib/python3.13/site-packages/numpy/f2py/_backends/_distutils.py": 1948707545068786,
+ "venv/lib/python3.13/site-packages/pip/_vendor/resolvelib/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/util.pyx": 649821942746469002,
+ "frontend/e2e/tests/translation.e2e.js": 9863246540495731784,
+ "venv/lib/python3.13/site-packages/authlib/jose/rfc8037/okp_key.py": 10312614562914096039,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/methods/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/compat.py": 16148553252010089561,
+ "backend/src/scripts/__init__.py": 5400372851656282343,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_describe.py": 362374422228593281,
+ "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/WHEEL": 8600534672961461758,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_utils.py": 15197339054699289627,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_ufunc.pyi": 6286629088867436848,
+ "venv/lib/python3.13/site-packages/sqlalchemy/util/__init__.py": 15821192733097665649,
+ "venv/lib/python3.13/site-packages/pygments/styles/rrt.py": 9490973359165080360,
+ "venv/lib/python3.13/site-packages/pygments/lexers/kusto.py": 16285533608924436308,
+ "venv/lib/python3.13/site-packages/secretstorage/defines.py": 9590959702075554048,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/test_numpy.py": 4073641912755651877,
+ "venv/lib/python3.13/site-packages/pandas/_testing/_warnings.py": 5640964566228306285,
+ "venv/lib/python3.13/site-packages/urllib3/contrib/emscripten/__init__.py": 3619091571279924576,
+ "venv/lib/python3.13/site-packages/pandas/_libs/index.pyi": 17679349633640606985,
+ "venv/lib/python3.13/site-packages/greenlet/platform/switch_sparc_sun_gcc.h": 2915128971664712180,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/datetimes/test_arithmetic.py": 4858019700859362660,
+ "backend/src/models/dataset_review_pkg/_session_models.py": 9902104970008253748,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/frequencies/test_frequencies.py": 14039315221824123200,
+ "backend/src/services/dataset_review/event_logger.py": 8944052747593678117,
+ "backend/git_repos/remote/test-repo.git/objects/d8/3fe0db1279ef07c4c4f3de4156a629373b4057": 7507193819578792576,
+ "venv/lib/python3.13/site-packages/numpy/lib/tests/test_arraysetops.py": 10588903945244480732,
+ "venv/lib/python3.13/site-packages/httpcore/_async/interfaces.py": 18250473733460571816,
+ "venv/lib/python3.13/site-packages/pip/_vendor/urllib3/util/timeout.py": 1807228452024740476,
+ "venv/lib/python3.13/site-packages/numpy/f2py/func2subr.pyi": 16573082220135508510,
+ "venv/lib/python3.13/site-packages/urllib3/response.py": 1987354357306756790,
+ "frontend/build/favicon.png": 16740551781088792605,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/test_scalar.py": 2434773821902319678,
+ "venv/lib/python3.13/site-packages/greenlet/tests/fail_switch_two_greenlets.py": 11156275429806391390,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/fail/flatiter.pyi": 6885824496927786205,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/base_class/test_constructors.py": 9767900500541600486,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/parser/test_upcast.py": 6496794053681247105,
+ "venv/lib/python3.13/site-packages/httpcore/__init__.py": 5897259569277532401,
+ "frontend/src/routes/admin/settings/llm/+page.svelte": 17653948269643098768,
+ "backend/src/services/dataset_review/semantic_resolver.py": 11369306880421964134,
+ "venv/lib/python3.13/site-packages/greenlet/tests/_test_extension.cpython-313-x86_64-linux-gnu.so": 1211491156495529145,
+ "venv/lib/python3.13/site-packages/authlib/integrations/flask_client/__init__.py": 9997757256282720103,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/__init__.py": 6534110674636458866,
+ "venv/lib/python3.13/site-packages/_pytest/assertion/__init__.py": 16392348866405910618,
+ "venv/lib/python3.13/site-packages/pandas/tests/groupby/aggregate/test_other.py": 783701524491896337,
+ "venv/lib/python3.13/site-packages/numpy/lib/_iotools.py": 10522826373041592861,
+ "venv/lib/python3.13/site-packages/click-8.3.1.dist-info/INSTALLER": 17282701611721059870,
+ "docker/backend.entrypoint.sh": 1034669340368151691,
+ "venv/lib/python3.13/site-packages/pydantic/json.py": 4109352930301629308,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/test_routines.py": 4860173574365060471,
+ "venv/lib/python3.13/site-packages/pandas/core/ops/dispatch.py": 7041711677358147534,
+ "venv/lib/python3.13/site-packages/rapidfuzz/__init__.pyi": 13131938031654453415,
+ "venv/lib/python3.13/site-packages/pandas/tests/extension/base/dim2.py": 5767600151459095125,
+ "venv/lib/python3.13/site-packages/pandas/tests/util/test_deprecate_kwarg.py": 10417724544218303733,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/pass/ma.py": 15912582628112164509,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/numerictypes.pyi": 15443101937711720707,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/linalg.pyi": 269481015135399748,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexing/multiindex/test_setitem.py": 2059440410065814114,
+ "venv/lib/python3.13/site-packages/httpx/_transports/base.py": 6498990531443644896,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/x509.pyi": 17458894097215345719,
+ "venv/lib/python3.13/site-packages/pandas/tests/tseries/offsets/test_business_hour.py": 13754646634123368797,
+ "venv/lib/python3.13/site-packages/pandas/io/formats/templates/latex_table.tpl": 8706980975714184465,
+ "venv/lib/python3.13/site-packages/secretstorage-3.5.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pyasn1/codec/native/__init__.py": 15728752901274520502,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/test_array.py": 16867692337986161626,
+ "venv/lib/python3.13/site-packages/sqlalchemy/orm/exc.py": 3242780937124999391,
+ "venv/lib/python3.13/site-packages/pip/_vendor/truststore/_macos.py": 7028037591427052891,
+ "venv/lib/python3.13/site-packages/pip/_vendor/pygments/token.py": 6987328478153445584,
+ "venv/lib/python3.13/site-packages/passlib/handlers/digests.py": 18158237109145814857,
+ "venv/lib/python3.13/site-packages/pycparser/ply/ctokens.py": 1599952198962458730,
+ "venv/lib/python3.13/site-packages/pygments/styles/__init__.py": 18383248976818885498,
+ "venv/lib/python3.13/site-packages/pygments/lexers/lean.py": 14518351619544450286,
+ "venv/lib/python3.13/site-packages/pygments/lexers/soong.py": 10273453675034306814,
+ "venv/lib/python3.13/site-packages/pandas/tests/test_downstream.py": 5635510753354256507,
+ "venv/lib/python3.13/site-packages/gitdb-4.0.12.dist-info/AUTHORS": 10073225185964928425,
+ "venv/lib/python3.13/site-packages/numpy/_core/cversions.py": 9724467539503410469,
+ "venv/lib/python3.13/site-packages/numpy-2.4.2.dist-info/WHEEL": 5838667082726674838,
+ "venv/lib/python3.13/site-packages/pandas/core/groupby/generic.py": 4857114071347950833,
+ "venv/lib/python3.13/site-packages/ecdsa/test_eddsa.py": 1785854649532849946,
+ "venv/lib/python3.13/site-packages/pygments/lexers/ml.py": 7510453371068494792,
+ "frontend/build/_app/immutable/nodes/3.C1LP-xCa.js": 9807460888503131276,
+ "venv/lib/python3.13/site-packages/pygments/lexers/gsql.py": 15294109558028161389,
+ "backend/src/api/routes/__tests__/test_git_status_route.py": 4501452711469218555,
+ "venv/lib/python3.13/site-packages/fastapi/middleware/cors.py": 7452860773712601508,
+ "venv/lib/python3.13/site-packages/numpy/core/_dtype_ctypes.pyi": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/pygments/styles/murphy.py": 8177992406082781615,
+ "venv/lib/python3.13/site-packages/pygments/lexers/installers.py": 5083244110640899732,
+ "venv/lib/python3.13/site-packages/certifi-2025.11.12.dist-info/licenses/LICENSE": 14230156892574098522,
+ "venv/lib/python3.13/site-packages/authlib/oidc/core/__init__.py": 16029653645350087968,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/regression/f77fixedform.f95": 10898637805043867370,
+ "venv/lib/python3.13/site-packages/pandas/tests/series/methods/test_copy.py": 3114918520437707410,
+ "backend/src/plugins/llm_analysis/plugin.py": 11133953577515642529,
+ "venv/lib/python3.13/site-packages/pip/_internal/resolution/resolvelib/base.py": 13454394827268856575,
+ "venv/lib/python3.13/site-packages/rsa/transform.py": 12261738253972114335,
+ "venv/lib/python3.13/site-packages/pygments/lexers/parasail.py": 7758704230750989282,
+ "backend/tests/services/clean_release/test_publication_service.py": 12656754025482108211,
+ "backend/git_repos/remote/test-repo.git/objects/c2/491dfd8c841bacd5f491510f6334aa4a626f00": 6297303620364618482,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/parameter/constant_array.f90": 9711940829820746513,
+ "frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js": 4485532466755188385,
+ "venv/lib/python3.13/site-packages/pygments/lexers/_qlik_builtins.py": 1728058904137960444,
+ "venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/hstore.py": 9700253004947691961,
+ "venv/lib/python3.13/site-packages/pandas/core/reshape/encoding.py": 12702053687535473061,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_util.py": 16024147572807865219,
+ "venv/lib/python3.13/site-packages/rapidfuzz/__pyinstaller/test_rapidfuzz_packaging.py": 5189055608193366093,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/common.py": 7426635866622531875,
+ "venv/lib/python3.13/site-packages/uvicorn-0.40.0.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc7662/token_validator.py": 13917237710752731397,
+ "venv/lib/python3.13/site-packages/pydantic_core/_pydantic_core.pyi": 16799580742094025110,
+ "backend/git_repos/remote/test-repo.git/refs/heads/dev": 8596267258668462395,
+ "backend/src/models/__tests__/test_clean_release.py": 9937664704633848570,
+ "venv/lib/python3.13/site-packages/starlette/endpoints.py": 3379755567024530053,
+ "venv/lib/python3.13/site-packages/pydantic_settings/py.typed": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/more_itertools-10.8.0.dist-info/METADATA": 6960169108624303030,
+ "venv/lib/python3.13/site-packages/sqlalchemy/cyextension/collections.cpython-313-x86_64-linux-gnu.so": 6157288238855118017,
+ "venv/lib/python3.13/site-packages/pydantic/_internal/_config.py": 12760390602912369447,
+ "venv/lib/python3.13/site-packages/numpy/_core/tests/examples/limited_api/limited_api1.c": 8494977275215578998,
+ "venv/lib/python3.13/site-packages/h11/_util.py": 9362339074207904329,
+ "frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js": 10301023261856534116,
+ "venv/lib/python3.13/site-packages/_pytest/_io/saferepr.py": 8025234471485188730,
+ "venv/lib/python3.13/site-packages/pygments/styles/fruity.py": 7925019839136894457,
+ "backend/src/core/superset_client/_datasets_preview_filters.py": 3588066821120121881,
+ "frontend/playwright-report/trace/defaultSettingsView.BDKsFU3c.css": 12935551588108679759,
+ "venv/lib/python3.13/site-packages/python_jose-3.5.0.dist-info/licenses/LICENSE": 17020744174398828059,
+ "backend/src/models/dataset_review.py": 18282368342351080120,
+ "venv/lib/python3.13/site-packages/pip/_vendor/platformdirs/version.py": 14723293207188512766,
+ "venv/lib/python3.13/site-packages/pandas/tests/frame/methods/test_align.py": 10284128457194204574,
+ "venv/lib/python3.13/site-packages/numpy/core/einsumfunc.py": 3484247123731380377,
+ "backend/src/api/routes/assistant/_routes.py": 17155281273786858236,
+ "venv/lib/python3.13/site-packages/pygments/lexers/d.py": 18120801227801223376,
+ "venv/lib/python3.13/site-packages/numpy/ctypeslib/__init__.pyi": 13208953770241664384,
+ "venv/lib/python3.13/site-packages/numpy/tests/test_configtool.py": 8208415015478205502,
+ "backend/src/services/notifications/__init__.py": 16179868089470006686,
+ "venv/lib/python3.13/site-packages/authlib/oauth2/rfc6749/grants/__init__.py": 3577295959173028042,
+ "venv/lib/python3.13/site-packages/pandas/core/computation/scope.py": 16859504937881548797,
+ "venv/lib/python3.13/site-packages/jeepney/bus.py": 5163075760432139100,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_char_codes.py": 14162745886150625150,
+ "venv/lib/python3.13/site-packages/jeepney/auth.py": 10565040329507087892,
+ "venv/lib/python3.13/site-packages/packaging/pylock.py": 15346942039643310253,
+ "backend/src/schemas/translate.py": 15896789917354585618,
+ "venv/lib/python3.13/site-packages/pip/_internal/cli/__init__.py": 11914508471759255927,
+ "venv/lib/python3.13/site-packages/pygments/lexers/rita.py": 8105458520706587972,
+ "venv/lib/python3.13/site-packages/pygments/lexers/unicon.py": 1155454077052833821,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/abc.py": 6227782083136374888,
+ "venv/lib/python3.13/site-packages/pandas/tests/io/excel/test_odswriter.py": 5134385709728943904,
+ "frontend/build/_app/immutable/nodes/10.CizHWbJb.js": 15960943239719776356,
+ "venv/lib/python3.13/site-packages/pandas/tests/strings/conftest.py": 12065119814157197510,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/bindings/_rust/openssl/cmac.pyi": 16042272072158438261,
+ "venv/lib/python3.13/site-packages/rapidfuzz/distance/Hamming.pyi": 4432290176776357346,
+ "venv/lib/python3.13/site-packages/pip/_vendor/rich/_stack.py": 5316826578695144945,
+ "venv/lib/python3.13/site-packages/pygments/styles/material.py": 14325514369696961874,
+ "frontend/build/_app/immutable/chunks/sEGDVeoa.js": 9540107777971680079,
+ "venv/lib/python3.13/site-packages/passlib/tests/test_crypto_des.py": 7198931807116651263,
+ "venv/lib/python3.13/site-packages/pygments/lexers/int_fiction.py": 8806961041808606055,
+ "venv/lib/python3.13/site-packages/pandas/core/internals/construction.py": 893951849732478990,
+ "venv/lib/python3.13/site-packages/psycopg2_binary.libs/libgssapi_krb5-497db0c6.so.2.2": 6199424505696679197,
+ "venv/lib/python3.13/site-packages/jsonschema-4.25.1.dist-info/INSTALLER": 17282701611721059870,
+ "venv/lib/python3.13/site-packages/pandas/plotting/_matplotlib/boxplot.py": 7090586111222952862,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/timedeltas/test_formats.py": 12299393760307251036,
+ "venv/lib/python3.13/site-packages/pandas/core/__init__.py": 15130871412783076140,
+ "venv/lib/python3.13/site-packages/rsa/key.py": 4783269051050521475,
+ "backend/src/api/routes/__tests__/test_datasets.py": 5175841745704208723,
+ "venv/lib/python3.13/site-packages/numpy/typing/tests/data/reveal/lib_function_base.pyi": 10972502518588022706,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/floating/test_construction.py": 6564829381134214401,
+ "venv/lib/python3.13/site-packages/cryptography/hazmat/primitives/kdf/argon2.py": 15389474901714096890,
+ "venv/lib/python3.13/site-packages/sqlalchemy/sql/crud.py": 805684028038896506,
+ "venv/lib/python3.13/site-packages/pandas/tests/indexes/multi/test_integrity.py": 12010564145080323987,
+ "venv/lib/python3.13/site-packages/pygments/lexers/go.py": 11118104397271513417,
+ "venv/lib/python3.13/site-packages/pandas/tests/base/test_transpose.py": 1686867045869336370,
+ "venv/lib/python3.13/site-packages/numpy/_typing/_nbit_base.pyi": 6546751036506752550,
+ "backend/src/scripts/init_auth_db.py": 8910351541713877041,
+ "backend/src/models/mapping.py": 17370626239851802183,
+ "venv/lib/python3.13/site-packages/numpy/f2py/tests/src/return_real/foo77.f": 16156304612888138777,
+ "venv/lib/python3.13/site-packages/six-1.17.0.dist-info/RECORD": 11604408378998955169,
+ "venv/lib/python3.13/site-packages/dotenv/__init__.py": 15464030923609356017,
+ "venv/lib/python3.13/site-packages/pandas/tests/arrays/masked/test_indexing.py": 9862204223281834360,
+ "backend/src/services/clean_release/demo_data_service.py": 14506634271910590558,
+ "venv/lib/python3.13/site-packages/pydantic/v1/json.py": 16596969681914729251
}
}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 27e75249..1243c967 100755
--- a/.gitignore
+++ b/.gitignore
@@ -93,3 +93,6 @@ semantic_audit_report.md
# E2E screenshots
e2e_*.png
+
+#generated doxygen
+docs/api/html
diff --git a/backend/src/api/routes/__tests__/test_migration_routes.py b/backend/src/api/routes/__tests__/test_migration_routes.py
index 952195e5..6fbedb97 100644
--- a/backend/src/api/routes/__tests__/test_migration_routes.py
+++ b/backend/src/api/routes/__tests__/test_migration_routes.py
@@ -2,7 +2,7 @@
#
# @BRIEF Unit tests for migration API route handlers.
# @LAYER API
-# @RELATION BINDS_TO -> [EXT:path:backend.src.api.routes.migration]
+# @RELATION BINDS_TO -> [MigrationApi]
#
from datetime import UTC, datetime
from pathlib import Path
diff --git a/backend/src/api/routes/admin_api_keys.py b/backend/src/api/routes/admin_api_keys.py
index d05e504b..9f597b08 100644
--- a/backend/src/api/routes/admin_api_keys.py
+++ b/backend/src/api/routes/admin_api_keys.py
@@ -3,7 +3,7 @@
# @LAYER API
# @RELATION DEPENDS_ON -> [APIKeyModel]
# @RELATION DEPENDS_ON -> [APIKeyUtilities]
-# @RELATION DEPENDS_ON -> [EXT:code:has_permission("admin:settings", "WRITE")]
+# @RELATION DEPENDS_ON -> [EXT:code:has_permission_admin_settings_WRITE]
# @INVARIANT GET /api/admin/api-keys NEVER returns key_hash or raw_key.
# @INVARIANT POST /api/admin/api-keys returns raw_key ONCE — never stored, never retrievable again.
# @INVARIANT DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.
diff --git a/backend/src/api/routes/assistant/_history.py b/backend/src/api/routes/assistant/_history.py
index 3bcebef8..89b594c3 100644
--- a/backend/src/api/routes/assistant/_history.py
+++ b/backend/src/api/routes/assistant/_history.py
@@ -33,7 +33,7 @@ logger = logger
# #region _append_history [C:2] [TYPE Function]
# @BRIEF Append conversation message to in-memory history buffer.
# @DATA_CONTRACT Input[user_id,conversation_id,role,text,state?,task_id?,confirmation_id?] -> Output[None]
-# @RELATION BINDS_TO -> [EXT:internal:CONVERSATIONS]
+# @RELATION BINDS_TO -> [CONVERSATIONS]
# @SIDE_EFFECT Mutates in-memory CONVERSATIONS store for user conversation history.
# @PRE user_id and conversation_id identify target conversation bucket.
# @POST Message entry is appended to CONVERSATIONS key list.
@@ -111,7 +111,7 @@ def _persist_message(
# #region _audit [C:2] [TYPE Function]
# @BRIEF Append in-memory audit record for assistant decision trace.
# @DATA_CONTRACT Input[user_id,payload:Dict[str,Any]] -> Output[None]
-# @RELATION BINDS_TO -> [EXT:internal:ASSISTANT_AUDIT]
+# @RELATION BINDS_TO -> [ASSISTANT_AUDIT]
# @SIDE_EFFECT Mutates in-memory ASSISTANT_AUDIT store and emits structured log event.
# @PRE payload describes decision/outcome fields.
# @POST ASSISTANT_AUDIT list for user contains new timestamped entry.
diff --git a/backend/src/api/routes/assistant/_schemas.py b/backend/src/api/routes/assistant/_schemas.py
index 334bd83f..e3ebb91f 100644
--- a/backend/src/api/routes/assistant/_schemas.py
+++ b/backend/src/api/routes/assistant/_schemas.py
@@ -99,7 +99,14 @@ class ConfirmationRecord(BaseModel):
# --- In-memory stores ---
+# #region CONVERSATIONS [C:1] [TYPE Constant]
+# @BRIEF In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}
+# #endregion CONVERSATIONS
CONVERSATIONS: dict[tuple[str, str], list[dict[str, Any]]] = {}
+
+# #region ASSISTANT_AUDIT [C:1] [TYPE Constant]
+# @BRIEF In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.
+# #endregion ASSISTANT_AUDIT
USER_ACTIVE_CONVERSATION: dict[str, str] = {}
CONFIRMATIONS: dict[str, ConfirmationRecord] = {}
ASSISTANT_AUDIT: dict[str, list[dict[str, Any]]] = {}
diff --git a/backend/src/api/routes/dashboards/_action_routes.py b/backend/src/api/routes/dashboards/_action_routes.py
index 42d03b03..7edec0ef 100644
--- a/backend/src/api/routes/dashboards/_action_routes.py
+++ b/backend/src/api/routes/dashboards/_action_routes.py
@@ -1,7 +1,7 @@
# #region DashboardActionRoutes [C:2] [TYPE Module] [SEMANTICS fastapi, dashboard, api, backup]
# @BRIEF Dashboard action route handlers — migrate, backup.
# @LAYER API
-# @RELATION DEPENDS_ON -> [[EXT:frontend:DashboardRouter]]
+# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]
# @RELATION DEPENDS_ON -> [DashboardSchemas]
from fastapi import Depends, HTTPException
diff --git a/backend/src/api/routes/dashboards/_detail_routes.py b/backend/src/api/routes/dashboards/_detail_routes.py
index 52868223..2a81b605 100644
--- a/backend/src/api/routes/dashboards/_detail_routes.py
+++ b/backend/src/api/routes/dashboards/_detail_routes.py
@@ -1,7 +1,7 @@
# #region DashboardDetailRoutes [C:3] [TYPE Module] [SEMANTICS fastapi, dashboard, api, transform, search, task]
# @BRIEF Dashboard detail, db-mappings, task history, thumbnail route handlers.
# @LAYER API
-# @RELATION DEPENDS_ON -> [[EXT:frontend:DashboardRouter]]
+# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]
# @RELATION DEPENDS_ON -> [DashboardSchemas]
# @RELATION DEPENDS_ON -> [DashboardHelpers]
# @RELATION DEPENDS_ON -> [DashboardProjection]
diff --git a/backend/src/api/routes/dashboards/_listing_routes.py b/backend/src/api/routes/dashboards/_listing_routes.py
index fa72e373..8bec60ed 100644
--- a/backend/src/api/routes/dashboards/_listing_routes.py
+++ b/backend/src/api/routes/dashboards/_listing_routes.py
@@ -1,7 +1,7 @@
# #region DashboardListingRoutes [C:4] [TYPE Module] [SEMANTICS fastapi, dashboard, api, search]
# @BRIEF Dashboard listing route handler for Dashboard Hub.
# @LAYER API
-# @RELATION DEPENDS_ON -> [[EXT:frontend:DashboardRouter]]
+# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]
# @RELATION DEPENDS_ON -> [DashboardSchemas]
# @RELATION DEPENDS_ON -> [DashboardHelpers]
# @RELATION DEPENDS_ON -> [DashboardProjection]
diff --git a/backend/src/api/routes/git/__init__.py b/backend/src/api/routes/git/__init__.py
index 2da524d2..ccb865ab 100644
--- a/backend/src/api/routes/git/__init__.py
+++ b/backend/src/api/routes/git/__init__.py
@@ -1,7 +1,7 @@
# #region GitPackage [C:5] [TYPE Module] [SEMANTICS git, api, package, sync]
# @BRIEF Package root for decomposed git routes. Re-exports all public symbols from submodules.
# @LAYER API
-# @RELATION CALLS -> [[EXT:list:GitPackage_all_routes]]
+# @RELATION CALLS -> [GitPackage]
# @INVARIANT git_service and os are module-level attributes for test monkeypatch compatibility.
# @PRE Git service initialized
# @POST Git API package exported
diff --git a/backend/src/api/routes/git_schemas.py b/backend/src/api/routes/git_schemas.py
index f33b1d97..fcf34c7f 100644
--- a/backend/src/api/routes/git_schemas.py
+++ b/backend/src/api/routes/git_schemas.py
@@ -2,7 +2,7 @@
#
# @BRIEF Defines Pydantic models for the Git integration API layer.
# @LAYER API
-# @RELATION DEPENDS_ON -> [EXT:path:backend.src.models.git]
+# @RELATION DEPENDS_ON -> [GitModels]
#
# @INVARIANT All schemas must be compatible with the FastAPI router.
diff --git a/backend/src/api/routes/health.py b/backend/src/api/routes/health.py
index 63ab54fa..6196a2cd 100644
--- a/backend/src/api/routes/health.py
+++ b/backend/src/api/routes/health.py
@@ -18,7 +18,7 @@ router = APIRouter(prefix="/api/health", tags=["Health"])
# @BRIEF Get aggregated health status for all dashboards.
# @PRE Caller has read permission for dashboard health view.
# @POST Returns HealthSummaryResponse.
-# @RELATION CALLS -> [EXT:path:backend.src.services.health_service.HealthService]
+# @RELATION CALLS -> [HealthService]
@router.get("/summary", response_model=HealthSummaryResponse)
async def get_health_summary(
environment_id: str | None = Query(None),
@@ -41,7 +41,7 @@ async def get_health_summary(
# @BRIEF Delete one persisted dashboard validation report from health summary.
# @PRE Caller has write permission for tasks/report maintenance.
# @POST Validation record is removed; linked task/logs are cleaned when available.
-# @RELATION CALLS -> [EXT:path:backend.src.services.health_service.HealthService]
+# @RELATION CALLS -> [HealthService]
@router.delete("/summary/{record_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_health_report(
record_id: str,
diff --git a/backend/src/api/routes/maintenance/_routes.py b/backend/src/api/routes/maintenance/_routes.py
index 82e7762e..adfbf0c2 100644
--- a/backend/src/api/routes/maintenance/_routes.py
+++ b/backend/src/api/routes/maintenance/_routes.py
@@ -54,7 +54,7 @@ from ._schemas import (
# #region list_dashboard_banners [C:2] [TYPE Function]
# @BRIEF Get per-dashboard banner state for the Dashboard Hub indicator.
-# @RELATION DEPENDS_ON -> [EXT:code:has_permission("maintenance", "READ")]
+# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]
@router.get("/dashboard-banners", response_model=list[MaintenanceDashboardBannerState])
async def list_dashboard_banners(
db: Session = Depends(get_db),
@@ -118,7 +118,7 @@ async def list_dashboard_banners(
# #region list_events [C:2] [TYPE Function]
# @BRIEF Get active and completed maintenance event lists with affected dashboard counts.
-# @RELATION DEPENDS_ON -> [EXT:code:has_permission("maintenance", "READ")]
+# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]
@router.get("/events", response_model=MaintenanceEventListResponse)
async def list_events(
db: Session = Depends(get_db),
@@ -500,7 +500,7 @@ async def end_all_maintenance(
# #region get_maintenance_settings [C:2] [TYPE Function]
# @BRIEF Get current maintenance settings configuration.
-# @RELATION DEPENDS_ON -> [EXT:code:has_permission("maintenance", "READ")]
+# @RELATION DEPENDS_ON -> [EXT:code:has_permission_maintenance_READ]
@router.get("/settings", response_model=MaintenanceSettingsResponse)
async def get_maintenance_settings(
db: Session = Depends(get_db),
diff --git a/backend/src/core/__tests__/test_native_filters.py b/backend/src/core/__tests__/test_native_filters.py
index a44dc6ce..d552a540 100644
--- a/backend/src/core/__tests__/test_native_filters.py
+++ b/backend/src/core/__tests__/test_native_filters.py
@@ -3,7 +3,7 @@
# @LAYER Domain
# @RELATION BINDS_TO ->[SupersetClient]
# @RELATION BINDS_TO ->[AsyncSupersetClient]
-# @RELATION BINDS_TO ->[[EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge]]
+# @RELATION BINDS_TO ->[FilterState]
import json
from unittest.mock import MagicMock
diff --git a/backend/src/core/async_superset_client.py b/backend/src/core/async_superset_client.py
index 20eddd86..c8aedf56 100644
--- a/backend/src/core/async_superset_client.py
+++ b/backend/src/core/async_superset_client.py
@@ -16,7 +16,6 @@ from .utils.async_network import AsyncAPIClient
# @BRIEF Async sibling of SupersetClient for dashboard read paths.
# @RELATION INHERITS -> [SupersetClient]
# @RELATION DEPENDS_ON -> [AsyncAPIClient]
-# @RELATION CALLS -> [EXT:method:AsyncAPIClient.request]
class AsyncSupersetClient(SupersetClient):
# #region AsyncSupersetClientInit [TYPE Function] [C:3]
# @PURPOSE: Initialize async Superset client with AsyncAPIClient transport.
diff --git a/backend/src/core/auth/__tests__/test_auth.py b/backend/src/core/auth/__tests__/test_auth.py
index 14826c6d..5bd4d1bc 100644
--- a/backend/src/core/auth/__tests__/test_auth.py
+++ b/backend/src/core/auth/__tests__/test_auth.py
@@ -255,5 +255,5 @@ def test_provision_adfs_user_existing(auth_service, auth_repo):
assert user is not None
assert user.username == "existingadfs@domain.com"
assert len(user.roles) == 0 # No matching group mappings
-# #endregion test_auth
# #endregion test_provision_adfs_user_existing
+# #endregion test_auth
diff --git a/backend/src/core/config_models.py b/backend/src/core/config_models.py
index 877b2180..c8de806f 100755
--- a/backend/src/core/config_models.py
+++ b/backend/src/core/config_models.py
@@ -1,9 +1,16 @@
# #region ConfigModels [C:3] [TYPE Module] [SEMANTICS pydantic, model, schedule]
# @BRIEF Defines the data models for application configuration using Pydantic.
# @LAYER Core
-# @RELATION IMPLEMENTS -> [EXT:internal:CoreContracts]
-# @RELATION IMPLEMENTS -> [EXT:internal:ConnectionContracts]
-
+# @RELATION IMPLEMENTS -> [CoreContracts]
+# @RELATION IMPLEMENTS -> [ConnectionContracts]
+#
+# #region CoreContracts [C:2] [TYPE Interface]
+# @BRIEF Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.
+# #endregion CoreContracts
+#
+# #region ConnectionContracts [C:2] [TYPE Interface]
+# @BRIEF Contract for database/environment connection configuration models.
+# #endregion ConnectionContracts
from pydantic import BaseModel, Field, field_validator
diff --git a/backend/src/core/cot_logger.py b/backend/src/core/cot_logger.py
index 3d7eb5a6..ad3183ac 100644
--- a/backend/src/core/cot_logger.py
+++ b/backend/src/core/cot_logger.py
@@ -4,7 +4,7 @@
# Provides log(), MarkerLogger, seed_trace_id(), push_span(), pop_span().
# @LAYER Core
# @RELATION CALLED_BY -> [TraceContextMiddleware]
-# @RELATION CALLED_BY -> [EXT:internal:All C4+ service and route modules]
+# @RELATION CALLED_BY -> [CotLoggerModule]
# @PRE Python 3.7+ (ContextVar available).
# @POST JSON log records written to the 'cot' logger at appropriate levels.
# @SIDE_EFFECT Writes structured JSON to the 'cot' Python logger.
diff --git a/backend/src/core/logger.py b/backend/src/core/logger.py
index eb2b31a1..9bc96db6 100755
--- a/backend/src/core/logger.py
+++ b/backend/src/core/logger.py
@@ -1,7 +1,7 @@
# #region LoggerModule [C:5] [TYPE Module] [SEMANTICS pydantic, logging, json, formatter, structured]
# @BRIEF Application logging system with CotJsonFormatter producing molecular CoT JSON output.
# @LAYER Core
-# @RELATION CALLED_BY -> [EXT:internal:All application modules]
+# @RELATION CALLED_BY -> [LoggerModule]
# @RELATION DEPENDS_ON -> [CotLoggerModule]
# @RELATION DEPENDS_ON -> [WebSocketLogHandler]
# @PRE Python 3.7+ with cot_logger ContextVars available.
@@ -37,7 +37,7 @@ _task_log_level = "INFO"
# #region CotJsonFormatter [C:3] [TYPE Class] [SEMANTICS logging,formatter,json,cot,protocol]
# @BRIEF JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
-# @RELATION IMPLEMENTS -> [EXT:internal:CotJsonFormat]
+# @RELATION IMPLEMENTS -> [CotJsonFormatter]
class CotJsonFormatter(logging.Formatter):
"""JSON formatter implementing the molecular CoT logging protocol.
diff --git a/backend/src/core/logger/__tests__/test_logger.py b/backend/src/core/logger/__tests__/test_logger.py
index f142d719..ee403350 100644
--- a/backend/src/core/logger/__tests__/test_logger.py
+++ b/backend/src/core/logger/__tests__/test_logger.py
@@ -1,7 +1,7 @@
# #region test_logger [TYPE Module] [C:3] [SEMANTICS test, logger, logging, unit]
# @BRIEF Unit tests for logger module
# @LAYER Infrastructure
-# @RELATION BINDS_TO -> [EXT:path:src.core.logger]
+# @RELATION BINDS_TO -> [LoggerModule]
from pathlib import Path
import sys
diff --git a/backend/src/core/migration_engine.py b/backend/src/core/migration_engine.py
index befae2d4..3b4677a0 100644
--- a/backend/src/core/migration_engine.py
+++ b/backend/src/core/migration_engine.py
@@ -28,7 +28,7 @@ from .logger import belief_scope, logger
# #region MigrationEngine [TYPE Class]
# @BRIEF Engine for transforming Superset export ZIPs.
-# @RELATION DEPENDS_ON -> [[EXT:list:MigrationEngine_internal_methods]]
+# @RELATION DEPENDS_ON -> [MigrationEngine]
class MigrationEngine:
# #region __init__ [TYPE Function]
# @PURPOSE: Initializes migration orchestration dependencies for ZIP/YAML metadata transformations.
@@ -45,7 +45,7 @@ class MigrationEngine:
# #endregion __init__
# #region transform_zip [TYPE Function]
# @PURPOSE: Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.
- # @RELATION DEPENDS_ON -> [[EXT:list:MigrateEngine_transform_methods]]
+ # @RELATION DEPENDS_ON -> [MigrationEngine]
# @PARAM zip_path (str) - Path to the source ZIP file.
# @PARAM output_path (str) - Path where the transformed ZIP will be saved.
# @PARAM db_mapping (Dict[str, str]) - Mapping of source UUID to target UUID.
diff --git a/backend/src/core/superset_client/_dashboards_write.py b/backend/src/core/superset_client/_dashboards_write.py
index b5c33d7c..39ed74c0 100644
--- a/backend/src/core/superset_client/_dashboards_write.py
+++ b/backend/src/core/superset_client/_dashboards_write.py
@@ -14,7 +14,7 @@ import json
from typing import Any, cast
from ..logger import belief_scope, logger as app_logger
-from ._layout[EXT:internal:_utils] import (
+from ._layout_utils import (
insert_banner_markdown_at_top,
parse_position_json,
remove_banner_from_position,
diff --git a/backend/src/core/task_manager/__tests__/test_task_logger.py b/backend/src/core/task_manager/__tests__/test_task_logger.py
index 689a73d1..a44a0cfd 100644
--- a/backend/src/core/task_manager/__tests__/test_task_logger.py
+++ b/backend/src/core/task_manager/__tests__/test_task_logger.py
@@ -1,5 +1,5 @@
# #region __tests__/test_task_logger [TYPE Module] [SEMANTICS test, task, logger, contract]
-# @RELATION BINDS_TO -> ../task_logger.py
+# @RELATION BINDS_TO -> [EXT:path:task_logger]
# @BRIEF Contract testing for TaskLogger
# #endregion __tests__/test_task_logger
import pytest
diff --git a/backend/src/models/config.py b/backend/src/models/config.py
index 796ec8d3..88648b90 100644
--- a/backend/src/models/config.py
+++ b/backend/src/models/config.py
@@ -3,7 +3,7 @@
# @BRIEF Defines SQLAlchemy persistence models for application and notification configuration records.
# @LAYER Domain
-# @RELATION DEPENDS_ON -> [EXT:internal:MappingModels:Base]
+# @RELATION DEPENDS_ON -> [MappingModels]
# @INVARIANT Configuration payload and notification credentials must remain persisted as non-null JSON documents.
from sqlalchemy import JSON, Boolean, Column, DateTime, String
diff --git a/backend/src/models/llm.py b/backend/src/models/llm.py
index a2cf916c..0e51e215 100644
--- a/backend/src/models/llm.py
+++ b/backend/src/models/llm.py
@@ -1,7 +1,7 @@
# #region LlmModels [C:3] [TYPE Module] [SEMANTICS sqlalchemy, llm, model, schema, validate, provider]
# @BRIEF SQLAlchemy models for LLM provider configuration and validation results.
# @LAYER Domain
-# @RELATION INHERITS -> MappingModels:Base
+# @RELATION INHERITS -> [MappingModels]
from datetime import datetime
import uuid
diff --git a/backend/src/models/maintenance.py b/backend/src/models/maintenance.py
index c3000dae..a0d0b842 100644
--- a/backend/src/models/maintenance.py
+++ b/backend/src/models/maintenance.py
@@ -2,7 +2,7 @@
# @BRIEF SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.
# @LAYER Domain
# @RELATION DEPENDS_ON -> [EXT:Library:sqlalchemy]
-# @RELATION DEPENDS_ON -> [EXT:internal:MappingBase]
+# @RELATION DEPENDS_ON -> [MappingModels]
# @INVARIANT MaintenanceDashboardBanner has unique partial index on (environment_id, dashboard_id) WHERE status='active'
# @INVARIANT MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint
diff --git a/backend/src/models/mapping.py b/backend/src/models/mapping.py
index b28dece3..0d8a4b35 100644
--- a/backend/src/models/mapping.py
+++ b/backend/src/models/mapping.py
@@ -19,6 +19,9 @@ from sqlalchemy import Boolean, Column, DateTime, Enum as SQLEnum, ForeignKey, S
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func
+# #region Base [C:1] [TYPE Class]
+# @BRIEF SQLAlchemy declarative base for all domain models.
+# #endregion Base
Base = declarative_base()
# #region ResourceType [C:1] [TYPE Class]
diff --git a/backend/src/models/profile.py b/backend/src/models/profile.py
index 3807a15a..57ad96e6 100644
--- a/backend/src/models/profile.py
+++ b/backend/src/models/profile.py
@@ -3,7 +3,7 @@
# @BRIEF Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
# @LAYER Domain
# @RELATION DEPENDS_ON -> [AuthModels]
-# @RELATION INHERITS -> [EXT:internal:MappingModels:Base]
+# @RELATION INHERITS -> [MappingModels]
#
# @INVARIANT Exactly one preference row exists per user_id.
# @INVARIANT Sensitive Git token is stored encrypted and never returned in plaintext.
@@ -23,7 +23,7 @@ from .mapping import Base
# #region UserDashboardPreference [C:3] [TYPE Class]
# @BRIEF Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
-# @RELATION INHERITS -> MappingModels:Base
+# @RELATION INHERITS -> [MappingModels]
class UserDashboardPreference(Base):
__tablename__ = "user_dashboard_preferences"
diff --git a/backend/src/plugins/git_plugin.py b/backend/src/plugins/git_plugin.py
index 29c8c689..380d70ab 100644
--- a/backend/src/plugins/git_plugin.py
+++ b/backend/src/plugins/git_plugin.py
@@ -2,7 +2,7 @@
#
# @BRIEF Предоставляет плагин для версионирования и развертывания дашбордов Superset.
# @LAYER Plugin
-# @RELATION INHERITS -> [EXT:path:src.core.plugin_base.PluginBase]
+# @RELATION INHERITS -> [PluginBase]
# @RELATION DEPENDS_ON -> [GitService]
# @RELATION DEPENDS_ON -> [SupersetClient]
# @RELATION DEPENDS_ON -> [ConfigManager]
diff --git a/backend/src/plugins/llm_analysis/plugin.py b/backend/src/plugins/llm_analysis/plugin.py
index 66dd7826..4e58783e 100644
--- a/backend/src/plugins/llm_analysis/plugin.py
+++ b/backend/src/plugins/llm_analysis/plugin.py
@@ -61,7 +61,7 @@ def _json_safe_value(value: Any):
# #region DashboardValidationPlugin [TYPE Class]
# @BRIEF Plugin for automated dashboard health analysis using LLMs.
-# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]
+# @RELATION IMPLEMENTS -> [PluginBase]
class DashboardValidationPlugin(PluginBase):
@property
def id(self) -> str:
@@ -326,7 +326,7 @@ class DashboardValidationPlugin(PluginBase):
# #region DocumentationPlugin [TYPE Class]
# @BRIEF Plugin for automated dataset documentation using LLMs.
-# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]
+# @RELATION IMPLEMENTS -> [PluginBase]
class DocumentationPlugin(PluginBase):
@property
def id(self) -> str:
diff --git a/backend/src/plugins/translate/__tests__/test_dictionary.py b/backend/src/plugins/translate/__tests__/test_dictionary.py
index d58be64a..54f86350 100644
--- a/backend/src/plugins/translate/__tests__/test_dictionary.py
+++ b/backend/src/plugins/translate/__tests__/test_dictionary.py
@@ -5,7 +5,7 @@
# test_dictionary_filter.py — Batch filter + migration
# test_dictionary_correction.py — Correction context capture
# test_dictionary_prompt_builder.py — Prompt builder operations
-# test_dictionary[EXT:internal:_utils].py — Utility functions
+# test_dictionary_utils.py — Utility functions
# @RELATION BINDS_TO -> [DictionaryManager]
# @RATIONALE Split monolithic test module into domain-specific files per INV_7.
# @REJECTED Keeping 1199-line test module violates module < 400 lines constraint.
@@ -16,5 +16,5 @@ from .test_dictionary_crud import * # noqa: F401, F403
from .test_dictionary_filter import * # noqa: F401, F403
from .test_dictionary_import import * # noqa: F401, F403
from .test_dictionary_prompt_builder import * # noqa: F401, F403
-from .test_dictionary[EXT:internal:_utils] import * # noqa: F401, F403
+from .test_dictionary_utils import * # noqa: F401, F403
# #endregion TestDictionaryLegacyHub
diff --git a/backend/src/plugins/translate/__tests__/test_dictionary_utils.py b/backend/src/plugins/translate/__tests__/test_dictionary_utils.py
index 65c01291..274aef36 100644
--- a/backend/src/plugins/translate/__tests__/test_dictionary_utils.py
+++ b/backend/src/plugins/translate/__tests__/test_dictionary_utils.py
@@ -1,8 +1,8 @@
# #region TestDictionaryUtils [C:3] [TYPE Module] [SEMANTICS test, dictionary, utils, normalization]
# @BRIEF Validate utility functions: _normalize_term and _detect_delimiter.
-# @RELATION BINDS_TO -> [[EXT:internal:_utils]]
+# @RELATION BINDS_TO -> [TranslationUtils]
-from src.plugins.translate.[EXT:internal:_utils] import _detect_delimiter, _normalize_term
+from src.plugins.translate._utils import _detect_delimiter, _normalize_term
class TestNormalizeTerm:
diff --git a/backend/src/plugins/translate/__tests__/test_text_cleaner.py b/backend/src/plugins/translate/__tests__/test_text_cleaner.py
index 296ff23a..a0c3e2cd 100644
--- a/backend/src/plugins/translate/__tests__/test_text_cleaner.py
+++ b/backend/src/plugins/translate/__tests__/test_text_cleaner.py
@@ -1,13 +1,13 @@
# #region TestTextCleaner [C:3] [TYPE Module] [SEMANTICS test, text, cleaner, whitespace, truncation]
# @BRIEF Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.
-# @RELATION BINDS_TO -> [[EXT:internal:_text_cleaner]]
+# @RELATION BINDS_TO -> [TextCleaner]
# @TEST_EDGE empty_string — empty/whitespace-only input returns ""
# @TEST_EDGE whitespace_variants — multiple spaces, newlines, tabs all collapse to single space
# @TEST_EDGE truncation_boundary — text shorter than, equal to, and longer than max_length
# @TEST_EDGE clean_combined — clean_text correctly chains normalize + truncate
# @TEST_EDGE zero_max_length — max_length=0 forces truncation on any non-empty text
-from src.plugins.translate.[EXT:internal:_text_cleaner] import clean_text, normalize_whitespace, truncate_text
+from src.plugins.translate._text_cleaner import clean_text, normalize_whitespace, truncate_text
# region TestNormalizeWhitespace [TYPE Class]
diff --git a/backend/src/plugins/translate/_batch_proc.py b/backend/src/plugins/translate/_batch_proc.py
index e553fcb5..13472654 100644
--- a/backend/src/plugins/translate/_batch_proc.py
+++ b/backend/src/plugins/translate/_batch_proc.py
@@ -27,7 +27,7 @@ from ._batch_insert import insert_batch_to_target
from ._lang_detect import batch_detect, get_detector
from ._llm_call import LLMTranslationService
from ._token_budget import estimate_token_budget
-from .[EXT:internal:_utils] import _check_translation_cache, _compute_key_hash, _compute_source_hash
+from ._utils import _check_translation_cache, _compute_key_hash, _compute_source_hash
from .dictionary import DictionaryManager
diff --git a/backend/src/plugins/translate/_batch_sizer.py b/backend/src/plugins/translate/_batch_sizer.py
index 41c85786..4d9b348b 100644
--- a/backend/src/plugins/translate/_batch_sizer.py
+++ b/backend/src/plugins/translate/_batch_sizer.py
@@ -28,7 +28,7 @@ from ._token_budget import (
REASONING_OVERHEAD,
estimate_token_budget,
)
-from .[EXT:internal:_utils] import estimate_row_tokens
+from ._utils import estimate_row_tokens
# #region AdaptiveBatchSizer [C:3] [TYPE Class]
diff --git a/backend/src/plugins/translate/_llm_call.py b/backend/src/plugins/translate/_llm_call.py
index 36042748..0905e1bb 100644
--- a/backend/src/plugins/translate/_llm_call.py
+++ b/backend/src/plugins/translate/_llm_call.py
@@ -31,7 +31,7 @@ from ...services.llm_provider import LLMProviderService
from ._llm_http import call_openai_compatible
from ._llm_parse import parse_llm_response
from ._token_budget import estimate_token_budget
-from .[EXT:internal:_utils] import _enforce_dictionary
+from ._utils import _enforce_dictionary
from .preview import DEFAULT_EXECUTION_PROMPT_TEMPLATE
from .prompt_builder import ContextAwarePromptBuilder
diff --git a/backend/src/plugins/translate/dictionary_correction.py b/backend/src/plugins/translate/dictionary_correction.py
index 751a9dca..38e48c03 100644
--- a/backend/src/plugins/translate/dictionary_correction.py
+++ b/backend/src/plugins/translate/dictionary_correction.py
@@ -10,7 +10,7 @@ from sqlalchemy.orm import Session
from ...core.logger import belief_scope, logger
from ...models.translate import DictionaryEntry, TerminologyDictionary
-from .[EXT:internal:_utils] import _normalize_term
+from ._utils import _normalize_term
class DictionaryCorrectionService:
diff --git a/backend/src/plugins/translate/dictionary_entries.py b/backend/src/plugins/translate/dictionary_entries.py
index 1a3bbe2b..8d08eadc 100644
--- a/backend/src/plugins/translate/dictionary_entries.py
+++ b/backend/src/plugins/translate/dictionary_entries.py
@@ -8,7 +8,7 @@ from sqlalchemy.orm import Session
from ...core.logger import belief_scope, logger
from ...models.translate import DictionaryEntry, TerminologyDictionary
-from .[EXT:internal:_utils] import _normalize_term
+from ._utils import _normalize_term
from .dictionary_validation import _validate_bcp47
diff --git a/backend/src/plugins/translate/dictionary_import_export.py b/backend/src/plugins/translate/dictionary_import_export.py
index c3c1f4f4..e533fa12 100644
--- a/backend/src/plugins/translate/dictionary_import_export.py
+++ b/backend/src/plugins/translate/dictionary_import_export.py
@@ -11,7 +11,7 @@ from sqlalchemy.orm import Session
from ...core.logger import belief_scope, logger
from ...models.translate import DictionaryEntry, TerminologyDictionary
-from .[EXT:internal:_utils] import _detect_delimiter, _normalize_term
+from ._utils import _detect_delimiter, _normalize_term
class DictionaryImportExport:
diff --git a/backend/src/plugins/translate/executor.py b/backend/src/plugins/translate/executor.py
index 60cb2c71..ca96ef6c 100644
--- a/backend/src/plugins/translate/executor.py
+++ b/backend/src/plugins/translate/executor.py
@@ -13,7 +13,7 @@
# @INVARIANT Batch processing is independent — one batch failure does not affect others.
# @RATIONALE Extracted from monolithic executor.py (1974 lines) into thin orchestrator
# to comply with INV_7. Sub-services in _run_service, _batch_proc, _llm_call, _batch_sizer.
-# Module-level helpers moved to [EXT:internal:_utils].py.
+# Module-level helpers moved to _utils.py.
# @REJECTED Keeping monolithic executor.py at 1974 lines — violates INV_7 by +1574 lines.
# Single monolithic LLM call — would lose all progress on any failure.
@@ -29,7 +29,7 @@ from ...models.translate import TranslationJob, TranslationRun, TranslationRunLa
from ...services.llm_provider import LLMProviderService
from ._run_service import RunExecutionService
from ._token_budget import estimate_token_budget
-from .[EXT:internal:_utils] import _check_translation_cache, _compute_source_hash, _enforce_dictionary, estimate_row_tokens
+from ._utils import _check_translation_cache, _compute_source_hash, _enforce_dictionary, estimate_row_tokens
__all__ = [
"TranslationExecutor", "estimate_row_tokens",
diff --git a/backend/src/plugins/translate/plugin.py b/backend/src/plugins/translate/plugin.py
index 65b7c9e4..1099c537 100644
--- a/backend/src/plugins/translate/plugin.py
+++ b/backend/src/plugins/translate/plugin.py
@@ -12,7 +12,7 @@ from ...core.plugin_base import PluginBase
# #region TranslatePlugin [TYPE Class]
# @BRIEF Plugin for translating SQL queries and dashboard definitions across database dialects.
-# @RELATION IMPLEMENTS -> [EXT:path:backend.src.core.plugin_base.PluginBase]
+# @RELATION IMPLEMENTS -> [PluginBase]
class TranslatePlugin(PluginBase):
@property
def id(self) -> str:
diff --git a/backend/src/plugins/translate/service.py b/backend/src/plugins/translate/service.py
index 44ff6dfa..28aef1ad 100644
--- a/backend/src/plugins/translate/service.py
+++ b/backend/src/plugins/translate/service.py
@@ -9,7 +9,7 @@
# @SIDE_EFFECT Queries Superset for column metadata and database dialect at save time.
# @RATIONALE Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.
# @REJECTED Invalidating in-progress runs on config edit would break scheduled run continuity.
-# @REJECTED Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service[EXT:internal:_utils].
+# @REJECTED Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service_utils.
from datetime import UTC, datetime
from typing import Any
@@ -23,7 +23,7 @@ from ...models.translate import TranslationJob, TranslationJobDictionary
from ...schemas.translate import TranslateJobCreate, TranslateJobUpdate
from .dictionary import _validate_bcp47
from .service_datasource import fetch_datasource_metadata
-from .service[EXT:internal:_utils] import _extract_dialect, job_to_response
+from .service_utils import _extract_dialect, job_to_response
# #region TranslateJobService [TYPE Class]
@@ -272,5 +272,5 @@ from .service_datasource import ( # noqa: E402, F401
get_dialect_from_database,
)
from .service_inline_correction import InlineCorrectionService # noqa: E402, F401
-from .service[EXT:internal:_utils] import _extract_dialect, job_to_response # noqa: E402, F401
+from .service_utils import _extract_dialect, job_to_response # noqa: E402, F401
# #endregion TranslateJobService
diff --git a/backend/src/plugins/translate/service_inline_correction.py b/backend/src/plugins/translate/service_inline_correction.py
index a766a048..a1c13542 100644
--- a/backend/src/plugins/translate/service_inline_correction.py
+++ b/backend/src/plugins/translate/service_inline_correction.py
@@ -14,7 +14,7 @@ from sqlalchemy.orm import Session
from ...core.logger import belief_scope, logger
from ...models.translate import DictionaryEntry, TranslationLanguage, TranslationRecord
-from .[EXT:internal:_utils] import _normalize_term
+from ._utils import _normalize_term
class InlineCorrectionService:
diff --git a/backend/src/schemas/_external_stubs.py b/backend/src/schemas/_external_stubs.py
deleted file mode 100644
index e89f7f51..00000000
--- a/backend/src/schemas/_external_stubs.py
+++ /dev/null
@@ -1,1173 +0,0 @@
-# #region ExternalStubs [C:1] [TYPE Module] [SEMANTICS external,stubs,contracts]
-# @BRIEF Stub contract references for external libraries, frontend stores, Python stdlib,
-# file paths, and other targets that exist outside the GRACE-Poly contract network.
-# @RATIONALE These are placeholder contracts that allow @RELATION edges to resolve.
-# The EXT: prefix categorizes the external target type (Python stdlib, Library,
-# frontend store, file path, method reference, etc.).
-# @REJECTED Leaving unresolved_relation warnings was rejected — every @RELATION edge
-# MUST point to a valid contract ID. These stubs provide the target.
-
-# #region EXT:FastAPI:TestClient [C:1] [TYPE External]
-# @BRIEF External reference: TestClient
-# #endregion EXT:FastAPI:TestClient
-
-# #region EXT:Library:SQLAlchemy.Base [C:1] [TYPE External]
-# @BRIEF External library: SQLAlchemy.Base
-# #endregion EXT:Library:SQLAlchemy.Base
-
-# #region EXT:Library:authlib [C:1] [TYPE External]
-# @BRIEF External library: authlib
-# #endregion EXT:Library:authlib
-
-# #region EXT:Library:fastapi.APIRouter [C:1] [TYPE External]
-# @BRIEF External library: fastapi.APIRouter
-# #endregion EXT:Library:fastapi.APIRouter
-
-# #region EXT:Library:pydantic [C:1] [TYPE External]
-# @BRIEF External library: pydantic
-# #endregion EXT:Library:pydantic
-
-# #region EXT:Library:pytest [C:1] [TYPE External]
-# @BRIEF External library: pytest
-# #endregion EXT:Library:pytest
-
-# #region EXT:Library:sqlalchemy [C:1] [TYPE External]
-# @BRIEF External library: sqlalchemy
-# #endregion EXT:Library:sqlalchemy
-
-# #region EXT:Library:sqlalchemy.orm.Session [C:1] [TYPE External]
-# @BRIEF External library: sqlalchemy.orm.Session
-# #endregion EXT:Library:sqlalchemy.orm.Session
-
-# #region EXT:Library:yaml [C:1] [TYPE External]
-# @BRIEF External library: yaml
-# #endregion EXT:Library:yaml
-
-# #region EXT:Python:Exception [C:1] [TYPE External]
-# @BRIEF Python standard library module: Exception
-# #endregion EXT:Python:Exception
-
-# #region EXT:Python:hashlib [C:1] [TYPE External]
-# @BRIEF Python standard library module: hashlib
-# #endregion EXT:Python:hashlib
-
-# #region EXT:Python:hashlib.sha256 [C:1] [TYPE External]
-# @BRIEF Python standard library module: hashlib.sha256
-# #endregion EXT:Python:hashlib.sha256
-
-# #region EXT:Python:json [C:1] [TYPE External]
-# @BRIEF Python standard library module: json
-# #endregion EXT:Python:json
-
-# #region EXT:Python:secrets [C:1] [TYPE External]
-# @BRIEF Python standard library module: secrets
-# #endregion EXT:Python:secrets
-
-# #region EXT:Python:secrets.token_urlsafe [C:1] [TYPE External]
-# @BRIEF Python standard library module: secrets.token_urlsafe
-# #endregion EXT:Python:secrets.token_urlsafe
-
-# #region EXT:Python:uuid [C:1] [TYPE External]
-# @BRIEF Python standard library module: uuid
-# #endregion EXT:Python:uuid
-
-# #region EXT:build.sh [C:1] [TYPE External]
-# @BRIEF External reference: build.sh
-# #endregion EXT:build.sh
-
-# #region EXT:code:has_permission("admin:settings", "WRITE") [C:1] [TYPE External]
-# @BRIEF Code expression: has_permission("admin:settings", "WRITE")
-# #endregion EXT:code:has_permission("admin:settings", "WRITE")
-
-# #region EXT:code:has_permission("maintenance", "READ") [C:1] [TYPE External]
-# @BRIEF Code expression: has_permission("maintenance", "READ")
-# #endregion EXT:code:has_permission("maintenance", "READ")
-
-# #region EXT:code:has_permission("maintenance", "WRITE") [C:1] [TYPE External]
-# @BRIEF Code expression: has_permission("maintenance", "WRITE")
-# #endregion EXT:code:has_permission("maintenance", "WRITE")
-
-# #region EXT:frontend:AssistantChatPanel [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: AssistantChatPanel
-# #endregion EXT:frontend:AssistantChatPanel
-
-# #region EXT:frontend:AssistantFirstMessageIntegrationTest [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: AssistantFirstMessageIntegrationTest
-# #endregion EXT:frontend:AssistantFirstMessageIntegrationTest
-
-# #region EXT:frontend:BranchSelector [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: BranchSelector
-# #endregion EXT:frontend:BranchSelector
-
-# #region EXT:frontend:Breadcrumbs [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: Breadcrumbs
-# #endregion EXT:frontend:Breadcrumbs
-
-# #region EXT:frontend:ConflictResolver [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ConflictResolver
-# #endregion EXT:frontend:ConflictResolver
-
-# #region EXT:frontend:DashboardHub [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: DashboardHub
-# #endregion EXT:frontend:DashboardHub
-
-# #region EXT:frontend:DashboardValidationService [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: DashboardValidationService
-# #endregion EXT:frontend:DashboardValidationService
-
-# #region EXT:frontend:DeploymentModal [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: DeploymentModal
-# #endregion EXT:frontend:DeploymentModal
-
-# #region EXT:frontend:EnvironmentsTab [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: EnvironmentsTab
-# #endregion EXT:frontend:EnvironmentsTab
-
-# #region EXT:frontend:GitApi [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: GitApi
-# #endregion EXT:frontend:GitApi
-
-# #region EXT:frontend:GitSettingsPage [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: GitSettingsPage
-# #endregion EXT:frontend:GitSettingsPage
-
-# #region EXT:frontend:LocaleEn [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: LocaleEn
-# #endregion EXT:frontend:LocaleEn
-
-# #region EXT:frontend:LocaleRu [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: LocaleRu
-# #endregion EXT:frontend:LocaleRu
-
-# #region EXT:frontend:MaintenanceEventsTable [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: MaintenanceEventsTable
-# #endregion EXT:frontend:MaintenanceEventsTable
-
-# #region EXT:frontend:MaintenanceServiceModule [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: MaintenanceServiceModule
-# #endregion EXT:frontend:MaintenanceServiceModule
-
-# #region EXT:frontend:MaintenanceSettingsPanel [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: MaintenanceSettingsPanel
-# #endregion EXT:frontend:MaintenanceSettingsPanel
-
-# #region EXT:frontend:PluginLoaderCore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: PluginLoaderCore
-# #endregion EXT:frontend:PluginLoaderCore
-
-# #region EXT:frontend:ProfilePageBindAccountFlowTests [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ProfilePageBindAccountFlowTests
-# #endregion EXT:frontend:ProfilePageBindAccountFlowTests
-
-# #region EXT:frontend:ProtectedRoute [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ProtectedRoute
-# #endregion EXT:frontend:ProtectedRoute
-
-# #region EXT:frontend:ProviderConfigIntegrationTest [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ProviderConfigIntegrationTest
-# #endregion EXT:frontend:ProviderConfigIntegrationTest
-
-# #region EXT:frontend:ReportCard [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ReportCard
-# #endregion EXT:frontend:ReportCard
-
-# #region EXT:frontend:ReportDetailPanel [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ReportDetailPanel
-# #endregion EXT:frontend:ReportDetailPanel
-
-# #region EXT:frontend:ReportModel [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ReportModel
-# #endregion EXT:frontend:ReportModel
-
-# #region EXT:frontend:ReportsList [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: ReportsList
-# #endregion EXT:frontend:ReportsList
-
-# #region EXT:frontend:RepositoryDashboardGrid [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: RepositoryDashboardGrid
-# #endregion EXT:frontend:RepositoryDashboardGrid
-
-# #region EXT:frontend:RoutePages [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: RoutePages
-# #endregion EXT:frontend:RoutePages
-
-# #region EXT:frontend:SessionRepositoryTests [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: SessionRepositoryTests
-# #endregion EXT:frontend:SessionRepositoryTests
-
-# #region EXT:frontend:SettingsUtils [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: SettingsUtils
-# #endregion EXT:frontend:SettingsUtils
-
-# #region EXT:frontend:SidebarNavigation [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: SidebarNavigation
-# #endregion EXT:frontend:SidebarNavigation
-
-# #region EXT:frontend:TaskModel [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TaskModel
-# #endregion EXT:frontend:TaskModel
-
-# #region EXT:frontend:TaskPersistenceService.delete_tasks [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TaskPersistenceService.delete_tasks
-# #endregion EXT:frontend:TaskPersistenceService.delete_tasks
-
-# #region EXT:frontend:TaskPersistenceService.load_tasks [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TaskPersistenceService.load_tasks
-# #endregion EXT:frontend:TaskPersistenceService.load_tasks
-
-# #region EXT:frontend:TaskRunner [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TaskRunner
-# #endregion EXT:frontend:TaskRunner
-
-# #region EXT:frontend:TasksModule [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TasksModule
-# #endregion EXT:frontend:TasksModule
-
-# #region EXT:frontend:TestPolicyResolutionService [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TestPolicyResolutionService
-# #endregion EXT:frontend:TestPolicyResolutionService
-
-# #region EXT:frontend:TestResourceService [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TestResourceService
-# #endregion EXT:frontend:TestResourceService
-
-# #region EXT:frontend:TestScreenshotService [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TestScreenshotService
-# #endregion EXT:frontend:TestScreenshotService
-
-# #region EXT:frontend:TopNavbar [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TopNavbar
-# #endregion EXT:frontend:TopNavbar
-
-# #region EXT:frontend:TypeProfiles [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: TypeProfiles
-# #endregion EXT:frontend:TypeProfiles
-
-# #region EXT:frontend:activity [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: activity
-# #endregion EXT:frontend:activity
-
-# #region EXT:frontend:activityStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: activityStore
-# #endregion EXT:frontend:activityStore
-
-# #region EXT:frontend:addToast [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: addToast
-# #endregion EXT:frontend:addToast
-
-# #region EXT:frontend:api [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: api
-# #endregion EXT:frontend:api
-
-# #region EXT:frontend:api.client [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: api.client
-# #endregion EXT:frontend:api.client
-
-# #region EXT:frontend:api_module [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: api_module
-# #endregion EXT:frontend:api_module
-
-# #region EXT:frontend:assistantChat [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: assistantChat
-# #endregion EXT:frontend:assistantChat
-
-# #region EXT:frontend:assistantChatStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: assistantChatStore
-# #endregion EXT:frontend:assistantChatStore
-
-# #region EXT:frontend:authStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: authStore
-# #endregion EXT:frontend:authStore
-
-# #region EXT:frontend:checkTargetTableSchema [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: checkTargetTableSchema
-# #endregion EXT:frontend:checkTargetTableSchema
-
-# #region EXT:frontend:core_logger [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: core_logger
-# #endregion EXT:frontend:core_logger
-
-# #region EXT:frontend:datasetReviewSession [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: datasetReviewSession
-# #endregion EXT:frontend:datasetReviewSession
-
-# #region EXT:frontend:datasetReviewSessionStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: datasetReviewSessionStore
-# #endregion EXT:frontend:datasetReviewSessionStore
-
-# #region EXT:frontend:dictionaryApi [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: dictionaryApi
-# #endregion EXT:frontend:dictionaryApi
-
-# #region EXT:frontend:environmentContext [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: environmentContext
-# #endregion EXT:frontend:environmentContext
-
-# #region EXT:frontend:environmentContextStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: environmentContextStore
-# #endregion EXT:frontend:environmentContextStore
-
-# #region EXT:frontend:fetchApi [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: fetchApi
-# #endregion EXT:frontend:fetchApi
-
-# #region EXT:frontend:fetchDatabases [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: fetchDatabases
-# #endregion EXT:frontend:fetchDatabases
-
-# #region EXT:frontend:fetchEnvironments [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: fetchEnvironments
-# #endregion EXT:frontend:fetchEnvironments
-
-# #region EXT:frontend:gitService [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: gitService
-# #endregion EXT:frontend:gitService
-
-# #region EXT:frontend:goto [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: goto
-# #endregion EXT:frontend:goto
-
-# #region EXT:frontend:handleUpdate [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: handleUpdate
-# #endregion EXT:frontend:handleUpdate
-
-# #region EXT:frontend:healthStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: healthStore
-# #endregion EXT:frontend:healthStore
-
-# #region EXT:frontend:i18n [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: i18n
-# #endregion EXT:frontend:i18n
-
-# #region EXT:frontend:i18n.profile.lookup_error [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: i18n.profile.lookup_error
-# #endregion EXT:frontend:i18n.profile.lookup_error
-
-# #region EXT:frontend:i18n.t [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: i18n.t
-# #endregion EXT:frontend:i18n.t
-
-# #region EXT:frontend:isProductionContextStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: isProductionContextStore
-# #endregion EXT:frontend:isProductionContextStore
-
-# #region EXT:frontend:migration.mappings.route [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: migration.mappings.route
-# #endregion EXT:frontend:migration.mappings.route
-
-# #region EXT:frontend:models.translate [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: models.translate
-# #endregion EXT:frontend:models.translate
-
-# #region EXT:frontend:normalize_report [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: normalize_report
-# #endregion EXT:frontend:normalize_report
-
-# #region EXT:frontend:orchestrator_lang_stats [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: orchestrator_lang_stats
-# #endregion EXT:frontend:orchestrator_lang_stats
-
-# #region EXT:frontend:policy_resolution_service [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: policy_resolution_service
-# #endregion EXT:frontend:policy_resolution_service
-
-# #region EXT:frontend:repository [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: repository
-# #endregion EXT:frontend:repository
-
-# #region EXT:frontend:requestApi [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: requestApi
-# #endregion EXT:frontend:requestApi
-
-# #region EXT:frontend:selectedEnvironmentStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: selectedEnvironmentStore
-# #endregion EXT:frontend:selectedEnvironmentStore
-
-# #region EXT:frontend:setupTests [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: setupTests
-# #endregion EXT:frontend:setupTests
-
-# #region EXT:frontend:sidebar [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: sidebar
-# #endregion EXT:frontend:sidebar
-
-# #region EXT:frontend:sidebarStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: sidebarStore
-# #endregion EXT:frontend:sidebarStore
-
-# #region EXT:frontend:stores [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: stores
-# #endregion EXT:frontend:stores
-
-# #region EXT:frontend:taskDrawer [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: taskDrawer
-# #endregion EXT:frontend:taskDrawer
-
-# #region EXT:frontend:taskDrawerStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: taskDrawerStore
-# #endregion EXT:frontend:taskDrawerStore
-
-# #region EXT:frontend:taskService [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: taskService
-# #endregion EXT:frontend:taskService
-
-# #region EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: test_dashboard_validation_plugin_persists_task_and_environment_ids
-# #endregion EXT:frontend:test_dashboard_validation_plugin_persists_task_and_environment_ids
-
-# #region EXT:frontend:test_llm_plugin_persistence [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: test_llm_plugin_persistence
-# #endregion EXT:frontend:test_llm_plugin_persistence
-
-# #region EXT:frontend:test_llm_provider [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: test_llm_provider
-# #endregion EXT:frontend:test_llm_provider
-
-# #region EXT:frontend:translationRunStore [C:1] [TYPE External]
-# @BRIEF Frontend store/service/component: translationRunStore
-# #endregion EXT:frontend:translationRunStore
-
-# #region EXT:internal:ASSISTANT_AUDIT [C:1] [TYPE External]
-# @BRIEF Internal module reference: ASSISTANT_AUDIT
-# #endregion EXT:internal:ASSISTANT_AUDIT
-
-# #region EXT:internal:All C4+ service and route modules [C:1] [TYPE External]
-# @BRIEF Internal module reference: All C4+ service and route modules
-# #endregion EXT:internal:All C4+ service and route modules
-
-# #region EXT:internal:All application modules [C:1] [TYPE External]
-# @BRIEF Internal module reference: All application modules
-# #endregion EXT:internal:All application modules
-
-# #region EXT:internal:CONVERSATIONS [C:1] [TYPE External]
-# @BRIEF Internal module reference: CONVERSATIONS
-# #endregion EXT:internal:CONVERSATIONS
-
-# #region EXT:internal:ConnectionContracts [C:1] [TYPE External]
-# @BRIEF Internal module reference: ConnectionContracts
-# #endregion EXT:internal:ConnectionContracts
-
-# #region EXT:internal:CoreContracts [C:1] [TYPE External]
-# @BRIEF Internal module reference: CoreContracts
-# #endregion EXT:internal:CoreContracts
-
-# #region EXT:internal:CotJsonFormat [C:1] [TYPE External]
-# @BRIEF Internal module reference: CotJsonFormat
-# #endregion EXT:internal:CotJsonFormat
-
-# #region EXT:internal:MappingBase [C:1] [TYPE External]
-# @BRIEF Internal module reference: MappingBase
-# #endregion EXT:internal:MappingBase
-
-# #region EXT:internal:MappingModels:Base [C:1] [TYPE External]
-# @BRIEF Internal module reference: MappingModels:Base
-# #endregion EXT:internal:MappingModels:Base
-
-# #region EXT:internal:NavigationContracts [C:1] [TYPE External]
-# @BRIEF Internal module reference: NavigationContracts
-# #endregion EXT:internal:NavigationContracts
-
-# #region EXT:internal:PageContracts [C:1] [TYPE External]
-# @BRIEF Internal module reference: PageContracts
-# #endregion EXT:internal:PageContracts
-
-# #region EXT:internal:Permissions [C:1] [TYPE External]
-# @BRIEF Internal module reference: Permissions
-# #endregion EXT:internal:Permissions
-
-# #region EXT:method:AsyncAPIClient._handle_http_error [C:1] [TYPE External]
-# @BRIEF Method reference: AsyncAPIClient._handle_http_error
-# #endregion EXT:method:AsyncAPIClient._handle_http_error
-
-# #region EXT:method:AsyncAPIClient.request [C:1] [TYPE External]
-# @BRIEF Method reference: AsyncAPIClient.request
-# #endregion EXT:method:AsyncAPIClient.request
-
-# #region EXT:method:BackupPlugin:execute [C:1] [TYPE External]
-# @BRIEF Method reference: BackupPlugin:execute
-# #endregion EXT:method:BackupPlugin:execute
-
-# #region EXT:method:GlobalSettings.app_timezone [C:1] [TYPE External]
-# @BRIEF Method reference: GlobalSettings.app_timezone
-# #endregion EXT:method:GlobalSettings.app_timezone
-
-# #region EXT:method:MappingService:get_suggestions [C:1] [TYPE External]
-# @BRIEF Method reference: MappingService:get_suggestions
-# #endregion EXT:method:MappingService:get_suggestions
-
-# #region EXT:method:MigrationPlugin:execute [C:1] [TYPE External]
-# @BRIEF Method reference: MigrationPlugin:execute
-# #endregion EXT:method:MigrationPlugin:execute
-
-# #region EXT:method:SessionEventLogger.log_event [C:1] [TYPE External]
-# @BRIEF Method reference: SessionEventLogger.log_event
-# #endregion EXT:method:SessionEventLogger.log_event
-
-# #region EXT:method:SupersetClient.compile_dataset_preview [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetClient.compile_dataset_preview
-# #endregion EXT:method:SupersetClient.compile_dataset_preview
-
-# #region EXT:method:SupersetClient.get_dashboard [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetClient.get_dashboard
-# #endregion EXT:method:SupersetClient.get_dashboard
-
-# #region EXT:method:SupersetClient.get_dashboard_detail [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetClient.get_dashboard_detail
-# #endregion EXT:method:SupersetClient.get_dashboard_detail
-
-# #region EXT:method:SupersetClient.get_dashboards_summary [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetClient.get_dashboards_summary
-# #endregion EXT:method:SupersetClient.get_dashboards_summary
-
-# #region EXT:method:SupersetClient.get_dataset [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetClient.get_dataset
-# #endregion EXT:method:SupersetClient.get_dataset
-
-# #region EXT:method:SupersetClient.update_dataset [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetClient.update_dataset
-# #endregion EXT:method:SupersetClient.update_dataset
-
-# #region EXT:method:SupersetContextExtractor.parse_superset_link [C:1] [TYPE External]
-# @BRIEF Method reference: SupersetContextExtractor.parse_superset_link
-# #endregion EXT:method:SupersetContextExtractor.parse_superset_link
-
-# #region EXT:method:TASK_TYPE_PLUGIN_MAP [C:1] [TYPE External]
-# @BRIEF Method reference: TASK_TYPE_PLUGIN_MAP
-# #endregion EXT:method:TASK_TYPE_PLUGIN_MAP
-
-# #region EXT:method:TaskLogPersistenceService.add_logs [C:1] [TYPE External]
-# @BRIEF Method reference: TaskLogPersistenceService.add_logs
-# #endregion EXT:method:TaskLogPersistenceService.add_logs
-
-# #region EXT:method:TaskLogPersistenceService.delete_logs_for_tasks [C:1] [TYPE External]
-# @BRIEF Method reference: TaskLogPersistenceService.delete_logs_for_tasks
-# #endregion EXT:method:TaskLogPersistenceService.delete_logs_for_tasks
-
-# #region EXT:method:TaskLogPersistenceService.get_log_stats [C:1] [TYPE External]
-# @BRIEF Method reference: TaskLogPersistenceService.get_log_stats
-# #endregion EXT:method:TaskLogPersistenceService.get_log_stats
-
-# #region EXT:method:TaskLogPersistenceService.get_logs [C:1] [TYPE External]
-# @BRIEF Method reference: TaskLogPersistenceService.get_logs
-# #endregion EXT:method:TaskLogPersistenceService.get_logs
-
-# #region EXT:method:TaskLogPersistenceService.get_sources [C:1] [TYPE External]
-# @BRIEF Method reference: TaskLogPersistenceService.get_sources
-# #endregion EXT:method:TaskLogPersistenceService.get_sources
-
-# #region EXT:method:TaskManager.create_task [C:1] [TYPE External]
-# @BRIEF Method reference: TaskManager.create_task
-# #endregion EXT:method:TaskManager.create_task
-
-# #region EXT:method:TranslationExecutor._auto_size_batches [C:1] [TYPE External]
-# @BRIEF Method reference: TranslationExecutor._auto_size_batches
-# #endregion EXT:method:TranslationExecutor._auto_size_batches
-
-# #region EXT:method:_build_body [C:1] [TYPE External]
-# @BRIEF Method reference: _build_body
-# #endregion EXT:method:_build_body
-
-# #region EXT:method:_extract_resource_name_from_task [C:1] [TYPE External]
-# @BRIEF Method reference: _extract_resource_name_from_task
-# #endregion EXT:method:_extract_resource_name_from_task
-
-# #region EXT:method:_extract_resource_type_from_task [C:1] [TYPE External]
-# @BRIEF Method reference: _extract_resource_type_from_task
-# #endregion EXT:method:_extract_resource_type_from_task
-
-# #region EXT:method:_find_dashboard_owners [C:1] [TYPE External]
-# @BRIEF Method reference: _find_dashboard_owners
-# #endregion EXT:method:_find_dashboard_owners
-
-# #region EXT:method:_get_git_status_for_dashboard [C:1] [TYPE External]
-# @BRIEF Method reference: _get_git_status_for_dashboard
-# #endregion EXT:method:_get_git_status_for_dashboard
-
-# #region EXT:method:_get_last_llm_task_for_dashboard [C:1] [TYPE External]
-# @BRIEF Method reference: _get_last_llm_task_for_dashboard
-# #endregion EXT:method:_get_last_llm_task_for_dashboard
-
-# #region EXT:method:_get_last_task_for_resource [C:1] [TYPE External]
-# @BRIEF Method reference: _get_last_task_for_resource
-# #endregion EXT:method:_get_last_task_for_resource
-
-# #region EXT:method:_initialize_providers [C:1] [TYPE External]
-# @BRIEF Method reference: _initialize_providers
-# #endregion EXT:method:_initialize_providers
-
-# #region EXT:method:_llm_http [C:1] [TYPE External]
-# @BRIEF Method reference: _llm_http
-# #endregion EXT:method:_llm_http
-
-# #region EXT:method:_normalize_datetime_for_compare [C:1] [TYPE External]
-# @BRIEF Method reference: _normalize_datetime_for_compare
-# #endregion EXT:method:_normalize_datetime_for_compare
-
-# #region EXT:method:_normalize_task_status [C:1] [TYPE External]
-# @BRIEF Method reference: _normalize_task_status
-# #endregion EXT:method:_normalize_task_status
-
-# #region EXT:method:_normalize_validation_status [C:1] [TYPE External]
-# @BRIEF Method reference: _normalize_validation_status
-# #endregion EXT:method:_normalize_validation_status
-
-# #region EXT:method:_prime_dashboard_meta_cache [C:1] [TYPE External]
-# @BRIEF Method reference: _prime_dashboard_meta_cache
-# #endregion EXT:method:_prime_dashboard_meta_cache
-
-# #region EXT:method:_resolve_dashboard_meta [C:1] [TYPE External]
-# @BRIEF Method reference: _resolve_dashboard_meta
-# #endregion EXT:method:_resolve_dashboard_meta
-
-# #region EXT:method:_resolve_targets [C:1] [TYPE External]
-# @BRIEF Method reference: _resolve_targets
-# #endregion EXT:method:_resolve_targets
-
-# #region EXT:method:_should_notify [C:1] [TYPE External]
-# @BRIEF Method reference: _should_notify
-# #endregion EXT:method:_should_notify
-
-# #region EXT:method:decrypt [C:1] [TYPE External]
-# @BRIEF Method reference: decrypt
-# #endregion EXT:method:decrypt
-
-# #region EXT:method:encrypt [C:1] [TYPE External]
-# @BRIEF Method reference: encrypt
-# #endregion EXT:method:encrypt
-
-# #region EXT:method:get_activity_summary [C:1] [TYPE External]
-# @BRIEF Method reference: get_activity_summary
-# #endregion EXT:method:get_activity_summary
-
-# #region EXT:method:get_dashboards_with_status [C:1] [TYPE External]
-# @BRIEF Method reference: get_dashboards_with_status
-# #endregion EXT:method:get_dashboards_with_status
-
-# #region EXT:method:get_datasets_with_status [C:1] [TYPE External]
-# @BRIEF Method reference: get_datasets_with_status
-# #endregion EXT:method:get_datasets_with_status
-
-# #region EXT:method:get_repo [C:1] [TYPE External]
-# @BRIEF Method reference: get_repo
-# #endregion EXT:method:get_repo
-
-# #region EXT:method:schemas.translate.TargetSchemaValidationRequest [C:1] [TYPE External]
-# @BRIEF Method reference: schemas.translate.TargetSchemaValidationRequest
-# #endregion EXT:method:schemas.translate.TargetSchemaValidationRequest
-
-# #region EXT:method:schemas.translate.TargetSchemaValidationResponse [C:1] [TYPE External]
-# @BRIEF Method reference: schemas.translate.TargetSchemaValidationResponse
-# #endregion EXT:method:schemas.translate.TargetSchemaValidationResponse
-
-# #region EXT:method:self.network.request [C:1] [TYPE External]
-# @BRIEF Method reference: self.network.request
-# #endregion EXT:method:self.network.request
-
-# #region EXT:module:TargetName [C:1] [TYPE External]
-# @BRIEF External reference: TargetName
-# #endregion EXT:module:TargetName
-
-# #region EXT:path:EnvSelector.svelte [C:1] [TYPE External]
-# @BRIEF File path: EnvSelector.svelte
-# #endregion EXT:path:EnvSelector.svelte
-
-# #region EXT:path:MappingTable.svelte [C:1] [TYPE External]
-# @BRIEF File path: MappingTable.svelte
-# #endregion EXT:path:MappingTable.svelte
-
-# #region EXT:path:backend/requirements.txt [C:1] [TYPE External]
-# @BRIEF File path: backend/requirements.txt
-# #endregion EXT:path:backend/requirements.txt
-
-# #region EXT:path:docker/backend.entrypoint.sh [C:1] [TYPE External]
-# @BRIEF File path: docker/backend.entrypoint.sh
-# #endregion EXT:path:docker/backend.entrypoint.sh
-
-# #region EXT:path:docker/frontend.entrypoint.sh [C:1] [TYPE External]
-# @BRIEF File path: docker/frontend.entrypoint.sh
-# #endregion EXT:path:docker/frontend.entrypoint.sh
-
-# #region EXT:path:docker/nginx.conf [C:1] [TYPE External]
-# @BRIEF File path: docker/nginx.conf
-# #endregion EXT:path:docker/nginx.conf
-
-# #region EXT:path:docker/nginx.ssl.conf [C:1] [TYPE External]
-# @BRIEF File path: docker/nginx.ssl.conf
-# #endregion EXT:path:docker/nginx.ssl.conf
-
-# #region EXT:path:frontend/package.json [C:1] [TYPE External]
-# @BRIEF File path: frontend/package.json
-# #endregion EXT:path:frontend/package.json
-
-# #region EXT:path:frontend/src/components/EnvSelector.svelte [C:1] [TYPE External]
-# @BRIEF File path: frontend/src/components/EnvSelector.svelte
-# #endregion EXT:path:frontend/src/components/EnvSelector.svelte
-
-# #region EXT:path:frontend/src/components/MappingTable.svelte [C:1] [TYPE External]
-# @BRIEF File path: frontend/src/components/MappingTable.svelte
-# #endregion EXT:path:frontend/src/components/MappingTable.svelte
-
-# #region EXT:path:frontend/src/components/PasswordPrompt.svelte [C:1] [TYPE External]
-# @BRIEF File path: frontend/src/components/PasswordPrompt.svelte
-# #endregion EXT:path:frontend/src/components/PasswordPrompt.svelte
-
-# #region EXT:path:frontend/src/components/TaskHistory.svelte [C:1] [TYPE External]
-# @BRIEF File path: frontend/src/components/TaskHistory.svelte
-# #endregion EXT:path:frontend/src/components/TaskHistory.svelte
-
-# #region EXT:path:frontend/src/lib/api.js [C:1] [TYPE External]
-# @BRIEF File path: frontend/src/lib/api.js
-# #endregion EXT:path:frontend/src/lib/api.js
-
-# #region EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES [C:1] [TYPE External]
-# @BRIEF External reference: SUPPORTED_DENSITIES
-# #endregion EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES
-
-# #region EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES [C:1] [TYPE External]
-# @BRIEF External reference: SUPPORTED_START_PAGES
-# #endregion EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES
-
-# #region EXT:requests [C:1] [TYPE External]
-# @BRIEF External reference: requests
-# #endregion EXT:requests
-
-# #region EXT:spec:BulkReplaceModal:Component [C:1] [TYPE External]
-# @BRIEF Spec/design-time contract: BulkReplaceModal:Component
-# #endregion EXT:spec:BulkReplaceModal:Component
-
-# #region EXT:spec:CorrectionCell:Component [C:1] [TYPE External]
-# @BRIEF Spec/design-time contract: CorrectionCell:Component
-# #endregion EXT:spec:CorrectionCell:Component
-
-# #region EXT:spec:StatsBar:Component [C:1] [TYPE External]
-# @BRIEF Spec/design-time contract: StatsBar:Component
-# #endregion EXT:spec:StatsBar:Component
-
-# #region EXT:spec:TargetSchemaHint:Component [C:1] [TYPE External]
-# @BRIEF Spec/design-time contract: TargetSchemaHint:Component
-# #endregion EXT:spec:TargetSchemaHint:Component
-
-# #region EXT:spec:TranslationPreview:Component [C:1] [TYPE External]
-# @BRIEF Spec/design-time contract: TranslationPreview:Component
-# #endregion EXT:spec:TranslationPreview:Component
-
-# #region EXT:ss-tools:log_security_event [C:1] [TYPE External]
-# @BRIEF External reference: log_security_event
-# #endregion EXT:ss-tools:log_security_event
-
-# #region EXT:sveltekit:$app/environment [C:1] [TYPE External]
-# @BRIEF SvelteKit import: $app/environment
-# #endregion EXT:sveltekit:$app/environment
-
-# #region EXT:sveltekit:$app/navigation [C:1] [TYPE External]
-# @BRIEF SvelteKit import: $app/navigation
-# #endregion EXT:sveltekit:$app/navigation
-
-# #region EXT:sveltekit:$app/stores [C:1] [TYPE External]
-# @BRIEF SvelteKit import: $app/stores
-# #endregion EXT:sveltekit:$app/stores
-
-# #region EXT:sveltekit:$env/static/public [C:1] [TYPE External]
-# @BRIEF SvelteKit import: $env/static/public
-# #endregion EXT:sveltekit:$env/static/public
-
-# #endregion ExternalStubs
-# #region EXT:list:GitDashboardPage_GitConfigRoutes [C:1] [TYPE External]
-# @BRIEF E2E test list target: GitDashboardPage, GitConfigRoutes
-# #endregion EXT:list:GitDashboardPage_GitConfigRoutes
-
-# #region EXT:list:MigrationApi_SettingsPage [C:1] [TYPE External]
-# @BRIEF E2E test list target: MigrationApi, SettingsPage
-# #endregion EXT:list:MigrationApi_SettingsPage
-
-# #region EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig [C:1] [TYPE External]
-# @BRIEF E2E test list target: LoginPage, SettingsPage, TranslateJob, GitConfig
-# #endregion EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig
-
-# #region EXT:list:TranslatePage_TranslateJobRoutes [C:1] [TYPE External]
-# @BRIEF E2E test list target: TranslatePage, TranslateJobRoutes
-# #endregion EXT:list:TranslatePage_TranslateJobRoutes
-
-# #region EXT:list:DashboardHub_LLM_SettingsPage [C:1] [TYPE External]
-# @BRIEF E2E test list target: DashboardHub, LLM, SettingsPage
-# #endregion EXT:list:DashboardHub_LLM_SettingsPage
-
-# #region EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab [C:1] [TYPE External]
-# @BRIEF E2E test list target: StartupEnvironmentWizard, LoginPage, EnvironmentsTab
-# #endregion EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab
-
-# #region EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge [C:1] [TYPE External]
-# @BRIEF Test filter state references
-# #endregion EXT:list:FilterState_ParsedNativeFilters_ExtraFormDataMerge
-
-# #region EXT:list:MigrationEngine_internal_methods [C:1] [TYPE External]
-# @BRIEF MigrationEngine internal method references
-# #endregion EXT:list:MigrationEngine_internal_methods
-
-# #region EXT:list:MigrateEngine_transform_methods [C:1] [TYPE External]
-# @BRIEF MigrationEngine transform method references
-# #endregion EXT:list:MigrateEngine_transform_methods
-
-# #region EXT:list:GitPackage_all_routes [C:1] [TYPE External]
-# @BRIEF Git package all route references
-# #endregion EXT:list:GitPackage_all_routes
-
-# #region EXT:internal:_text_cleaner [C:1] [TYPE External]
-# @BRIEF Test module reference: _text_cleaner
-# #endregion EXT:internal:_text_cleaner
-
-# #region EXT:internal:_utils [C:1] [TYPE External]
-# @BRIEF Test module reference: _utils
-# #endregion EXT:internal:_utils
-
-# #region EXT:internal:test_health_service [C:1] [TYPE External]
-# @BRIEF Test self-reference: test_health_service
-# #endregion EXT:internal:test_health_service
-
-# #region EXT:internal:re_sqlparse [C:1] [TYPE External]
-# @BRIEF Internal: re and sqlparse
-# #endregion EXT:internal:re_sqlparse
-
-# #region EXT:method:ValidationApi.fetchTasks [C:1] [TYPE External]
-# @BRIEF Method reference: ValidationApi.fetchTasks
-# #endregion EXT:method:ValidationApi.fetchTasks
-
-# #region EXT:frontend:ReportTypeProfiles [C:1] [TYPE External]
-# @BRIEF Frontend: ReportTypeProfiles
-# #endregion EXT:frontend:ReportTypeProfiles
-
-# #region EXT:frontend:AssistantChatTest [C:1] [TYPE External]
-# @BRIEF Frontend: AssistantChatTest
-# #endregion EXT:frontend:AssistantChatTest
-
-# #region EXT:frontend:DashboardDetailPage [C:1] [TYPE External]
-# @BRIEF Frontend: DashboardDetailPage
-# #endregion EXT:frontend:DashboardDetailPage
-
-# #region EXT:frontend:DashboardRouter [C:1] [TYPE External]
-# @BRIEF Frontend: DashboardRouter
-# #endregion EXT:frontend:DashboardRouter
-
-# #region EXT:frontend:EnvConfig [C:1] [TYPE External]
-# @BRIEF Frontend: EnvConfig
-# #endregion EXT:frontend:EnvConfig
-
-# #region EXT:frontend:App [C:1] [TYPE External]
-# @BRIEF Frontend module: App
-# #endregion EXT:frontend:App
-
-# #region EXT:frontend:Utils [C:1] [TYPE External]
-# @BRIEF Frontend utility module: Utils
-# #endregion EXT:frontend:Utils
-
-# #region EXT:frontend:AuthService [C:1] [TYPE External]
-# @BRIEF Frontend: AuthService
-# #endregion EXT:frontend:AuthService
-
-# #region EXT:frontend:Navbar [C:1] [TYPE External]
-# @BRIEF Frontend component: Navbar
-# #endregion EXT:frontend:Navbar
-
-# #region EXT:frontend:ValidationPolicy [C:1] [TYPE External]
-# @BRIEF Frontend: ValidationPolicy
-# #endregion EXT:frontend:ValidationPolicy
-
-# #region EXT:frontend:Select [C:1] [TYPE External]
-# @BRIEF Frontend component: Select
-# #endregion EXT:frontend:Select
-
-# #region EXT:frontend:AssistantApi [C:1] [TYPE External]
-# @BRIEF Frontend: AssistantApi
-# #endregion EXT:frontend:AssistantApi
-
-# #region EXT:frontend:DatasetReviewApi [C:1] [TYPE External]
-# @BRIEF Frontend: DatasetReviewApi
-# #endregion EXT:frontend:DatasetReviewApi
-
-# #region EXT:frontend:DatasetReviewWorkspace [C:1] [TYPE External]
-# @BRIEF Frontend: DatasetReviewWorkspace
-# #endregion EXT:frontend:DatasetReviewWorkspace
-
-# #region EXT:frontend:auth [C:1] [TYPE External]
-# @BRIEF Frontend: auth
-# #endregion EXT:frontend:auth
-
-# #region EXT:Library:OAuth [C:1] [TYPE External]
-# @BRIEF External library: OAuth
-# #endregion EXT:Library:OAuth
-
-# #region EXT:frontend:adminService [C:1] [TYPE External]
-# @BRIEF Frontend service: adminService
-# #endregion EXT:frontend:adminService
-
-# #region EXT:path:backend.src.api.routes.migration [C:1] [TYPE External]
-# @BRIEF Backend API route: migration
-# #endregion EXT:path:backend.src.api.routes.migration
-
-# #region EXT:path:backend.src.core.plugin_base.PluginBase [C:1] [TYPE External]
-# @BRIEF Backend core: PluginBase
-# #endregion EXT:path:backend.src.core.plugin_base.PluginBase
-
-# #region EXT:path:backend.src.models.clean_release [C:1] [TYPE External]
-# @BRIEF Backend model: clean_release
-# #endregion EXT:path:backend.src.models.clean_release
-
-# #region EXT:path:backend.src.models.git [C:1] [TYPE External]
-# @BRIEF Backend model: git
-# #endregion EXT:path:backend.src.models.git
-
-# #region EXT:path:backend.src.models.report [C:1] [TYPE External]
-# @BRIEF Backend model: report
-# #endregion EXT:path:backend.src.models.report
-
-# #region EXT:path:backend.api.storage [C:1] [TYPE External]
-# @BRIEF Backend API: storage
-# #endregion EXT:path:backend.api.storage
-
-# #region EXT:path:backend.src.services.clean_release.demo_data_service [C:1] [TYPE External]
-# @BRIEF Backend service: demo_data_service
-# #endregion EXT:path:backend.src.services.clean_release.demo_data_service
-
-# #region EXT:path:backend.src.services.clean_release.repository [C:1] [TYPE External]
-# @BRIEF Backend service: clean_release repository
-# #endregion EXT:path:backend.src.services.clean_release.repository
-
-# #region EXT:path:backend.src.services.health_service.HealthService [C:1] [TYPE External]
-# @BRIEF Backend service: HealthService
-# #endregion EXT:path:backend.src.services.health_service.HealthService
-
-# #region EXT:path:backend.src.api.routes.admin.create_user [C:1] [TYPE External]
-# @BRIEF Backend API route: admin.create_user
-# #endregion EXT:path:backend.src.api.routes.admin.create_user
-
-# #region EXT:path:backend.src.api.routes.admin.list_roles [C:1] [TYPE External]
-# @BRIEF Backend API route: admin.list_roles
-# #endregion EXT:path:backend.src.api.routes.admin.list_roles
-
-# #region EXT:path:backend.src.api.routes.admin.list_users [C:1] [TYPE External]
-# @BRIEF Backend API route: admin.list_users
-# #endregion EXT:path:backend.src.api.routes.admin.list_users
-
-# #region EXT:path:backend.src.api.routes.settings.get_logging_config [C:1] [TYPE External]
-# @BRIEF Backend API route: settings.get_logging_config
-# #endregion EXT:path:backend.src.api.routes.settings.get_logging_config
-
-# #region EXT:path:backend.src.api.routes.settings.update_logging_config [C:1] [TYPE External]
-# @BRIEF Backend API route: settings.update_logging_config
-# #endregion EXT:path:backend.src.api.routes.settings.update_logging_config
-
-# #region EXT:path:backend/src/plugins/llm_analysis/plugin.py [C:1] [TYPE External]
-# @BRIEF Backend plugin path: llm_analysis/plugin.py
-# #endregion EXT:path:backend/src/plugins/llm_analysis/plugin.py
-
-# #region EXT:path:frontend/src/lib/api.js (inferred) [C:1] [TYPE External]
-# @BRIEF Frontend lib path: api.js
-# #endregion EXT:path:frontend/src/lib/api.js (inferred)
-
-# #region EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte [C:1] [TYPE External]
-# @BRIEF Frontend route path
-# #endregion EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte
-
-# #region EXT:path:frontend/src/services/toolsService.js [C:1] [TYPE External]
-# @BRIEF Frontend service path: toolsService.js
-# #endregion EXT:path:frontend/src/services/toolsService.js
-
-# #region EXT:path:frontend/src/lib/i18n/index.ts [key [C:1] [TYPE External]
-# @BRIEF Frontend i18n path
-# #endregion EXT:path:frontend/src/lib/i18n/index.ts [key
-
-# #region EXT:path:../task_logger.py [C:1] [TYPE External]
-# @BRIEF Relative path: task_logger.py
-# #endregion EXT:path:../task_logger.py
-
-# #region EXT:path:/tools/storage [C:1] [TYPE External]
-# @BRIEF Path: /tools/storage
-# #endregion EXT:path:/tools/storage
-
-# #region EXT:path:src/core/logger.py [C:1] [TYPE External]
-# @BRIEF Path: src/core/logger.py
-# #endregion EXT:path:src/core/logger.py
-
-# #region EXT:path:src.core.logger [C:1] [TYPE External]
-# @BRIEF Path: src.core.logger
-# #endregion EXT:path:src.core.logger
-
-# #region EXT:path:src.core.plugin_base.PluginBase [C:1] [TYPE External]
-# @BRIEF Path: src.core.plugin_base.PluginBase
-# #endregion EXT:path:src.core.plugin_base.PluginBase
-
-# #region EXT:frontend:GitServiceClient [C:1] [TYPE External]
-# @BRIEF Frontend: GitServiceClient
-# #endregion EXT:frontend:GitServiceClient
-
-# #region EXT:Library:sqlalchemy.Session [C:1] [TYPE External]
-# @BRIEF External library: sqlalchemy.Session
-# #endregion EXT:Library:sqlalchemy.Session
-
-# #region EXT:internal:OAuth [C:1] [TYPE External]
-# @BRIEF Internal: OAuth
-# #endregion EXT:internal:OAuth
-
-# #region EXT:desc:Used by PluginLoad [C:1] [TYPE External]
-# @BRIEF Descriptive: PluginLoader
-# #endregion EXT:desc:Used by PluginLoad
-
-# #region EXT:desc:Instantiated by Plu [C:1] [TYPE External]
-# @BRIEF Descriptive: PluginConfig
-# #endregion EXT:desc:Instantiated by Plu
-
-# #region EXT:desc:Depends on PluginBa [C:1] [TYPE External]
-# @BRIEF Descriptive: PluginLoader
-# #endregion EXT:desc:Depends on PluginBa
-
-# #region EXT:desc:Used by main app an [C:1] [TYPE External]
-# @BRIEF Descriptive: AppDependencies
-# #endregion EXT:desc:Used by main app an
-
-# #region EXT:desc:Inherits from Plugi [C:1] [TYPE External]
-# @BRIEF Descriptive: PluginBase uses SupersetClient
-# #endregion EXT:desc:Inherits from Plugi
-
-# #region EXT:desc:Inherits from Plugi [C:1] [TYPE External]
-# @BRIEF Descriptive: PluginBase uses DatasetMapper
-# #endregion EXT:desc:Inherits from Plugi
-
-# #region EXT:code:has_permission("admin:settings", "WRITE") [C:1] [TYPE External]
-# @BRIEF Permission check expression
-# #endregion EXT:code:has_permission("admin:settings", "WRITE")
-
-# #region EXT:code:has_permission("maintenance", "READ") [C:1] [TYPE External]
-# @BRIEF Permission check expression
-# #endregion EXT:code:has_permission("maintenance", "READ")
-
-# #region EXT:code:has_permission("maintenance", "WRITE") [C:1] [TYPE External]
-# @BRIEF Permission check expression
-# #endregion EXT:code:has_permission("maintenance", "WRITE")
-
-# #region EXT:frontend:BackupManager [C:1] [TYPE External]
-# @BRIEF Frontend component: BackupManager
-# #endregion EXT:frontend:BackupManager
-
-# #region EXT:frontend:DebugTool [C:1] [TYPE External]
-# @BRIEF Frontend component: DebugTool
-# #endregion EXT:frontend:DebugTool
-
-# #region EXT:frontend:toasts [C:1] [TYPE External]
-# @BRIEF Frontend store: toasts
-# #endregion EXT:frontend:toasts
-
-# #region EXT:frontend:onresume [C:1] [TYPE External]
-# @BRIEF Frontend event: onresume
-# #endregion EXT:frontend:onresume
-
-# #region EXT:frontend:oncancel [C:1] [TYPE External]
-# @BRIEF Frontend event: oncancel
-# #endregion EXT:frontend:oncancel
-
-# #region EXT:frontend:onresolve [C:1] [TYPE External]
-# @BRIEF Frontend event: onresolve
-# #endregion EXT:frontend:onresolve
-
-# #region EXT:frontend:api.js [C:1] [TYPE External]
-# @BRIEF Frontend module: api.js
-# #endregion EXT:frontend:api.js
-
-# #region EXT:frontend:i18n.locale [C:1] [TYPE External]
-# @BRIEF Frontend store: i18n.locale
-# #endregion EXT:frontend:i18n.locale
-
-# #region EXT:frontend:DashboardMaintenanceBadge [C:1] [TYPE External]
-# @BRIEF Frontend component: DashboardMaintenanceBadge
-# #endregion EXT:frontend:DashboardMaintenanceBadge
-
-# #region EXT:frontend:locale [C:1] [TYPE External]
-# @BRIEF Frontend store: locale
-# #endregion EXT:frontend:locale
-
-# #region EXT:frontend:TaskDrawer [C:1] [TYPE External]
-# @BRIEF Frontend component: TaskDrawer
-# #endregion EXT:frontend:TaskDrawer
-
-# #region EXT:Library:superset_tool.client [C:1] [TYPE External]
-# @BRIEF External library: superset_tool.client
-# #endregion EXT:Library:superset_tool.client
-
-# #region EXT:Library:superset_tool.utils [C:1] [TYPE External]
-# @BRIEF External library: superset_tool.utils
-# #endregion EXT:Library:superset_tool.utils
-
-# #region EXT:Library:pandas [C:1] [TYPE External]
-# @BRIEF External library: pandas
-# #endregion EXT:Library:pandas
-
-# #region EXT:Library:bcrypt [C:1] [TYPE External]
-# @BRIEF External library: bcrypt
-# #endregion EXT:Library:bcrypt
-
-# #region EXT:Library:rapidfuzz [C:1] [TYPE External]
-# @BRIEF External library: rapidfuzz
-# #endregion EXT:Library:rapidfuzz
-
-# #region EXT:Library:tenacity [C:1] [TYPE External]
-# @BRIEF External library: tenacity
-# #endregion EXT:Library:tenacity
-
-# #region EXT:Library:OAuth2PasswordBearer [C:1] [TYPE External]
-# @BRIEF External library: OAuth2PasswordBearer
-# #endregion EXT:Library:OAuth2PasswordBearer
-
-# #region EXT:Library:pydantic_settings.BaseSettings [C:1] [TYPE External]
-# @BRIEF External library: pydantic_settings.BaseSettings
-# #endregion EXT:Library:pydantic_settings.BaseSettings
-
-# #region EXT:Python:enum [C:1] [TYPE External]
-# @BRIEF Python standard library: enum
-# #endregion EXT:Python:enum
-
-# #region EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte [C:1] [TYPE External]
-# @BRIEF File path: frontend report page
-# #endregion EXT:path:frontend/src/routes/reports/llm/[taskId]/+page.svelte
-
-# #region EXT:path:frontend/src/lib/i18n/index.ts [key [C:1] [TYPE External]
-# @BRIEF File path: i18n index.ts
-# #endregion EXT:path:frontend/src/lib/i18n/index.ts [key
-
-# #region EXT:frontend:i18n_ru_locale [C:1] [TYPE External]
-# @BRIEF Frontend: i18n_ru_locale
-# #endregion EXT:frontend:i18n_ru_locale
-
-# #region EXT:frontend:i18n_en_locale [C:1] [TYPE External]
-# @BRIEF Frontend: i18n_en_locale
-# #endregion EXT:frontend:i18n_en_locale
-
-# #region EXT:method:adminService.createADGroupMapping [C:1] [TYPE External]
-# @BRIEF Method reference: adminService.createADGroupMapping
-# #endregion EXT:method:adminService.createADGroupMapping
-
-# #region EXT:method:adminService.getLoggingConfig [C:1] [TYPE External]
-# @BRIEF Method reference: adminService.getLoggingConfig
-# #endregion EXT:method:adminService.getLoggingConfig
-
-# #region EXT:method:adminService.updateLoggingConfig [C:1] [TYPE External]
-# @BRIEF Method reference: adminService.updateLoggingConfig
-# #endregion EXT:method:adminService.updateLoggingConfig
-
-# #region EXT:method:adminService.deleteUser [C:1] [TYPE External]
-# @BRIEF Method reference: adminService.deleteUser
-# #endregion EXT:method:adminService.deleteUser
-
-# #region EXT:method:adminService.createUser [C:1] [TYPE External]
-# @BRIEF Method reference: adminService.createUser
-# #endregion EXT:method:adminService.createUser
-
-# #region EXT:method:adminService.updateUser [C:1] [TYPE External]
-# @BRIEF Method reference: adminService.updateUser
-# #endregion EXT:method:adminService.updateUser
-
-# #region EXT:method:DatasetMapper.get_sqllab_mappings [C:1] [TYPE External]
-# @BRIEF Method reference: DatasetMapper.get_sqllab_mappings
-# #endregion EXT:method:DatasetMapper.get_sqllab_mappings
-
-# #region EXT:method:DatasetMapper.load_excel_mappings [C:1] [TYPE External]
-# @BRIEF Method reference: DatasetMapper.load_excel_mappings
-# #endregion EXT:method:DatasetMapper.load_excel_mappings
diff --git a/backend/src/schemas/validation.py b/backend/src/schemas/validation.py
index bdd8ea66..6fecbc94 100644
--- a/backend/src/schemas/validation.py
+++ b/backend/src/schemas/validation.py
@@ -90,6 +90,7 @@ class ValidationRunResponse(BaseModel):
timestamp: datetime | None = None
screenshot_path: str | None = None
task_name: str | None = None # resolved from ValidationPolicy at query time
+ issues_count: int = 0 # number of issues found during validation
class Config:
from_attributes = True
diff --git a/backend/src/services/__tests__/test_health_service.py b/backend/src/services/__tests__/test_health_service.py
index f2b4e628..211c3e78 100644
--- a/backend/src/services/__tests__/test_health_service.py
+++ b/backend/src/services/__tests__/test_health_service.py
@@ -5,7 +5,7 @@ from unittest.mock import MagicMock, patch
from src.models.llm import ValidationRecord
from src.services.health_service import HealthService
-# region [EXT:internal:test_health_service] [TYPE Module]
+# region test_health_service] [TYPE Module]
# @PURPOSE: Unit tests for HealthService aggregation logic.
# @RELATION BINDS_TO ->[HealthService]
@@ -163,7 +163,7 @@ async def test_get_health_summary_reuses_dashboard_metadata_cache_across_service
# region test_delete_validation_report_deletes_dashboard_scope_and_linked_tasks [TYPE Function]
-# @RELATION BINDS_TO ->[[EXT:internal:test_health_service]]
+# @RELATION BINDS_TO -> [HealthService]
# @PURPOSE: Verify that deleting a validation report also removes dashboard scope and linked tasks.
def test_delete_validation_report_deletes_dashboard_scope_and_linked_tasks():
db = MagicMock()
@@ -239,7 +239,7 @@ def test_delete_validation_report_deletes_dashboard_scope_and_linked_tasks():
# region test_delete_validation_report_returns_false_for_unknown_record [TYPE Function]
-# @RELATION BINDS_TO ->[[EXT:internal:test_health_service]]
+# @RELATION BINDS_TO -> [HealthService]
# @PURPOSE: Verify delete returns False when validation record does not exist.
def test_delete_validation_report_returns_false_for_unknown_record():
db = MagicMock()
@@ -254,7 +254,7 @@ def test_delete_validation_report_returns_false_for_unknown_record():
# region test_delete_validation_report_swallows_linked_task_cleanup_failure [TYPE Function]
-# @RELATION BINDS_TO ->[[EXT:internal:test_health_service]]
+# @RELATION BINDS_TO -> [HealthService]
# @PURPOSE: Verify delete swallows exceptions when cleaning up linked tasks.
def test_delete_validation_report_swallows_linked_task_cleanup_failure():
db = MagicMock()
@@ -306,4 +306,4 @@ def test_delete_validation_report_swallows_linked_task_cleanup_failure():
# endregion test_delete_validation_report_swallows_linked_task_cleanup_failure
-# endregion [EXT:internal:test_health_service]
+# endregion test_health_service]
diff --git a/backend/src/services/clean_release/candidate_service.py b/backend/src/services/clean_release/candidate_service.py
index 8cf58f53..79fa281f 100644
--- a/backend/src/services/clean_release/candidate_service.py
+++ b/backend/src/services/clean_release/candidate_service.py
@@ -1,8 +1,8 @@
# #region candidate_service [C:5] [TYPE Module] [SEMANTICS pydantic, clean-release, candidate, lifecycle, release]
# @BRIEF Register release candidates with validated artifacts and advance lifecycle through legal transitions.
# @LAYER Domain
-# @RELATION DEPENDS_ON -> [EXT:path:backend.src.services.clean_release.repository]
-# @RELATION DEPENDS_ON -> [EXT:path:backend.src.models.clean_release]
+# @RELATION DEPENDS_ON -> [CleanReleaseRepository]
+# @RELATION DEPENDS_ON -> [CleanReleaseModels]
# @PRE candidate_id must be unique; artifacts input must be non-empty and valid.
# @POST candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.
# @INVARIANT Candidate lifecycle transitions are delegated to domain guard logic.
diff --git a/backend/src/services/profile_preference_service.py b/backend/src/services/profile_preference_service.py
index d856850a..3031844e 100644
--- a/backend/src/services/profile_preference_service.py
+++ b/backend/src/services/profile_preference_service.py
@@ -4,7 +4,7 @@
# @LAYER Domain
# @RELATION DEPENDS_ON -> [AuthRepository]
# @RELATION DEPENDS_ON -> [UserDashboardPreference]
-# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
# @RELATION DEPENDS_ON -> [EncryptionManager]
# @RATIONALE Extracted from ProfileService to satisfy INV_7. Preference CRUD is the core profile
# operation with DB persistence, token encryption, and cross-field validation — a
@@ -31,7 +31,7 @@ from ..schemas.profile import (
ProfilePreferenceUpdateRequest,
)
from .llm_provider import EncryptionManager
-from .profile[EXT:internal:_utils] import (
+from .profile_utils import (
ProfileAuthorizationError,
ProfileValidationError,
build_default_preference,
@@ -336,7 +336,7 @@ class ProfilePreferenceService:
# #endregion _to_preference_payload
# #region _build_default_preference [C:1] [TYPE Function]
- # @BRIEF Delegate to profile[EXT:internal:_utils].build_default_preference.
+ # @BRIEF Delegate to ProfileUtils.build_default_preference.
def _build_default_preference(self, user_id: str) -> ProfilePreference:
return build_default_preference(user_id)
# #endregion _build_default_preference
diff --git a/backend/src/services/profile_service.py b/backend/src/services/profile_service.py
index 7b6059f1..974ed1d5 100644
--- a/backend/src/services/profile_service.py
+++ b/backend/src/services/profile_service.py
@@ -12,7 +12,7 @@
# @RELATION DEPENDS_ON -> [ProfilePreferenceService]
# @RELATION DEPENDS_ON -> [SupersetLookupService]
# @RELATION DEPENDS_ON -> [SecurityBadgeService]
-# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
#
# @INVARIANT Profile ID needs to be unique per-user session
#
@@ -28,7 +28,7 @@
# @SIDE_EFFECT Database read/write operations
# @RATIONALE Decomposed from monolithic 770-line ProfileService into three focused services
# (ProfilePreferenceService, SupersetLookupService, SecurityBadgeService) plus pure
-# utility functions (profile[EXT:internal:_utils]) to satisfy INV_7. This module is a thin facade
+# utility functions (ProfileUtils) to satisfy INV_7. This module is a thin facade
# that preserves the public API contract for all existing callers.
# @REJECTED Keeping all three domains in a single ProfileService class was rejected — it violated
# INV_7 (770 lines vs 150 max), mixed I/O patterns (DB writes + HTTP calls), and created
@@ -48,7 +48,7 @@ from ..schemas.profile import (
SupersetAccountLookupResponse,
)
from .profile_preference_service import ProfilePreferenceService
-from .profile[EXT:internal:_utils] import (
+from .profile_utils import (
EnvironmentNotFoundError,
ProfileAuthorizationError,
ProfileValidationError,
@@ -77,7 +77,7 @@ __all__ = [
# @RELATION DEPENDS_ON -> [ProfilePreferenceService]
# @RELATION DEPENDS_ON -> [SupersetLookupService]
# @RELATION DEPENDS_ON -> [SecurityBadgeService]
-# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
# @PRE Caller provides authenticated User context for external service methods.
# @POST Delegates to sub-services and returns normalized profile/lookup responses.
# @SIDE_EFFECT Writes preference records and encrypted tokens; performs external account lookups when requested.
diff --git a/backend/src/services/profile_utils.py b/backend/src/services/profile_utils.py
index 312d4d1a..20910d63 100644
--- a/backend/src/services/profile_utils.py
+++ b/backend/src/services/profile_utils.py
@@ -1,4 +1,4 @@
-# #region profile[EXT:internal:_utils] [C:2] [TYPE Module] [SEMANTICS string,normalization,utility,sanitize]
+# #region ProfileUtils [C:2] [TYPE Module] [SEMANTICS string,normalization,utility,sanitize]
# @BRIEF Pure utility helpers for profile data sanitization, normalization, and secret masking.
# Also contains shared exception classes to avoid circular imports between profile sub-modules.
# @LAYER Domain
@@ -122,8 +122,8 @@ def mask_secret_value(secret: str | None) -> str | None:
# @BRIEF Validate username/toggle constraints for preference mutation.
# @RELATION CALLS -> [sanitize_username]
# @RELATION CALLS -> [sanitize_text]
-# @RELATION DEPENDS_ON -> [EXT:profile[EXT:internal:_utils]:SUPPORTED_DENSITIES]
-# @RELATION DEPENDS_ON -> [EXT:profile[EXT:internal:_utils]:SUPPORTED_START_PAGES]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
# @POST Returns validation errors list; empty list means valid.
def validate_update_payload(
superset_username: str | None,
@@ -242,4 +242,4 @@ def normalize_owner_tokens(owners: Iterable[Any] | None) -> list[str]:
normalized.append(token)
return normalized
# #endregion normalize_owner_tokens
-# #endregion profile[EXT:internal:_utils]
+# #endregion ProfileUtils
diff --git a/backend/src/services/security_badge_service.py b/backend/src/services/security_badge_service.py
index 9c6ac9a9..231e46c1 100644
--- a/backend/src/services/security_badge_service.py
+++ b/backend/src/services/security_badge_service.py
@@ -4,7 +4,7 @@
# @LAYER Domain
# @RELATION DEPENDS_ON -> [User]
# @RELATION DEPENDS_ON -> [discover_declared_permissions]
-# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
# @RATIONALE Extracted from ProfileService to satisfy INV_7. Security badge construction
# is a distinct concern with its own dependencies (discover_declared_permissions,
# plugin_loader) and can be tested independently.
@@ -20,7 +20,7 @@ from typing import Any
from ..core.logger import belief_scope, logger
from ..models.auth import User
from ..schemas.profile import ProfilePermissionState, ProfileSecuritySummary
-from .profile[EXT:internal:_utils] import sanitize_text
+from .profile_utils import sanitize_text
from .rbac_permission_catalog import discover_declared_permissions
diff --git a/backend/src/services/sql_table_extractor.py b/backend/src/services/sql_table_extractor.py
index ed09927f..9e28b47d 100644
--- a/backend/src/services/sql_table_extractor.py
+++ b/backend/src/services/sql_table_extractor.py
@@ -4,7 +4,7 @@
# Phase 2: In Jinja spans, extract "schema.table" from string values
# Phase 3: In SQL spans, regex pattern + sqlparse filter to reject string literal false positives
# @LAYER Service
-# @RELATION DEPENDS_ON -> [[EXT:internal:re_sqlparse]]
+# @RELATION DEPENDS_ON -> [EXT:Library:sqlparse]
# @INVARIANT Only exact schema.table matches (case-insensitive); unqualified references are NOT matched.
# @INVARIANT Returns a set[str] of fully-qualified table names (lowercased for case-insensitive matching).
diff --git a/backend/src/services/superset_lookup_service.py b/backend/src/services/superset_lookup_service.py
index 1e694da6..5011cb81 100644
--- a/backend/src/services/superset_lookup_service.py
+++ b/backend/src/services/superset_lookup_service.py
@@ -3,7 +3,7 @@
# @LAYER Domain
# @RELATION DEPENDS_ON -> [SupersetClient]
# @RELATION DEPENDS_ON -> [SupersetAccountLookupAdapter]
-# @RELATION DEPENDS_ON -> [profile[EXT:internal:_utils]]
+# @RELATION DEPENDS_ON -> [ProfileUtils]
# @RATIONALE Extracted from ProfileService to satisfy INV_7. Superset account lookup has distinct
# I/O patterns (external HTTP calls, environment resolution) that isolate cleanly from
# preference persistence and security badge logic.
@@ -25,7 +25,7 @@ from ..schemas.profile import (
SupersetAccountLookupRequest,
SupersetAccountLookupResponse,
)
-from .profile[EXT:internal:_utils] import EnvironmentNotFoundError
+from .profile_utils import EnvironmentNotFoundError
# #region SupersetLookupService [C:4] [TYPE Class] [SEMANTICS superset,lookup,environment,degradation]
diff --git a/backend/src/services/validation_run_service.py b/backend/src/services/validation_run_service.py
index 7fb9a988..aa58f06b 100644
--- a/backend/src/services/validation_run_service.py
+++ b/backend/src/services/validation_run_service.py
@@ -91,6 +91,7 @@ class ValidationRunService:
timestamp=r.timestamp,
screenshot_path=r.screenshot_path,
task_name=self._resolve_task_name(r),
+ issues_count=len(r.issues) if r.issues else 0,
)
for r in records
]
diff --git a/backend/tests/services/clean_release/test_demo_mode_isolation.py b/backend/tests/services/clean_release/test_demo_mode_isolation.py
index e32698ea..70062e61 100644
--- a/backend/tests/services/clean_release/test_demo_mode_isolation.py
+++ b/backend/tests/services/clean_release/test_demo_mode_isolation.py
@@ -2,7 +2,7 @@
# @SEMANTICS: clean-release, demo-mode, isolation, namespace, repository
# @PURPOSE: Verify demo and real mode namespace isolation contracts before TUI integration.
# @LAYER Tests
-# @RELATION DEPENDS_ON -> [EXT:path:backend.src.services.clean_release.demo_data_service]
+# @RELATION DEPENDS_ON -> [DemoDataService]
from __future__ import annotations
diff --git a/backend/tests/test_layout_utils.py b/backend/tests/test_layout_utils.py
index cbb44902..c56c4faa 100644
--- a/backend/tests/test_layout_utils.py
+++ b/backend/tests/test_layout_utils.py
@@ -1,4 +1,4 @@
-# #region test_layout[EXT:internal:_utils] [C:3] [TYPE TestModule] [SEMANTICS test, layout, superset, height, estimation]
+# #region TestLayoutUtils [C:3] [TYPE TestModule] [SEMANTICS test, layout, superset, height, estimation]
# @BRIEF Contract tests for layout utility functions — _estimate_markdown_height.
# Verifies the height estimation formula: empty → 19, short text → computed,
# padding accounted for, and long text capped at 200.
@@ -11,7 +11,7 @@
# @TEST_EDGE: very_long_content -> capped at maximum height (200)
import pytest
-from src.core.superset_client._layout[EXT:internal:_utils] import _estimate_markdown_height
+from src.core.superset_client._layout_utils import _estimate_markdown_height
class TestEstimateMarkdownHeight:
@@ -52,4 +52,4 @@ class TestEstimateMarkdownHeight:
content = "
"
assert _estimate_markdown_height(content) == 19
# #endregion test_html_only_content
-# #endregion test_layout[EXT:internal:_utils]
+# #endregion TestLayoutUtils
diff --git a/backend/tests/test_logger.py b/backend/tests/test_logger.py
index c1c552c5..d848b92c 100644
--- a/backend/tests/test_logger.py
+++ b/backend/tests/test_logger.py
@@ -2,7 +2,7 @@
# @SEMANTICS: logging, tests, belief_state, cot, json
# @PURPOSE: Unit tests for the custom logger CoT JSON formatters and configuration context manager.
# @LAYER Tests
-# @RELATION BINDS_TO -> [EXT:path:src/core/logger.py]
+# @RELATION BINDS_TO -> [LoggerModule]
# @INVARIANT: All required log statements must correctly check the threshold.
import logging
diff --git a/docs/api/Doxyfile b/docs/api/Doxyfile
new file mode 100644
index 00000000..5cf35b9f
--- /dev/null
+++ b/docs/api/Doxyfile
@@ -0,0 +1,20 @@
+PROJECT_NAME = "ss-tools API"
+PROJECT_BRIEF = "Superset Tools Backend — GRACE-Poly semantic contracts"
+OUTPUT_DIRECTORY = docs/api/html
+INPUT = /home/busya/dev/ss-tools/docs/api/doxygen_stripped.txt
+FILE_PATTERNS = *.txt
+RECURSIVE = NO
+EXTENSION_MAPPING = txt=C
+GENERATE_HTML = YES
+GENERATE_LATEX = NO
+QUIET = YES
+WARNINGS = NO
+JAVADOC_AUTOBRIEF = YES
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+SORT_BRIEF_DOCS = YES
+FULL_PATH_NAMES = YES
+HTML_OUTPUT = .
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH = 250
diff --git a/docs/api/doxygen_docs.h b/docs/api/doxygen_docs.h
new file mode 100644
index 00000000..e1497af9
--- /dev/null
+++ b/docs/api/doxygen_docs.h
@@ -0,0 +1,21169 @@
+/// @defgroup SrcRoot "SrcRoot"
+/// @{
+/// @brief Canonical backend package root for application, scripts, and tests.
+/// @}
+void SrcRoot(void);
+
+/// @defgroup src_api "src.api"
+/// @{
+/// @brief Backend API package root.
+/// @}
+void src_api(void);
+
+/// @defgroup AuthApi "AuthApi"
+/// @{
+/// @brief Authentication API endpoints.
+/// @invariant All auth endpoints must return consistent error codes.
+/// @post FastAPI app instance with auth routes registered.
+/// @pre Python environment and dependencies installed; database available.
+/// @}
+void AuthApi(void);
+
+/// @defgroup login_for_access_token "login_for_access_token"
+/// @{
+/// @brief Authenticates a user and returns a JWT access token.
+/// @post Returns a Token object on success.
+/// @pre form_data contains username and password.
+/// @}
+void login_for_access_token(void);
+
+/// @defgroup read_users_me "read_users_me"
+/// @{
+/// @brief Retrieves the profile of the currently authenticated user.
+/// @post Returns the current user's data.
+/// @pre Valid JWT token provided.
+/// @}
+void read_users_me(void);
+
+/// @defgroup logout "logout"
+/// @{
+/// @brief Logs out the current user (placeholder for session revocation).
+/// @post Returns success message.
+/// @pre Valid JWT token provided.
+/// @}
+void logout(void);
+
+/// @defgroup login_adfs "login_adfs"
+/// @{
+/// @brief Initiates the ADFS OIDC login flow.
+/// @post Redirects the user to ADFS.
+/// @}
+void login_adfs(void);
+
+/// @defgroup auth_callback_adfs "auth_callback_adfs"
+/// @{
+/// @brief Handles the callback from ADFS after successful authentication.
+/// @post Provisions user JIT and returns session token.
+/// @}
+void auth_callback_adfs(void);
+
+/// @defgroup ApiRoutesModule "ApiRoutesModule"
+/// @{
+/// @brief Provide lazy route module loading to avoid heavyweight imports during tests.
+/// @invariant Only names listed in __all__ are importable via __getattr__.
+/// @post Route modules are lazily loadable via __getattr__
+/// @pre FastAPI app initialized, route modules available in package
+/// @}
+void ApiRoutesModule(void);
+
+/// @defgroup Route_Group_Contracts "Route_Group_Contracts"
+/// @{
+/// @brief Declare the canonical route-module registry used by lazy imports and app router inclusion.
+/// @}
+void Route_Group_Contracts(void);
+
+/// @defgroup ApiRoutesGetAttr "ApiRoutesGetAttr"
+/// @{
+/// @brief Lazily import route module by attribute name.
+/// @post Returns imported submodule or raises AttributeError.
+/// @pre name is module candidate exposed in __all__.
+/// @}
+void ApiRoutesGetAttr(void);
+
+/// @defgroup RoutesTestsConftest "RoutesTestsConftest"
+/// @{
+/// @brief Shared low-fidelity test doubles for API route test modules.
+/// @}
+void RoutesTestsConftest(void);
+
+/// @defgroup AssistantApiTests "AssistantApiTests"
+/// @{
+/// @brief Validate assistant API endpoint logic via direct async handler invocation.
+/// @invariant Every test clears assistant in-memory state before execution.
+/// @}
+void AssistantApiTests(void);
+
+/// @defgroup _dataset_review_session "_dataset_review_session"
+/// @{
+/// @brief Build minimal owned dataset-review session fixture for assistant scoped routing tests.
+/// @}
+void _dataset_review_session(void);
+
+/// @defgroup _await_none "_await_none"
+/// @{
+/// @brief Async helper returning None for planner fallback tests.
+/// @}
+void _await_none(void);
+
+/// @defgroup test_unknown_command_returns_needs_clarification "test_unknown_command_returns_needs_clarification"
+/// @{
+/// @brief Unknown command should return clarification state and unknown intent.
+/// @}
+void test_unknown_command_returns_needs_clarification(void);
+
+/// @defgroup test_capabilities_question_returns_successful_help "test_capabilities_question_returns_successful_help"
+/// @{
+/// @brief Capability query should return deterministic help response.
+/// @}
+void test_capabilities_question_returns_successful_help(void);
+
+/// @defgroup test_assistant_message_request_accepts_dataset_review_session_binding "test_assistant_message_request_accepts_dataset_review_session_binding"
+/// @{
+/// @brief Assistant request schema should accept active dataset review session binding for scoped orchestration.
+/// @}
+void test_assistant_message_request_accepts_dataset_review_session_binding(void);
+
+/// @defgroup test_dataset_review_scoped_message_uses_masked_filter_context "test_dataset_review_scoped_message_uses_masked_filter_context"
+/// @{
+/// @brief Session-scoped assistant context should mask imported-filter raw values before assistant-visible metadata is persisted.
+/// @}
+void test_dataset_review_scoped_message_uses_masked_filter_context(void);
+
+/// @defgroup test_dataset_review_scoped_command_returns_confirmation_for_mapping_approval "test_dataset_review_scoped_command_returns_confirmation_for_mapping_approval"
+/// @{
+/// @brief Session-scoped assistant commands should route dataset-review mapping approvals into confirmation workflow with bound session metadata.
+/// @}
+void test_dataset_review_scoped_command_returns_confirmation_for_mapping_approval(void);
+
+/// @defgroup test_dataset_review_scoped_command_routes_field_semantics_update "test_dataset_review_scoped_command_routes_field_semantics_update"
+/// @{
+/// @brief Session-scoped assistant commands should route semantic field updates through explicit confirmation metadata.
+/// @}
+void test_dataset_review_scoped_command_routes_field_semantics_update(void);
+
+/// @defgroup TestAssistantAuthz "TestAssistantAuthz"
+/// @{
+/// @brief Verify assistant confirmation ownership, expiration, and deny behavior for restricted users.
+/// @invariant Security-sensitive flows fail closed for unauthorized actors.
+/// @}
+void TestAssistantAuthz(void);
+
+/// @defgroup _run_async "_run_async"
+/// @{
+/// @brief Execute async endpoint handler in synchronous test context.
+/// @post Returns coroutine result or raises propagated exception.
+/// @pre coroutine is awaitable endpoint invocation.
+/// @}
+void _run_async(void);
+
+/// @defgroup _FakeTask "_FakeTask"
+/// @{
+/// @brief Lightweight task model used for assistant authz tests.
+/// @post Returns task with provided id, status, and user_id accessible as attributes.
+/// @pre task_id is non-empty string.
+/// @}
+void _FakeTask(void);
+
+/// @defgroup _FakeConfigManager "_FakeConfigManager"
+/// @{
+/// @brief Provide deterministic environment aliases required by intent parsing.
+/// @invariant get_config() is absent; only get_environments() is emulated. Safe only for routes that do not invoke get_config() on the injected ConfigManager — verify against assistant.py route handler code before adding new test cases that use this fake.
+/// @post get_environments() returns two deterministic SimpleNamespace stubs with id/name.
+/// @pre No external config or DB state is required.
+/// @}
+void _FakeConfigManager(void);
+
+/// @defgroup _other_admin_user "_other_admin_user"
+/// @{
+/// @brief Build second admin principal fixture for ownership tests.
+/// @post Returns alternate admin-like user stub.
+/// @pre Ownership mismatch scenario needs distinct authenticated actor.
+/// @}
+void _other_admin_user(void);
+
+/// @defgroup _limited_user "_limited_user"
+/// @{
+/// @brief Build limited principal without required assistant execution privileges.
+/// @post Returns restricted user stub.
+/// @pre Permission denial scenario needs non-admin actor.
+/// @}
+void _limited_user(void);
+
+/// @defgroup _FakeDb "_FakeDb"
+/// @{
+/// @brief In-memory DB session double constrained to assistant message/confirmation/audit persistence paths.
+/// @invariant query/add/merge are intentionally narrow and must not claim full SQLAlchemy Session semantics.
+/// @}
+void _FakeDb(void);
+
+/// @defgroup _clear_assistant_state "_clear_assistant_state"
+/// @{
+/// @brief Reset assistant process-local state between test cases.
+/// @post Assistant in-memory state dictionaries are cleared.
+/// @pre Assistant globals may contain state from prior tests.
+/// @}
+void _clear_assistant_state(void);
+
+/// @defgroup test_confirmation_owner_mismatch_returns_403 "test_confirmation_owner_mismatch_returns_403"
+/// @{
+/// @brief Confirm endpoint should reject requests from user that does not own the confirmation token.
+/// @post Second actor receives 403 on confirm operation.
+/// @pre Confirmation token is created by first admin actor.
+/// @}
+void test_confirmation_owner_mismatch_returns_403(void);
+
+/// @defgroup test_expired_confirmation_cannot_be_confirmed "test_expired_confirmation_cannot_be_confirmed"
+/// @{
+/// @brief Expired confirmation token should be rejected and not create task.
+/// @post Confirm endpoint raises 400 and no task is created.
+/// @pre Confirmation token exists and is manually expired before confirm request.
+/// @}
+void test_expired_confirmation_cannot_be_confirmed(void);
+
+/// @defgroup test_limited_user_cannot_launch_restricted_operation "test_limited_user_cannot_launch_restricted_operation"
+/// @{
+/// @brief Limited user should receive denied state for privileged operation.
+/// @post Assistant returns denied state and does not execute operation.
+/// @pre Restricted user attempts dangerous deploy command.
+/// @}
+void test_limited_user_cannot_launch_restricted_operation(void);
+
+/// @defgroup TestCleanReleaseApi "TestCleanReleaseApi"
+/// @{
+/// @brief Contract tests for clean release checks and reports endpoints.
+/// @invariant API returns deterministic payload shapes for checks and reports.
+/// @}
+void TestCleanReleaseApi(void);
+
+/// @defgroup test_start_check_and_get_status_contract "test_start_check_and_get_status_contract"
+/// @{
+/// @brief Validate checks start endpoint returns expected identifiers and status endpoint reflects the same run.
+/// @}
+void test_start_check_and_get_status_contract(void);
+
+/// @defgroup test_get_report_not_found_returns_404 "test_get_report_not_found_returns_404"
+/// @{
+/// @brief Validate reports endpoint returns 404 for an unknown report identifier.
+/// @}
+void test_get_report_not_found_returns_404(void);
+
+/// @defgroup test_get_report_success "test_get_report_success"
+/// @{
+/// @brief Validate reports endpoint returns persisted report payload for an existing report identifier.
+/// @}
+void test_get_report_success(void);
+
+/// @defgroup test_prepare_candidate_api_success "test_prepare_candidate_api_success"
+/// @{
+/// @brief Validate candidate preparation endpoint returns prepared status and manifest identifier on valid input.
+/// @}
+void test_prepare_candidate_api_success(void);
+
+/// @defgroup TestCleanReleaseLegacyCompat "TestCleanReleaseLegacyCompat"
+/// @{
+/// @brief Compatibility tests for legacy clean-release API paths retained during v2 migration.
+/// @}
+void TestCleanReleaseLegacyCompat(void);
+
+/// @defgroup _seed_legacy_repo "_seed_legacy_repo"
+/// @{
+/// @brief Seed in-memory repository with minimum trusted data for legacy endpoint contracts.
+/// @post Candidate, policy, registry and manifest are available for legacy checks flow.
+/// @pre Repository is empty.
+/// @}
+void _seed_legacy_repo(void);
+
+/// @defgroup test_legacy_prepare_endpoint_still_available "test_legacy_prepare_endpoint_still_available"
+/// @{
+/// @brief Verify legacy prepare endpoint remains reachable and returns a status payload.
+/// @}
+void test_legacy_prepare_endpoint_still_available(void);
+
+/// @defgroup test_legacy_checks_endpoints_still_available "test_legacy_checks_endpoints_still_available"
+/// @{
+/// @brief Verify legacy checks start/status endpoints remain available during v2 transition.
+/// @}
+void test_legacy_checks_endpoints_still_available(void);
+
+/// @defgroup TestCleanReleaseSourcePolicy "TestCleanReleaseSourcePolicy"
+/// @{
+/// @brief Validate API behavior for source isolation violations in clean release preparation.
+/// @invariant External endpoints must produce blocking violation entries.
+/// @}
+void TestCleanReleaseSourcePolicy(void);
+
+/// @defgroup _repo_with_seed_data "_repo_with_seed_data"
+/// @{
+/// @brief Seed repository with candidate, registry, and active policy for source isolation test flow.
+/// @}
+void _repo_with_seed_data(void);
+
+/// @defgroup test_prepare_candidate_blocks_external_source "test_prepare_candidate_blocks_external_source"
+/// @{
+/// @brief Verify candidate preparation is blocked when at least one source host is external to the trusted registry.
+/// @}
+void test_prepare_candidate_blocks_external_source(void);
+
+/// @defgroup CleanReleaseV2ApiTests "CleanReleaseV2ApiTests"
+/// @{
+/// @brief API contract tests for redesigned clean release endpoints.
+/// @}
+void CleanReleaseV2ApiTests(void);
+
+/// @defgroup test_candidate_registration_contract "test_candidate_registration_contract"
+/// @{
+/// @brief Validate candidate registration endpoint creates a draft candidate with expected identifier contract.
+/// @}
+void test_candidate_registration_contract(void);
+
+/// @defgroup test_artifact_import_contract "test_artifact_import_contract"
+/// @{
+/// @brief Validate artifact import endpoint accepts candidate artifacts and returns success status payload.
+/// @}
+void test_artifact_import_contract(void);
+
+/// @defgroup test_manifest_build_contract "test_manifest_build_contract"
+/// @{
+/// @brief Validate manifest build endpoint produces manifest payload linked to the target candidate.
+/// @}
+void test_manifest_build_contract(void);
+
+/// @defgroup CleanReleaseV2ReleaseApiTests "CleanReleaseV2ReleaseApiTests"
+/// @{
+/// @brief API contract test scaffolding for clean release approval and publication endpoints.
+/// @}
+void CleanReleaseV2ReleaseApiTests(void);
+
+/// @defgroup _seed_candidate_and_passed_report "_seed_candidate_and_passed_report"
+/// @{
+/// @brief Seed repository with approvable candidate and passed report for release endpoint contracts.
+/// @}
+void _seed_candidate_and_passed_report(void);
+
+/// @defgroup test_release_approve_and_publish_revoke_contract "test_release_approve_and_publish_revoke_contract"
+/// @{
+/// @brief Verify approve, publish, and revoke endpoints preserve expected release lifecycle contract.
+/// @}
+void test_release_approve_and_publish_revoke_contract(void);
+
+/// @defgroup test_release_reject_contract "test_release_reject_contract"
+/// @{
+/// @brief Verify reject endpoint returns successful rejection decision payload.
+/// @}
+void test_release_reject_contract(void);
+
+/// @defgroup DashboardsApiTests "DashboardsApiTests"
+/// @{
+/// @brief Unit tests for dashboards API endpoints.
+/// @}
+void DashboardsApiTests(void);
+
+/// @defgroup test_get_dashboards_success "test_get_dashboards_success"
+/// @{
+/// @brief Validate dashboards listing returns a populated response that satisfies the schema contract.
+/// @post Response matches DashboardsResponse schema
+/// @pre env_id exists
+/// @test GET /api/dashboards returns 200 and valid schema
+/// @}
+void test_get_dashboards_success(void);
+
+/// @defgroup test_get_dashboards_with_search "test_get_dashboards_with_search"
+/// @{
+/// @brief Validate dashboards listing applies the search filter and returns only matching rows.
+/// @post Filtered result count must match search
+/// @pre search parameter provided
+/// @test GET /api/dashboards filters by search term
+/// @}
+void test_get_dashboards_with_search(void);
+
+/// @defgroup test_get_dashboards_empty "test_get_dashboards_empty"
+/// @{
+/// @brief Validate dashboards listing returns an empty payload for an environment without dashboards.
+/// @}
+void test_get_dashboards_empty(void);
+
+/// @defgroup test_get_dashboards_superset_failure "test_get_dashboards_superset_failure"
+/// @{
+/// @brief Validate dashboards listing surfaces a 503 contract when Superset access fails.
+/// @}
+void test_get_dashboards_superset_failure(void);
+
+/// @defgroup test_get_dashboards_env_not_found "test_get_dashboards_env_not_found"
+/// @{
+/// @brief Validate dashboards listing returns 404 when the requested environment does not exist.
+/// @post Returns 404 error
+/// @pre env_id does not exist
+/// @test GET /api/dashboards returns 404 if env_id missing
+/// @}
+void test_get_dashboards_env_not_found(void);
+
+/// @defgroup test_get_dashboards_invalid_pagination "test_get_dashboards_invalid_pagination"
+/// @{
+/// @brief Validate dashboards listing rejects invalid pagination parameters with 400 responses.
+/// @post Returns 400 error
+/// @pre page < 1 or page_size > 100
+/// @test GET /api/dashboards returns 400 for invalid page/page_size
+/// @}
+void test_get_dashboards_invalid_pagination(void);
+
+/// @defgroup test_get_dashboard_detail_success "test_get_dashboard_detail_success"
+/// @{
+/// @brief Validate dashboard detail returns charts and datasets for an existing dashboard.
+/// @test GET /api/dashboards/{id} returns dashboard detail with charts and datasets
+/// @}
+void test_get_dashboard_detail_success(void);
+
+/// @defgroup test_get_dashboard_detail_env_not_found "test_get_dashboard_detail_env_not_found"
+/// @{
+/// @brief Validate dashboard detail returns 404 when the requested environment is missing.
+/// @test GET /api/dashboards/{id} returns 404 for missing environment
+/// @}
+void test_get_dashboard_detail_env_not_found(void);
+
+/// @defgroup test_migrate_dashboards_success "test_migrate_dashboards_success"
+/// @{
+/// @brief Validate dashboard migration request creates an async task and returns its identifier.
+/// @post Returns task_id and create_task was called
+/// @POST/@SIDE_EFFECT: create_task was called
+/// @pre Valid source_env_id, target_env_id, dashboard_ids
+/// @test POST /api/dashboards/migrate creates migration task
+/// @}
+void test_migrate_dashboards_success(void);
+
+/// @defgroup test_migrate_dashboards_no_ids "test_migrate_dashboards_no_ids"
+/// @{
+/// @brief Validate dashboard migration rejects empty dashboard identifier lists.
+/// @post Returns 400 error
+/// @pre dashboard_ids is empty
+/// @test POST /api/dashboards/migrate returns 400 for empty dashboard_ids
+/// @}
+void test_migrate_dashboards_no_ids(void);
+
+/// @defgroup test_migrate_dashboards_env_not_found "test_migrate_dashboards_env_not_found"
+/// @{
+/// @brief Validate migration creation returns 404 when the source environment cannot be resolved.
+/// @pre source_env_id and target_env_id are valid environment IDs
+/// @}
+void test_migrate_dashboards_env_not_found(void);
+
+/// @defgroup test_backup_dashboards_success "test_backup_dashboards_success"
+/// @{
+/// @brief Validate dashboard backup request creates an async backup task and returns its identifier.
+/// @post Returns task_id and create_task was called
+/// @POST/@SIDE_EFFECT: create_task was called
+/// @pre Valid env_id, dashboard_ids
+/// @test POST /api/dashboards/backup creates backup task
+/// @}
+void test_backup_dashboards_success(void);
+
+/// @defgroup test_backup_dashboards_env_not_found "test_backup_dashboards_env_not_found"
+/// @{
+/// @brief Validate backup task creation returns 404 when the target environment is missing.
+/// @pre env_id is a valid environment ID
+/// @}
+void test_backup_dashboards_env_not_found(void);
+
+/// @defgroup test_get_database_mappings_success "test_get_database_mappings_success"
+/// @{
+/// @brief Validate database mapping suggestions are returned for valid source and target environments.
+/// @post Returns list of database mappings
+/// @pre Valid source_env_id, target_env_id
+/// @test GET /api/dashboards/db-mappings returns mapping suggestions
+/// @}
+void test_get_database_mappings_success(void);
+
+/// @defgroup test_get_database_mappings_env_not_found "test_get_database_mappings_env_not_found"
+/// @{
+/// @brief Validate database mapping suggestions return 404 when either environment is missing.
+/// @pre source_env_id and target_env_id are valid environment IDs
+/// @}
+void test_get_database_mappings_env_not_found(void);
+
+/// @defgroup test_get_dashboard_tasks_history_filters_success "test_get_dashboard_tasks_history_filters_success"
+/// @{
+/// @brief Validate dashboard task history returns only related backup and LLM tasks.
+/// @test GET /api/dashboards/{id}/tasks returns backup and llm tasks for dashboard
+/// @}
+void test_get_dashboard_tasks_history_filters_success(void);
+
+/// @defgroup test_get_dashboard_thumbnail_success "test_get_dashboard_thumbnail_success"
+/// @{
+/// @brief Validate dashboard thumbnail endpoint proxies image bytes and content type from Superset.
+/// @test GET /api/dashboards/{id}/thumbnail proxies image bytes from Superset
+/// @}
+void test_get_dashboard_thumbnail_success(void);
+
+/// @defgroup _build_profile_preference_stub "_build_profile_preference_stub"
+/// @{
+/// @brief Creates profile preference payload stub for dashboards filter contract tests.
+/// @post Returns object compatible with ProfileService.get_my_preference contract.
+/// @pre username can be empty; enabled indicates profile-default toggle state.
+/// @}
+void _build_profile_preference_stub(void);
+
+/// @defgroup _matches_actor_case_insensitive "_matches_actor_case_insensitive"
+/// @{
+/// @brief Applies trim + case-insensitive owners OR modified_by matching used by route contract tests.
+/// @post Returns True when bound username matches any owner or modified_by.
+/// @pre owners can be None or list-like values.
+/// @}
+void _matches_actor_case_insensitive(void);
+
+/// @defgroup test_get_dashboards_profile_filter_contract_owners_or_modified_by "test_get_dashboards_profile_filter_contract_owners_or_modified_by"
+/// @{
+/// @brief Validate profile-default filtering matches owner and modifier aliases using normalized Superset actor values.
+/// @post Response includes only matching dashboards and effective_profile_filter metadata.
+/// @pre Current user has enabled profile-default preference and bound username.
+/// @test GET /api/dashboards applies profile-default filter with owners OR modified_by trim+case-insensitive semantics.
+/// @}
+void test_get_dashboards_profile_filter_contract_owners_or_modified_by(void);
+
+/// @defgroup test_get_dashboards_override_show_all_contract "test_get_dashboards_override_show_all_contract"
+/// @{
+/// @brief Validate override_show_all bypasses profile-default filtering without changing dashboard list semantics.
+/// @post Response remains unfiltered and effective_profile_filter.applied is false.
+/// @pre Profile-default preference exists but override_show_all=true query is provided.
+/// @test GET /api/dashboards honors override_show_all and disables profile-default filter for current page.
+/// @}
+void test_get_dashboards_override_show_all_contract(void);
+
+/// @defgroup test_get_dashboards_profile_filter_no_match_results_contract "test_get_dashboards_profile_filter_no_match_results_contract"
+/// @{
+/// @brief Validate profile-default filtering returns an empty dashboard page when no actor aliases match the bound user.
+/// @post Response total is 0 with deterministic pagination and active effective_profile_filter metadata.
+/// @pre Profile-default preference is enabled with bound username and all dashboards are non-matching.
+/// @test GET /api/dashboards returns empty result set when profile-default filter is active and no dashboard actors match.
+/// @}
+void test_get_dashboards_profile_filter_no_match_results_contract(void);
+
+/// @defgroup test_get_dashboards_page_context_other_disables_profile_default "test_get_dashboards_page_context_other_disables_profile_default"
+/// @{
+/// @brief Validate non-dashboard page contexts suppress profile-default filtering and preserve unfiltered results.
+/// @post Response remains unfiltered and metadata reflects source_page=other.
+/// @pre Profile-default preference exists but page_context=other query is provided.
+/// @test GET /api/dashboards does not auto-apply profile-default filter outside dashboards_main page context.
+/// @}
+void test_get_dashboards_page_context_other_disables_profile_default(void);
+
+/// @defgroup test_get_dashboards_profile_filter_matches_display_alias_without_detail_fanout "test_get_dashboards_profile_filter_matches_display_alias_without_detail_fanout"
+/// @{
+/// @brief Validate profile-default filtering reuses resolved Superset display aliases without triggering per-dashboard detail fanout.
+/// @post Route matches by alias (`Superset Admin`) and does not call `SupersetClient.get_dashboard` in list filter path.
+/// @pre Profile-default filter is active, bound username is `admin`, dashboard actors contain display labels.
+/// @test GET /api/dashboards resolves Superset display-name alias once and filters without per-dashboard detail calls.
+/// @}
+void test_get_dashboards_profile_filter_matches_display_alias_without_detail_fanout(void);
+
+/// @defgroup test_get_dashboards_profile_filter_matches_owner_object_payload_contract "test_get_dashboards_profile_filter_matches_owner_object_payload_contract"
+/// @{
+/// @brief Validate profile-default filtering accepts owner object payloads once aliases resolve to the bound Superset username.
+/// @post Response keeps dashboards where owner object resolves to bound username alias.
+/// @pre Profile-default preference is enabled and owners list contains dict payloads.
+/// @test GET /api/dashboards profile-default filter matches Superset owner object payloads.
+/// @}
+void test_get_dashboards_profile_filter_matches_owner_object_payload_contract(void);
+
+/// @defgroup DatasetReviewApiTests "DatasetReviewApiTests"
+/// @{
+/// @brief Verify backend US1 dataset review lifecycle, export, parsing, and dictionary-resolution contracts.
+/// @}
+void DatasetReviewApiTests(void);
+
+/// @defgroup _make_user "_make_user"
+/// @{
+/// @}
+void _make_user(void);
+
+/// @defgroup _make_config_manager "_make_config_manager"
+/// @{
+/// @}
+void _make_config_manager(void);
+
+/// @defgroup _make_session "_make_session"
+/// @{
+/// @}
+void _make_session(void);
+
+/// @defgroup _make_us2_session "_make_us2_session"
+/// @{
+/// @}
+void _make_us2_session(void);
+
+/// @defgroup _make_us3_session "_make_us3_session"
+/// @{
+/// @}
+void _make_us3_session(void);
+
+/// @defgroup _make_preview_ready_session "_make_preview_ready_session"
+/// @{
+/// @}
+void _make_preview_ready_session(void);
+
+/// @defgroup dataset_review_api_dependencies "dataset_review_api_dependencies"
+/// @{
+/// @}
+void dataset_review_api_dependencies(void);
+
+/// @defgroup test_parse_superset_link_dashboard_partial_recovery "test_parse_superset_link_dashboard_partial_recovery"
+/// @{
+/// @brief Verify dashboard links recover dataset context and preserve explicit partial-recovery markers.
+/// @}
+void test_parse_superset_link_dashboard_partial_recovery(void);
+
+/// @defgroup test_parse_superset_link_dashboard_slug_recovery "test_parse_superset_link_dashboard_slug_recovery"
+/// @{
+/// @brief Verify dashboard slug links resolve through dashboard detail endpoints and recover dataset context.
+/// @}
+void test_parse_superset_link_dashboard_slug_recovery(void);
+
+/// @defgroup test_parse_superset_link_dashboard_permalink_partial_recovery "test_parse_superset_link_dashboard_permalink_partial_recovery"
+/// @{
+/// @brief Verify dashboard permalink links no longer fail parsing and preserve permalink filter state for partial recovery.
+/// @}
+void test_parse_superset_link_dashboard_permalink_partial_recovery(void);
+
+/// @defgroup test_parse_superset_link_dashboard_permalink_recovers_dataset_from_nested_dashboard_state "test_parse_superset_link_dashboard_permalink_recovers_dataset_from_nested_dashboard_state"
+/// @{
+/// @brief Verify permalink state with nested dashboard id recovers dataset binding and keeps imported filters.
+/// @}
+void test_parse_superset_link_dashboard_permalink_recovers_dataset_from_nested_dashboard_state(void);
+
+/// @defgroup test_resolve_from_dictionary_prefers_exact_match "test_resolve_from_dictionary_prefers_exact_match"
+/// @{
+/// @brief Verify trusted dictionary exact matches outrank fuzzy candidates and unresolved fields stay explicit.
+/// @}
+void test_resolve_from_dictionary_prefers_exact_match(void);
+
+/// @defgroup test_orchestrator_start_session_preserves_partial_recovery "test_orchestrator_start_session_preserves_partial_recovery"
+/// @{
+/// @brief Verify session start persists usable recovery-required state when Superset intake is partial.
+/// @}
+void test_orchestrator_start_session_preserves_partial_recovery(void);
+
+/// @defgroup test_orchestrator_start_session_bootstraps_recovery_state "test_orchestrator_start_session_bootstraps_recovery_state"
+/// @{
+/// @brief Verify session start persists recovered filters, template variables, and initial execution mappings for review workspace bootstrap.
+/// @}
+void test_orchestrator_start_session_bootstraps_recovery_state(void);
+
+/// @defgroup test_start_session_endpoint_returns_created_summary "test_start_session_endpoint_returns_created_summary"
+/// @{
+/// @brief Verify POST session lifecycle endpoint returns a persisted ownership-scoped summary.
+/// @}
+void test_start_session_endpoint_returns_created_summary(void);
+
+/// @defgroup test_get_session_detail_export_and_lifecycle_endpoints "test_get_session_detail_export_and_lifecycle_endpoints"
+/// @{
+/// @brief Verify lifecycle get/patch/delete plus documentation and validation exports remain ownership-scoped and usable.
+/// @}
+void test_get_session_detail_export_and_lifecycle_endpoints(void);
+
+/// @defgroup test_get_clarification_state_returns_empty_payload_when_session_has_no_record "test_get_clarification_state_returns_empty_payload_when_session_has_no_record"
+/// @{
+/// @brief Clarification state endpoint should return a non-blocking empty payload when the session has no clarification aggregate yet.
+/// @}
+void test_get_clarification_state_returns_empty_payload_when_session_has_no_record(void);
+
+/// @defgroup test_us2_clarification_endpoints_persist_answer_and_feedback "test_us2_clarification_endpoints_persist_answer_and_feedback"
+/// @{
+/// @brief Clarification endpoints should expose one current question, persist the answer before advancement, and store feedback on the answer audit record.
+/// @}
+void test_us2_clarification_endpoints_persist_answer_and_feedback(void);
+
+/// @defgroup test_us2_field_semantic_override_lock_unlock_and_feedback "test_us2_field_semantic_override_lock_unlock_and_feedback"
+/// @{
+/// @brief Semantic field endpoints should apply manual overrides with lock/provenance invariants and persist feedback independently.
+/// @}
+void test_us2_field_semantic_override_lock_unlock_and_feedback(void);
+
+/// @defgroup test_us3_mapping_patch_approval_preview_and_launch_endpoints "test_us3_mapping_patch_approval_preview_and_launch_endpoints"
+/// @{
+/// @brief US3 execution endpoints should persist manual overrides, preserve explicit approval semantics, return contract-shaped preview truth, and expose audited launch handoff.
+/// @}
+void test_us3_mapping_patch_approval_preview_and_launch_endpoints(void);
+
+/// @defgroup test_us3_preview_response_propagates_refreshed_session_version_for_launch_follow_up "test_us3_preview_response_propagates_refreshed_session_version_for_launch_follow_up"
+/// @{
+/// @brief Preview response should expose the refreshed session version so the normal preview-then-launch UI flow can satisfy optimistic locking without a forced full reload.
+/// @}
+void test_us3_preview_response_propagates_refreshed_session_version_for_launch_follow_up(void);
+
+/// @defgroup test_us3_preview_endpoint_returns_failed_preview_without_false_dashboard_not_found_contract_drift "test_us3_preview_endpoint_returns_failed_preview_without_false_dashboard_not_found_contract_drift"
+/// @{
+/// @brief Preview endpoint should preserve API contract and surface generic upstream preview failures without fabricating dashboard-not-found semantics for non-dashboard 404s.
+/// @}
+void test_us3_preview_endpoint_returns_failed_preview_without_false_dashboard_not_found_contract_drift(void);
+
+/// @defgroup test_mutation_endpoints_surface_session_version_conflict_payload "test_mutation_endpoints_surface_session_version_conflict_payload"
+/// @{
+/// @brief Dataset review mutation endpoints should return deterministic 409 conflict semantics when optimistic-lock versions are stale.
+/// @}
+void test_mutation_endpoints_surface_session_version_conflict_payload(void);
+
+/// @defgroup test_update_session_surfaces_commit_time_session_version_conflict_payload "test_update_session_surfaces_commit_time_session_version_conflict_payload"
+/// @{
+/// @brief Session lifecycle mutation should return deterministic 409 conflict semantics when commit-time optimistic locking rejects a stale write.
+/// @}
+void test_update_session_surfaces_commit_time_session_version_conflict_payload(void);
+
+/// @defgroup test_execution_snapshot_includes_recovered_imported_filters_without_template_mapping "test_execution_snapshot_includes_recovered_imported_filters_without_template_mapping"
+/// @{
+/// @brief Recovered imported filters with values should flow into preview filter context even when no template variable mapping exists.
+/// @}
+void test_execution_snapshot_includes_recovered_imported_filters_without_template_mapping(void);
+
+/// @defgroup test_execution_snapshot_preserves_mapped_template_variables_and_filter_context "test_execution_snapshot_preserves_mapped_template_variables_and_filter_context"
+/// @{
+/// @brief Mapped template variables should still populate template params while contributing their effective filter context.
+/// @}
+void test_execution_snapshot_preserves_mapped_template_variables_and_filter_context(void);
+
+/// @defgroup test_execution_snapshot_skips_partial_imported_filters_without_values "test_execution_snapshot_skips_partial_imported_filters_without_values"
+/// @{
+/// @brief Partial imported filters without raw or normalized values must not emit bogus active preview filters.
+/// @}
+void test_execution_snapshot_skips_partial_imported_filters_without_values(void);
+
+/// @defgroup test_us3_launch_endpoint_requires_launch_permission "test_us3_launch_endpoint_requires_launch_permission"
+/// @{
+/// @brief Launch endpoint should enforce the contract RBAC permission instead of the generic session-manage permission.
+/// @}
+void test_us3_launch_endpoint_requires_launch_permission(void);
+
+/// @defgroup test_semantic_source_version_propagation_preserves_locked_fields "test_semantic_source_version_propagation_preserves_locked_fields"
+/// @{
+/// @brief Updated semantic source versions should mark unlocked fields reviewable while preserving locked manual values.
+/// @}
+void test_semantic_source_version_propagation_preserves_locked_fields(void);
+
+/// @defgroup DatasetsApiTests "DatasetsApiTests"
+/// @{
+/// @brief Unit tests for datasets API endpoints.
+/// @invariant Endpoint contracts remain stable for success and validation failure paths.
+/// @}
+void DatasetsApiTests(void);
+
+/// @defgroup test_get_datasets_success "test_get_datasets_success"
+/// @{
+/// @brief Validate successful datasets listing contract for an existing environment.
+/// @post Response matches DatasetsResponse schema
+/// @pre env_id exists
+/// @test GET /api/datasets returns 200 and valid schema
+/// @}
+void test_get_datasets_success(void);
+
+/// @defgroup test_get_datasets_env_not_found "test_get_datasets_env_not_found"
+/// @{
+/// @brief Validate datasets listing returns 404 when the requested environment does not exist.
+/// @post Returns 404 error
+/// @pre env_id does not exist
+/// @test GET /api/datasets returns 404 if env_id missing
+/// @}
+void test_get_datasets_env_not_found(void);
+
+/// @defgroup test_get_datasets_invalid_pagination "test_get_datasets_invalid_pagination"
+/// @{
+/// @brief Validate datasets listing rejects invalid pagination parameters with 400 responses.
+/// @post Returns 400 error
+/// @pre page < 1 or page_size > 100
+/// @test GET /api/datasets returns 400 for invalid page/page_size
+/// @}
+void test_get_datasets_invalid_pagination(void);
+
+/// @defgroup test_map_columns_success "test_map_columns_success"
+/// @{
+/// @brief Validate map-columns request creates an async mapping task and returns its identifier.
+/// @post Returns task_id
+/// @pre Valid env_id, dataset_ids, source_type (sqllab)
+/// @test POST /api/datasets/map-columns creates mapping task
+/// @}
+void test_map_columns_success(void);
+
+/// @defgroup test_map_columns_invalid_source_type "test_map_columns_invalid_source_type"
+/// @{
+/// @brief Validate map-columns rejects unsupported source types with a 400 contract response.
+/// @post Returns 400 error
+/// @pre source_type is not 'sqllab' or 'xlsx'
+/// @test POST /api/datasets/map-columns returns 400 for invalid source_type
+/// @}
+void test_map_columns_invalid_source_type(void);
+
+/// @defgroup test_generate_docs_success "test_generate_docs_success"
+/// @{
+/// @brief Validate generate-docs request creates an async documentation task and returns its identifier.
+/// @post Returns task_id
+/// @pre Valid env_id, dataset_ids, llm_provider
+/// @test POST /api/datasets/generate-docs creates doc generation task
+/// @}
+void test_generate_docs_success(void);
+
+/// @defgroup test_map_columns_empty_ids "test_map_columns_empty_ids"
+/// @{
+/// @brief Validate map-columns rejects empty dataset identifier lists.
+/// @post Returns 400 error
+/// @pre dataset_ids is empty
+/// @test POST /api/datasets/map-columns returns 400 for empty dataset_ids
+/// @}
+void test_map_columns_empty_ids(void);
+
+/// @defgroup test_map_columns_missing_database_id "test_map_columns_missing_database_id"
+/// @{
+/// @brief Validate map-columns rejects sqllab source without database_id.
+/// @post Returns 400 error
+/// @test POST /api/datasets/map-columns returns 400 for sqllab without database_id
+/// @}
+void test_map_columns_missing_database_id(void);
+
+/// @defgroup test_generate_docs_empty_ids "test_generate_docs_empty_ids"
+/// @{
+/// @brief Validate generate-docs rejects empty dataset identifier lists.
+/// @post Returns 400 error
+/// @pre dataset_ids is empty
+/// @test POST /api/datasets/generate-docs returns 400 for empty dataset_ids
+/// @}
+void test_generate_docs_empty_ids(void);
+
+/// @defgroup test_generate_docs_env_not_found "test_generate_docs_env_not_found"
+/// @{
+/// @brief Validate generate-docs returns 404 when the requested environment cannot be resolved.
+/// @post Returns 404 error
+/// @pre env_id does not exist
+/// @test POST /api/datasets/generate-docs returns 404 for missing env
+/// @}
+void test_generate_docs_env_not_found(void);
+
+/// @defgroup test_get_datasets_superset_failure "test_get_datasets_superset_failure"
+/// @{
+/// @brief Validate datasets listing surfaces a 503 contract when Superset access fails.
+/// @post Returns 503 with stable error detail when upstream dataset fetch fails.
+/// @}
+void test_get_datasets_superset_failure(void);
+
+/// @defgroup TestGitApi "TestGitApi"
+/// @{
+/// @brief API tests for Git configurations and repository operations.
+/// @}
+void TestGitApi(void);
+
+/// @defgroup DbMock "DbMock"
+/// @{
+/// @brief In-memory session double for git route tests with minimal query/filter persistence semantics.
+/// @invariant Supports only the SQLAlchemy-like operations exercised by this test module.
+/// @}
+void DbMock(void);
+
+/// @defgroup test_get_git_configs_masks_pat "test_get_git_configs_masks_pat"
+/// @{
+/// @brief Validate listing git configs masks stored PAT values in API-facing responses.
+/// @}
+void test_get_git_configs_masks_pat(void);
+
+/// @defgroup test_create_git_config_persists_config "test_create_git_config_persists_config"
+/// @{
+/// @brief Validate creating git config persists supplied server attributes in backing session.
+/// @}
+void test_create_git_config_persists_config(void);
+
+/// @defgroup test_update_git_config_modifies_record "test_update_git_config_modifies_record"
+/// @{
+/// @brief Validate updating git config modifies mutable fields while preserving masked PAT semantics.
+/// @}
+void test_update_git_config_modifies_record(void);
+
+/// @defgroup SingleConfigDbMock "SingleConfigDbMock"
+/// @{
+/// @}
+void SingleConfigDbMock(void);
+
+/// @defgroup test_update_git_config_raises_404_if_not_found "test_update_git_config_raises_404_if_not_found"
+/// @{
+/// @brief Validate updating non-existent git config raises HTTP 404 contract response.
+/// @}
+void test_update_git_config_raises_404_if_not_found(void);
+
+/// @defgroup test_delete_git_config_removes_record "test_delete_git_config_removes_record"
+/// @{
+/// @brief Validate deleting existing git config removes record and returns success payload.
+/// @}
+void test_delete_git_config_removes_record(void);
+
+/// @defgroup test_test_git_config_validates_connection_successfully "test_test_git_config_validates_connection_successfully"
+/// @{
+/// @brief Validate test-connection endpoint returns success when provider connectivity check passes.
+/// @}
+void test_test_git_config_validates_connection_successfully(void);
+
+/// @defgroup MockGitService "MockGitService"
+/// @{
+/// @}
+void MockGitService(void);
+
+/// @defgroup test_test_git_config_fails_validation "test_test_git_config_fails_validation"
+/// @{
+/// @brief Validate test-connection endpoint raises HTTP 400 when provider connectivity check fails.
+/// @}
+void test_test_git_config_fails_validation(void);
+
+/// @defgroup test_list_gitea_repositories_returns_payload "test_list_gitea_repositories_returns_payload"
+/// @{
+/// @brief Validate gitea repositories endpoint returns normalized list for GITEA provider configs.
+/// @}
+void test_list_gitea_repositories_returns_payload(void);
+
+/// @defgroup test_list_gitea_repositories_rejects_non_gitea "test_list_gitea_repositories_rejects_non_gitea"
+/// @{
+/// @brief Validate gitea repositories endpoint rejects non-GITEA providers with HTTP 400.
+/// @}
+void test_list_gitea_repositories_rejects_non_gitea(void);
+
+/// @defgroup test_create_remote_repository_creates_provider_repo "test_create_remote_repository_creates_provider_repo"
+/// @{
+/// @brief Validate remote repository creation endpoint maps provider response into normalized payload.
+/// @}
+void test_create_remote_repository_creates_provider_repo(void);
+
+/// @defgroup test_init_repository_initializes_and_saves_binding "test_init_repository_initializes_and_saves_binding"
+/// @{
+/// @brief Validate repository initialization endpoint creates local repo and persists dashboard binding.
+/// @}
+void test_init_repository_initializes_and_saves_binding(void);
+
+/// @defgroup TestGitStatusRoute "TestGitStatusRoute"
+/// @{
+/// @brief Validate status endpoint behavior for missing and error repository states.
+/// @}
+void TestGitStatusRoute(void);
+
+/// @defgroup test_get_repository_status_returns_no_repo_payload_for_missing_repo "test_get_repository_status_returns_no_repo_payload_for_missing_repo"
+/// @{
+/// @brief Ensure missing local repository is represented as NO_REPO payload instead of an API error.
+/// @post Route returns a deterministic NO_REPO status payload.
+/// @pre GitService.get_status raises HTTPException(404).
+/// @}
+void test_get_repository_status_returns_no_repo_payload_for_missing_repo(void);
+
+/// @defgroup test_get_repository_status_propagates_non_404_http_exception "test_get_repository_status_propagates_non_404_http_exception"
+/// @{
+/// @brief Ensure HTTP exceptions other than 404 are not masked.
+/// @post Raised exception preserves original status and detail.
+/// @pre GitService.get_status raises HTTPException with non-404 status.
+/// @}
+void test_get_repository_status_propagates_non_404_http_exception(void);
+
+/// @defgroup test_get_repository_diff_propagates_http_exception "test_get_repository_diff_propagates_http_exception"
+/// @{
+/// @brief Ensure diff endpoint preserves domain HTTP errors from GitService.
+/// @post Endpoint raises same HTTPException values.
+/// @pre GitService.get_diff raises HTTPException.
+/// @}
+void test_get_repository_diff_propagates_http_exception(void);
+
+/// @defgroup test_get_history_wraps_unexpected_error_as_500 "test_get_history_wraps_unexpected_error_as_500"
+/// @{
+/// @brief Ensure non-HTTP exceptions in history endpoint become deterministic 500 errors.
+/// @post Endpoint returns HTTPException with status 500 and route context.
+/// @pre GitService.get_commit_history raises ValueError.
+/// @}
+void test_get_history_wraps_unexpected_error_as_500(void);
+
+/// @defgroup test_commit_changes_wraps_unexpected_error_as_500 "test_commit_changes_wraps_unexpected_error_as_500"
+/// @{
+/// @brief Ensure commit endpoint does not leak unexpected errors as 400.
+/// @post Endpoint raises HTTPException(500) with route context.
+/// @pre GitService.commit_changes raises RuntimeError.
+/// @}
+void test_commit_changes_wraps_unexpected_error_as_500(void);
+
+/// @defgroup test_get_repository_status_batch_returns_mixed_statuses "test_get_repository_status_batch_returns_mixed_statuses"
+/// @{
+/// @brief Ensure batch endpoint returns per-dashboard statuses in one response.
+/// @post Returned map includes resolved status for each requested dashboard ID.
+/// @pre Some repositories are missing and some are initialized.
+/// @}
+void test_get_repository_status_batch_returns_mixed_statuses(void);
+
+/// @defgroup test_get_repository_status_batch_marks_item_as_error_on_service_failure "test_get_repository_status_batch_marks_item_as_error_on_service_failure"
+/// @{
+/// @brief Ensure batch endpoint marks failed items as ERROR without failing entire request.
+/// @post Failed dashboard status is marked as ERROR.
+/// @pre GitService raises non-HTTP exception for one dashboard.
+/// @}
+void test_get_repository_status_batch_marks_item_as_error_on_service_failure(void);
+
+/// @defgroup test_get_repository_status_batch_deduplicates_and_truncates_ids "test_get_repository_status_batch_deduplicates_and_truncates_ids"
+/// @{
+/// @brief Ensure batch endpoint protects server from oversized payloads.
+/// @post Result contains unique IDs up to configured cap.
+/// @pre request includes duplicate IDs and more than MAX_REPOSITORY_STATUS_BATCH entries.
+/// @}
+void test_get_repository_status_batch_deduplicates_and_truncates_ids(void);
+
+/// @defgroup test_commit_changes_applies_profile_identity_before_commit "test_commit_changes_applies_profile_identity_before_commit"
+/// @{
+/// @brief Ensure commit route configures repository identity from profile preferences before commit call.
+/// @post git_service.configure_identity receives resolved identity and commit proceeds.
+/// @pre Profile preference contains git_username/git_email for current user.
+/// @}
+void test_commit_changes_applies_profile_identity_before_commit(void);
+
+/// @defgroup test_pull_changes_applies_profile_identity_before_pull "test_pull_changes_applies_profile_identity_before_pull"
+/// @{
+/// @brief Ensure pull route configures repository identity from profile preferences before pull call.
+/// @post git_service.configure_identity receives resolved identity and pull proceeds.
+/// @pre Profile preference contains git_username/git_email for current user.
+/// @}
+void test_pull_changes_applies_profile_identity_before_pull(void);
+
+/// @defgroup test_get_merge_status_returns_service_payload "test_get_merge_status_returns_service_payload"
+/// @{
+/// @brief Ensure merge status route returns service payload as-is.
+/// @post Route response contains has_unfinished_merge=True.
+/// @pre git_service.get_merge_status returns unfinished merge payload.
+/// @}
+void test_get_merge_status_returns_service_payload(void);
+
+/// @defgroup test_resolve_merge_conflicts_passes_resolution_items_to_service "test_resolve_merge_conflicts_passes_resolution_items_to_service"
+/// @{
+/// @brief Ensure merge resolve route forwards parsed resolutions to service.
+/// @post Service receives normalized list and route returns resolved files.
+/// @pre resolve_data has one file strategy.
+/// @}
+void test_resolve_merge_conflicts_passes_resolution_items_to_service(void);
+
+/// @defgroup test_abort_merge_calls_service_and_returns_result "test_abort_merge_calls_service_and_returns_result"
+/// @{
+/// @brief Ensure abort route delegates to service.
+/// @post Route returns aborted status.
+/// @pre Service abort_merge returns aborted status.
+/// @}
+void test_abort_merge_calls_service_and_returns_result(void);
+
+/// @defgroup test_continue_merge_passes_message_and_returns_commit "test_continue_merge_passes_message_and_returns_commit"
+/// @{
+/// @brief Ensure continue route passes commit message to service.
+/// @post Route returns committed status and hash.
+/// @pre continue_data.message is provided.
+/// @}
+void test_continue_merge_passes_message_and_returns_commit(void);
+
+/// @defgroup TestMigrationRoutes "TestMigrationRoutes"
+/// @{
+/// @brief Unit tests for migration API route handlers.
+/// @}
+void TestMigrationRoutes(void);
+
+/// @defgroup _mock_env "_mock_env"
+/// @{
+/// @}
+void _mock_env(void);
+
+/// @defgroup _make_sync_config_manager "_make_sync_config_manager"
+/// @{
+/// @}
+void _make_sync_config_manager(void);
+
+/// @defgroup TestProfileApi "TestProfileApi"
+/// @{
+/// @brief Verifies profile API route contracts for preference read/update and Superset account lookup.
+/// @}
+void TestProfileApi(void);
+
+/// @defgroup mock_profile_route_dependencies "mock_profile_route_dependencies"
+/// @{
+/// @brief Provides deterministic dependency overrides for profile route tests.
+/// @post Dependencies are overridden for current test and restored afterward.
+/// @pre App instance is initialized.
+/// @}
+void mock_profile_route_dependencies(void);
+
+/// @defgroup profile_route_deps_fixture "profile_route_deps_fixture"
+/// @{
+/// @brief Pytest fixture wrapper for profile route dependency overrides.
+/// @post Yields overridden dependencies and clears overrides after test.
+/// @pre None.
+/// @}
+void profile_route_deps_fixture(void);
+
+/// @defgroup _build_preference_response "_build_preference_response"
+/// @{
+/// @brief Builds stable profile preference response payload for route tests.
+/// @post Returns ProfilePreferenceResponse object with deterministic timestamps.
+/// @pre user_id is provided.
+/// @}
+void _build_preference_response(void);
+
+/// @defgroup test_get_profile_preferences_returns_self_payload "test_get_profile_preferences_returns_self_payload"
+/// @{
+/// @brief Verifies GET /api/profile/preferences returns stable self-scoped payload.
+/// @post Response status is 200 and payload contains current user preference.
+/// @pre Authenticated user context is available.
+/// @}
+void test_get_profile_preferences_returns_self_payload(void);
+
+/// @defgroup test_patch_profile_preferences_success "test_patch_profile_preferences_success"
+/// @{
+/// @brief Verifies PATCH /api/profile/preferences persists valid payload through route mapping.
+/// @post Response status is 200 with saved preference payload.
+/// @pre Valid request payload and authenticated user.
+/// @}
+void test_patch_profile_preferences_success(void);
+
+/// @defgroup test_patch_profile_preferences_validation_error "test_patch_profile_preferences_validation_error"
+/// @{
+/// @brief Verifies route maps domain validation failure to HTTP 422 with actionable details.
+/// @post Response status is 422 and includes validation messages.
+/// @pre Service raises ProfileValidationError.
+/// @}
+void test_patch_profile_preferences_validation_error(void);
+
+/// @defgroup test_patch_profile_preferences_cross_user_denied "test_patch_profile_preferences_cross_user_denied"
+/// @{
+/// @brief Verifies route maps domain authorization guard failure to HTTP 403.
+/// @post Response status is 403 with denial message.
+/// @pre Service raises ProfileAuthorizationError.
+/// @}
+void test_patch_profile_preferences_cross_user_denied(void);
+
+/// @defgroup test_lookup_superset_accounts_success "test_lookup_superset_accounts_success"
+/// @{
+/// @brief Verifies lookup route returns success payload with normalized candidates.
+/// @post Response status is 200 and items list is returned.
+/// @pre Valid environment_id and service success response.
+/// @}
+void test_lookup_superset_accounts_success(void);
+
+/// @defgroup test_lookup_superset_accounts_env_not_found "test_lookup_superset_accounts_env_not_found"
+/// @{
+/// @brief Verifies lookup route maps missing environment to HTTP 404.
+/// @post Response status is 404 with explicit message.
+/// @pre Service raises EnvironmentNotFoundError.
+/// @}
+void test_lookup_superset_accounts_env_not_found(void);
+
+/// @defgroup TestReportsApi "TestReportsApi"
+/// @{
+/// @brief Contract tests for GET /api/reports defaults, pagination, and filtering behavior.
+/// @invariant API response contract contains {items,total,page,page_size,has_next,applied_filters}.
+/// @}
+void TestReportsApi(void);
+
+/// @defgroup _make_task "_make_task"
+/// @{
+/// @brief Build Task fixture with controlled timestamps/status for reports list/detail normalization.
+/// @}
+void _make_task(void);
+
+/// @defgroup test_get_reports_default_pagination_contract "test_get_reports_default_pagination_contract"
+/// @{
+/// @brief Validate reports list endpoint default pagination and contract keys for mixed task statuses.
+/// @}
+void test_get_reports_default_pagination_contract(void);
+
+/// @defgroup test_get_reports_filter_and_pagination "test_get_reports_filter_and_pagination"
+/// @{
+/// @brief Validate reports list endpoint applies task-type/status filters and pagination boundaries.
+/// @}
+void test_get_reports_filter_and_pagination(void);
+
+/// @defgroup test_get_reports_handles_mixed_naive_and_aware_datetimes "test_get_reports_handles_mixed_naive_and_aware_datetimes"
+/// @{
+/// @brief Validate reports sorting remains stable when task timestamps mix naive and timezone-aware datetimes.
+/// @}
+void test_get_reports_handles_mixed_naive_and_aware_datetimes(void);
+
+/// @defgroup test_get_reports_invalid_filter_returns_400 "test_get_reports_invalid_filter_returns_400"
+/// @{
+/// @brief Validate reports list endpoint rejects unsupported task type filters with HTTP 400.
+/// @}
+void test_get_reports_invalid_filter_returns_400(void);
+
+/// @defgroup TestReportsDetailApi "TestReportsDetailApi"
+/// @{
+/// @brief Contract tests for GET /api/reports/{report_id} detail endpoint behavior.
+/// @invariant Detail endpoint tests must keep deterministic assertions for success and not-found contracts.
+/// @}
+void TestReportsDetailApi(void);
+
+/// @defgroup test_get_report_detail_success "test_get_report_detail_success"
+/// @{
+/// @brief Validate report detail endpoint returns report body with diagnostics and next actions for existing task.
+/// @}
+void test_get_report_detail_success(void);
+
+/// @defgroup test_get_report_detail_not_found "test_get_report_detail_not_found"
+/// @{
+/// @brief Validate report detail endpoint returns 404 when requested report identifier is absent.
+/// @}
+void test_get_report_detail_not_found(void);
+
+/// @defgroup TestReportsOpenapiConformance "TestReportsOpenapiConformance"
+/// @{
+/// @brief Validate implemented reports payload shape against OpenAPI-required top-level contract fields.
+/// @invariant List and detail payloads include required contract keys.
+/// @}
+void TestReportsOpenapiConformance(void);
+
+/// @defgroup _FakeTaskManager "_FakeTaskManager"
+/// @{
+/// @brief Minimal task-manager fake exposing static task list for OpenAPI conformance checks.
+/// @invariant get_all_tasks returns seeded tasks unchanged.
+/// @}
+void _FakeTaskManager(void);
+
+/// @defgroup _admin_user "_admin_user"
+/// @{
+/// @brief Provide admin principal fixture required by reports routes in conformance tests.
+/// @}
+void _admin_user(void);
+
+/// @defgroup _task "_task"
+/// @{
+/// @brief Construct deterministic task fixture consumed by reports list/detail payload assertions.
+/// @}
+void _task(void);
+
+/// @defgroup test_reports_list_openapi_required_keys "test_reports_list_openapi_required_keys"
+/// @{
+/// @brief Verify reports list endpoint includes all required OpenAPI top-level keys.
+/// @}
+void test_reports_list_openapi_required_keys(void);
+
+/// @defgroup test_reports_detail_openapi_required_keys "test_reports_detail_openapi_required_keys"
+/// @{
+/// @brief Verify reports detail endpoint returns payload containing the report object key.
+/// @}
+void test_reports_detail_openapi_required_keys(void);
+
+/// @defgroup test_tasks_logs_module "test_tasks_logs_module"
+/// @{
+/// @brief Contract testing for task logs API endpoints.
+/// @}
+void test_tasks_logs_module(void);
+
+/// @defgroup test_get_task_logs_success "test_get_task_logs_success"
+/// @{
+/// @brief Validate task logs endpoint returns filtered logs for an existing task.
+/// @}
+void test_get_task_logs_success(void);
+
+/// @defgroup test_get_task_logs_not_found "test_get_task_logs_not_found"
+/// @{
+/// @brief Validate task logs endpoint returns 404 when the task identifier is missing.
+/// @}
+void test_get_task_logs_not_found(void);
+
+/// @defgroup test_get_task_logs_invalid_limit "test_get_task_logs_invalid_limit"
+/// @{
+/// @brief Validate task logs endpoint enforces query validation for limit lower bound.
+/// @}
+void test_get_task_logs_invalid_limit(void);
+
+/// @defgroup test_get_task_log_stats_success "test_get_task_log_stats_success"
+/// @{
+/// @brief Validate log stats endpoint returns success payload for an existing task.
+/// @}
+void test_get_task_log_stats_success(void);
+
+/// @defgroup AdminApi "AdminApi"
+/// @{
+/// @brief Admin API endpoints for user and role management.
+/// @invariant All endpoints in this module require 'Admin' role or 'admin' scope.
+/// @}
+void AdminApi(void);
+
+/// @defgroup list_users "list_users"
+/// @{
+/// @brief Lists all registered users.
+/// @post Returns a list of UserSchema objects.
+/// @pre Current user has 'Admin' role.
+/// @}
+void list_users(void);
+
+/// @defgroup create_user "create_user"
+/// @{
+/// @brief Creates a new local user.
+/// @post New user is created in the database.
+/// @pre Current user has 'Admin' role.
+/// @}
+void create_user(void);
+
+/// @defgroup update_user "update_user"
+/// @{
+/// @brief Updates an existing user.
+/// @post User record is updated in the database.
+/// @pre Current user has 'Admin' role.
+/// @}
+void update_user(void);
+
+/// @defgroup delete_user "delete_user"
+/// @{
+/// @brief Deletes a user.
+/// @post User record is removed from the database.
+/// @pre Current user has 'Admin' role.
+/// @}
+void delete_user(void);
+
+/// @defgroup list_roles "list_roles"
+/// @{
+/// @brief Lists all available roles.
+/// @}
+void list_roles(void);
+
+/// @defgroup create_role "create_role"
+/// @{
+/// @brief Creates a new system role with associated permissions.
+/// @post New Role record is created in auth.db.
+/// @pre Role name must be unique.
+/// @}
+void create_role(void);
+
+/// @defgroup update_role "update_role"
+/// @{
+/// @brief Updates an existing role's metadata and permissions.
+/// @post Role record is updated in auth.db.
+/// @pre role_id must be a valid existing role UUID.
+/// @}
+void update_role(void);
+
+/// @defgroup delete_role "delete_role"
+/// @{
+/// @brief Removes a role from the system.
+/// @post Role record is removed from auth.db.
+/// @pre role_id must be a valid existing role UUID.
+/// @}
+void delete_role(void);
+
+/// @defgroup list_ad_mappings "list_ad_mappings"
+/// @{
+/// @brief Lists all AD Group to Role mappings.
+/// @}
+void list_ad_mappings(void);
+
+/// @defgroup create_ad_mapping "create_ad_mapping"
+/// @{
+/// @brief Creates a new AD Group mapping.
+/// @}
+void create_ad_mapping(void);
+
+/// @defgroup AdminApiKeyRoutes "AdminApiKeyRoutes"
+/// @{
+/// @brief Admin API endpoints for API key management — list, generate (one-time reveal), and revoke.
+/// @invariant DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.
+/// @}
+void AdminApiKeyRoutes(void);
+
+/// @defgroup ApiKeyCreateRequest "ApiKeyCreateRequest"
+/// @{
+/// @}
+void ApiKeyCreateRequest(void);
+
+/// @defgroup ApiKeyCreateResponse "ApiKeyCreateResponse"
+/// @{
+/// @}
+void ApiKeyCreateResponse(void);
+
+/// @defgroup ApiKeyListItem "ApiKeyListItem"
+/// @{
+/// @}
+void ApiKeyListItem(void);
+
+/// @defgroup ApiKeyRevokeResponse "ApiKeyRevokeResponse"
+/// @{
+/// @}
+void ApiKeyRevokeResponse(void);
+
+/// @defgroup list_api_keys "list_api_keys"
+/// @{
+/// @brief List all API keys — NEVER returns key_hash or raw_key.
+/// @post Returns list of ApiKeyListItem without sensitive fields.
+/// @pre Requires admin:settings WRITE permission.
+/// @}
+void list_api_keys(void);
+
+/// @defgroup create_api_key "create_api_key"
+/// @{
+/// @brief Generate a new API key — returns raw key ONCE, never stored or retrievable again.
+/// @post Creates APIKey row with SHA-256 hash. Returns raw key in response.
+/// @pre Requires admin:settings WRITE permission. name is required, at least one permission.
+/// @}
+void create_api_key(void);
+
+/// @defgroup revoke_api_key "revoke_api_key"
+/// @{
+/// @brief Revoke an API key by setting active=False. Preserves row for audit.
+/// @post Sets active=False on the key. Returns 404 if already revoked or not found.
+/// @pre Requires admin:settings WRITE permission.
+/// @}
+void revoke_api_key(void);
+
+/// @defgroup AssistantAdminRoutes "AssistantAdminRoutes"
+/// @{
+/// @brief FastAPI route handlers for assistant admin operations — conversation listing, deletion, history, audit.
+/// @invariant Audit endpoint requires tasks:READ permission.
+/// @}
+void AssistantAdminRoutes(void);
+
+/// @defgroup list_conversations "list_conversations"
+/// @{
+/// @brief Return paginated conversation list for current user with archived flag and last message preview.
+/// @post Conversations are grouped by conversation_id sorted by latest activity descending.
+/// @pre Authenticated user context and valid pagination params.
+/// @}
+void list_conversations(void);
+
+/// @defgroup delete_conversation "delete_conversation"
+/// @{
+/// @brief Soft-delete or hard-delete a conversation and clear its in-memory trace.
+/// @post Conversation records are removed from DB and CONVERSATIONS cache.
+/// @pre conversation_id belongs to current_user.
+/// @}
+void delete_conversation(void);
+
+/// @defgroup get_history "get_history"
+/// @{
+/// @brief Retrieve paginated assistant conversation history for current user.
+/// @post Returns persistent messages and mirrored in-memory snapshot for diagnostics.
+/// @pre Authenticated user is available and page params are valid.
+/// @}
+void get_history(void);
+
+/// @defgroup get_assistant_audit "get_assistant_audit"
+/// @{
+/// @brief Return assistant audit decisions for current user from persistent and in-memory stores.
+/// @post Audit payload is returned in reverse chronological order from DB.
+/// @pre User has tasks:READ permission.
+/// @}
+void get_assistant_audit(void);
+
+/// @defgroup AssistantCommandParser "AssistantCommandParser"
+/// @{
+/// @brief Deterministic RU/EN command text parser that converts user messages into intent payloads.
+/// @invariant Every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+/// @}
+void AssistantCommandParser(void);
+
+/// @defgroup _parse_command "_parse_command"
+/// @{
+/// @brief Deterministically parse RU/EN command text into intent payload.
+/// @invariant every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+/// @post Returns intent dict with domain/operation/entities/confidence/risk fields.
+/// @pre message contains raw user text and config manager resolves environments.
+/// @}
+void _parse_command(void);
+
+/// @defgroup AssistantDatasetReview "AssistantDatasetReview"
+/// @{
+/// @brief Dataset review context loading and intent planning for the assistant API.
+/// @invariant Dataset review operations are always scoped to the owner's session.
+/// @}
+void AssistantDatasetReview(void);
+
+/// @defgroup _serialize_dataset_review_context "_serialize_dataset_review_context"
+/// @{
+/// @brief Build assistant-safe dataset-review context snapshot with masked imported-filter payloads for session-scoped assistant routing.
+/// @post Returns a serializable dictionary containing the complete review context.
+/// @pre session_id is a valid active review session identifier.
+/// @}
+void _serialize_dataset_review_context(void);
+
+/// @defgroup _load_dataset_review_context "_load_dataset_review_context"
+/// @{
+/// @brief Load owner-scoped dataset-review context for assistant planning and grounded response generation.
+/// @post Returns a loaded context object with session data and findings.
+/// @pre session_id is a valid active review session identifier.
+/// @}
+void _load_dataset_review_context(void);
+
+/// @defgroup _extract_dataset_review_target "_extract_dataset_review_target"
+/// @{
+/// @brief Extract structured dataset-review focus target hints embedded in assistant prompts.
+/// @}
+void _extract_dataset_review_target(void);
+
+/// @defgroup _match_dataset_review_field "_match_dataset_review_field"
+/// @{
+/// @brief Resolve one semantic field from assistant-visible context by id or user-visible label.
+/// @}
+void _match_dataset_review_field(void);
+
+/// @defgroup _extract_quoted_segment "_extract_quoted_segment"
+/// @{
+/// @brief Extract one quoted assistant command segment after a label token.
+/// @}
+void _extract_quoted_segment(void);
+
+/// @defgroup _plan_dataset_review_intent "_plan_dataset_review_intent"
+/// @{
+/// @brief Parse session-scoped dataset-review assistant commands before falling back to generic assistant tool routing.
+/// @}
+void _plan_dataset_review_intent(void);
+
+/// @defgroup AssistantDatasetReviewDispatch "AssistantDatasetReviewDispatch"
+/// @{
+/// @brief Dispatch and confirmation handling for dataset-review assistant intents.
+/// @invariant Dataset review dispatch requires valid session version for write operations.
+/// @}
+void AssistantDatasetReviewDispatch(void);
+
+/// @defgroup _dataset_review_conflict_http_exception "_dataset_review_conflict_http_exception"
+/// @{
+/// @brief Convert dataset-review optimistic-lock conflicts into shared 409 assistant semantics.
+/// @}
+void _dataset_review_conflict_http_exception(void);
+
+/// @defgroup _dispatch_dataset_review_intent "_dispatch_dataset_review_intent"
+/// @{
+/// @brief Route confirmed dataset-review assistant intents through existing backend dataset-review APIs and orchestration boundaries.
+/// @post Returns a structured response with planned actions and confirmations.
+/// @pre context contains valid session data and user intent.
+/// @}
+void _dispatch_dataset_review_intent(void);
+
+/// @defgroup AssistantDispatch "AssistantDispatch"
+/// @{
+/// @brief Intent dispatch engine, confirmation summary, and clarification text for the assistant API.
+/// @invariant Unsupported operations are rejected via HTTPException(400).
+/// @}
+void AssistantDispatch(void);
+
+/// @defgroup _clarification_text_for_intent "_clarification_text_for_intent"
+/// @{
+/// @brief Convert technical missing-parameter errors into user-facing clarification prompts.
+/// @post Returned text is human-readable and actionable for target operation.
+/// @pre state was classified as needs_clarification for current intent/error combination.
+/// @}
+void _clarification_text_for_intent(void);
+
+/// @defgroup _async_confirmation_summary "_async_confirmation_summary"
+/// @{
+/// @brief Build human-readable confirmation prompt for an intent before execution.
+/// @post Returns a formatted summary string suitable for display to the user.
+/// @pre actions is a non-empty list of planned review actions.
+/// @}
+void _async_confirmation_summary(void);
+
+/// @defgroup _dispatch_intent "_dispatch_intent"
+/// @{
+/// @brief Execute parsed assistant intent via existing task/plugin/git services.
+/// @invariant unsupported operations are rejected via HTTPException(400).
+/// @post Returns response text, optional task id, and UI actions for follow-up.
+/// @pre intent operation is known and actor permissions are validated per operation.
+/// @}
+void _dispatch_intent(void);
+
+/// @defgroup AssistantHistory "AssistantHistory"
+/// @{
+/// @brief Conversation history, audit trail, and confirmation persistence helpers for the assistant API.
+/// @invariant Failed persistence attempts always rollback before returning.
+/// @}
+void AssistantHistory(void);
+
+/// @defgroup _append_history "_append_history"
+/// @{
+/// @brief Append conversation message to in-memory history buffer.
+/// @invariant every appended entry includes generated message_id and created_at timestamp.
+/// @post Message entry is appended to CONVERSATIONS key list.
+/// @pre user_id and conversation_id identify target conversation bucket.
+/// @}
+void _append_history(void);
+
+/// @defgroup _persist_message "_persist_message"
+/// @{
+/// @brief Persist assistant/user message record to database.
+/// @invariant failed persistence attempts always rollback before returning.
+/// @post Message row is committed or persistence failure is logged.
+/// @pre db session is writable and message payload is serializable.
+/// @}
+void _persist_message(void);
+
+/// @defgroup _audit "_audit"
+/// @{
+/// @brief Append in-memory audit record for assistant decision trace.
+/// @invariant persisted in-memory audit entry always contains created_at in ISO format.
+/// @post ASSISTANT_AUDIT list for user contains new timestamped entry.
+/// @pre payload describes decision/outcome fields.
+/// @}
+void _audit(void);
+
+/// @defgroup _persist_audit "_persist_audit"
+/// @{
+/// @brief Persist structured assistant audit payload in database.
+/// @post Audit row is committed or failure is logged with rollback.
+/// @pre db session is writable and payload is JSON-serializable.
+/// @}
+void _persist_audit(void);
+
+/// @defgroup _persist_confirmation "_persist_confirmation"
+/// @{
+/// @brief Persist confirmation token record to database.
+/// @post Confirmation row exists in persistent storage.
+/// @pre record contains id/user/intent/dispatch/expiry fields.
+/// @}
+void _persist_confirmation(void);
+
+/// @defgroup _update_confirmation_state "_update_confirmation_state"
+/// @{
+/// @brief Update persistent confirmation token lifecycle state.
+/// @post State and consumed_at fields are updated when applicable.
+/// @pre confirmation_id references existing row.
+/// @}
+void _update_confirmation_state(void);
+
+/// @defgroup _load_confirmation_from_db "_load_confirmation_from_db"
+/// @{
+/// @brief Load confirmation token from database into in-memory model.
+/// @post Returns ConfirmationRecord when found, otherwise None.
+/// @pre confirmation_id may or may not exist in storage.
+/// @}
+void _load_confirmation_from_db(void);
+
+/// @defgroup _ensure_conversation "_ensure_conversation"
+/// @{
+/// @brief Resolve active conversation id in memory or create a new one.
+/// @post Returns stable conversation id and updates USER_ACTIVE_CONVERSATION.
+/// @pre user_id identifies current actor.
+/// @}
+void _ensure_conversation(void);
+
+/// @defgroup _resolve_or_create_conversation "_resolve_or_create_conversation"
+/// @{
+/// @brief Resolve active conversation using explicit id, memory cache, or persisted history.
+/// @post Returns conversation id and updates USER_ACTIVE_CONVERSATION cache.
+/// @pre user_id and db session are available.
+/// @}
+void _resolve_or_create_conversation(void);
+
+/// @defgroup _cleanup_history_ttl "_cleanup_history_ttl"
+/// @{
+/// @brief Enforce assistant message retention window by deleting expired rows and in-memory records.
+/// @post Messages older than ASSISTANT_MESSAGE_TTL_DAYS are removed from persistence and memory mirrors.
+/// @pre db session is available and user_id references current actor scope.
+/// @}
+void _cleanup_history_ttl(void);
+
+/// @defgroup _is_conversation_archived "_is_conversation_archived"
+/// @{
+/// @brief Determine archived state for a conversation based on last update timestamp.
+/// @post Returns True when conversation inactivity exceeds archive threshold.
+/// @pre updated_at can be null for empty conversations.
+/// @}
+void _is_conversation_archived(void);
+
+/// @defgroup _coerce_query_bool "_coerce_query_bool"
+/// @{
+/// @brief Normalize bool-like query values for compatibility in direct handler invocations/tests.
+/// @post Returns deterministic boolean flag.
+/// @pre value may be bool, string, or FastAPI Query metadata object.
+/// @}
+void _coerce_query_bool(void);
+
+/// @defgroup AssistantLlmPlanner "AssistantLlmPlanner"
+/// @{
+/// @brief LLM-based intent planning, tool catalog construction, and authorization for the assistant API.
+/// @invariant Tool catalog is filtered by user permissions before being sent to LLM.
+/// @post LLM tool catalog filtered and returned
+/// @pre Assistant routes initialized, user authenticated
+/// @}
+void AssistantLlmPlanner(void);
+
+/// @defgroup _check_any_permission "_check_any_permission"
+/// @{
+/// @brief Validate user against alternative permission checks (logical OR).
+/// @post Returns on first successful permission; raises 403-like HTTPException otherwise.
+/// @pre checks list contains resource-action tuples.
+/// @}
+void _check_any_permission(void);
+
+/// @defgroup _has_any_permission "_has_any_permission"
+/// @{
+/// @brief Check whether user has at least one permission tuple from the provided list.
+/// @post Returns True when at least one permission check passes.
+/// @pre current_user and checks list are valid.
+/// @}
+void _has_any_permission(void);
+
+/// @defgroup _build_tool_catalog "_build_tool_catalog"
+/// @{
+/// @brief Build current-user tool catalog for LLM planner with operation contracts and defaults.
+/// @post Returns list of executable tools filtered by permission and runtime availability.
+/// @pre current_user is authenticated; config/db are available.
+/// @}
+void _build_tool_catalog(void);
+
+/// @defgroup _coerce_intent_entities "_coerce_intent_entities"
+/// @{
+/// @brief Normalize intent entity value types from LLM output to route-compatible values.
+/// @post Returned intent has numeric ids coerced where possible and string values stripped.
+/// @pre intent contains entities dict or missing entities.
+/// @}
+void _coerce_intent_entities(void);
+
+/// @defgroup AssistantLlmPlannerIntent "AssistantLlmPlannerIntent"
+/// @{
+/// @brief LLM-based intent planning and authorization for the assistant API — separated from tool catalog.
+/// @invariant Production deployments always require confirmation.
+/// @post Intent planning registered with confirmation gate
+/// @pre Assistant routes initialized, user authenticated
+/// @}
+void AssistantLlmPlannerIntent(void);
+
+/// @defgroup _plan_intent_with_llm "_plan_intent_with_llm"
+/// @{
+/// @brief Use active LLM provider to select best tool/operation from dynamic catalog.
+/// @post Returns normalized intent dict when planning succeeds; otherwise None.
+/// @pre tools list contains allowed operations for current user.
+/// @}
+void _plan_intent_with_llm(void);
+
+/// @defgroup _authorize_intent "_authorize_intent"
+/// @{
+/// @brief Validate user permissions for parsed intent before confirmation/dispatch.
+/// @post Returns if authorized; raises HTTPException(403) when denied.
+/// @pre intent.operation is present for known assistant command domains.
+/// @}
+void _authorize_intent(void);
+
+/// @defgroup AssistantResolvers "AssistantResolvers"
+/// @{
+/// @brief Environment, dashboard, provider, and task resolution utilities for the assistant API.
+/// @invariant Resolution functions never raise; they return None on failure.
+/// @}
+void AssistantResolvers(void);
+
+/// @defgroup _extract_id "_extract_id"
+/// @{
+/// @brief Extract first regex match group from text by ordered pattern list.
+/// @post Returns first matched token or None.
+/// @pre patterns contain at least one capture group.
+/// @}
+void _extract_id(void);
+
+/// @defgroup _resolve_env_id "_resolve_env_id"
+/// @{
+/// @brief Resolve environment identifier/name token to canonical environment id.
+/// @post Returns matched environment id or None.
+/// @pre config_manager provides environment list.
+/// @}
+void _resolve_env_id(void);
+
+/// @defgroup _is_production_env "_is_production_env"
+/// @{
+/// @brief Determine whether environment token resolves to production-like target.
+/// @post Returns True for production/prod synonyms, else False.
+/// @pre config_manager provides environments or token text is provided.
+/// @}
+void _is_production_env(void);
+
+/// @defgroup _resolve_provider_id "_resolve_provider_id"
+/// @{
+/// @brief Resolve provider token to provider id with active/default fallback.
+/// @post Returns provider id or None when no providers configured.
+/// @pre db session can load provider list through LLMProviderService.
+/// @}
+void _resolve_provider_id(void);
+
+/// @defgroup _get_default_environment_id "_get_default_environment_id"
+/// @{
+/// @brief Resolve default environment id from settings or first configured environment.
+/// @post Returns default environment id or None when environment list is empty.
+/// @pre config_manager returns environments list.
+/// @}
+void _get_default_environment_id(void);
+
+/// @defgroup _resolve_dashboard_id_by_ref "_resolve_dashboard_id_by_ref"
+/// @{
+/// @brief Resolve dashboard id by title or slug reference in selected environment.
+/// @post Returns dashboard id when uniquely matched, otherwise None.
+/// @pre dashboard_ref is a non-empty string-like token.
+/// @}
+void _resolve_dashboard_id_by_ref(void);
+
+/// @defgroup _resolve_dashboard_id_entity "_resolve_dashboard_id_entity"
+/// @{
+/// @brief Resolve dashboard id from intent entities using numeric id or dashboard_ref fallback.
+/// @post Returns resolved dashboard id or None when ambiguous/unresolvable.
+/// @pre entities may contain dashboard_id as int/str and optional dashboard_ref.
+/// @}
+void _resolve_dashboard_id_entity(void);
+
+/// @defgroup _get_environment_name_by_id "_get_environment_name_by_id"
+/// @{
+/// @brief Resolve human-readable environment name by id.
+/// @post Returns matching environment name or fallback id.
+/// @pre environment id may be None.
+/// @}
+void _get_environment_name_by_id(void);
+
+/// @defgroup _extract_result_deep_links "_extract_result_deep_links"
+/// @{
+/// @brief Build deep-link actions to verify task result from assistant chat.
+/// @post Returns zero or more assistant actions for dashboard open/diff.
+/// @pre task object is available.
+/// @}
+void _extract_result_deep_links(void);
+
+/// @defgroup _build_task_observability_summary "_build_task_observability_summary"
+/// @{
+/// @brief Build compact textual summary for completed tasks to reduce "black box" effect.
+/// @post Returns non-empty summary line for known task types or empty string fallback.
+/// @pre task may contain plugin-specific result payload.
+/// @}
+void _build_task_observability_summary(void);
+
+/// @defgroup AssistantRoutes "AssistantRoutes"
+/// @{
+/// @brief FastAPI route handlers for the assistant API — message sending, confirmation, conversation management.
+/// @invariant Risky operations are never executed without valid confirmation token.
+/// @}
+void AssistantRoutes(void);
+
+/// @defgroup send_message "send_message"
+/// @{
+/// @brief Parse assistant command, enforce safety gates, and dispatch executable intent.
+/// @invariant non-safe operations are gated with confirmation before execution from this endpoint.
+/// @post Response state is one of clarification/confirmation/started/success/denied/failed.
+/// @pre Authenticated user is available and message text is non-empty.
+/// @}
+void send_message(void);
+
+/// @defgroup confirm_operation "confirm_operation"
+/// @{
+/// @brief Execute previously requested risky operation after explicit user confirmation.
+/// @post Confirmation state becomes consumed and operation result is persisted in history.
+/// @pre confirmation_id exists, belongs to current user, is pending, and not expired.
+/// @}
+void confirm_operation(void);
+
+/// @defgroup cancel_operation "cancel_operation"
+/// @{
+/// @brief Cancel pending risky operation and mark confirmation token as cancelled.
+/// @post Confirmation becomes cancelled and cannot be executed anymore.
+/// @pre confirmation_id exists, belongs to current user, and is still pending.
+/// @}
+void cancel_operation(void);
+
+/// @defgroup AssistantSchemas "AssistantSchemas"
+/// @{
+/// @brief Pydantic models, in-memory stores, and permission mappings for the assistant API.
+/// @invariant In-memory stores are module-level singletons shared across the assistant package.
+/// @}
+void AssistantSchemas(void);
+
+/// @defgroup AssistantMessageRequest "AssistantMessageRequest"
+/// @{
+/// @brief Input payload for assistant message endpoint.
+/// @invariant message is always non-empty and no longer than 4000 characters.
+/// @post Request object provides message text and optional conversation binding.
+/// @pre message length is within accepted bounds.
+/// @}
+void AssistantMessageRequest(void);
+
+/// @defgroup AssistantAction "AssistantAction"
+/// @{
+/// @brief UI action descriptor returned with assistant responses.
+/// @invariant type and label are required for every UI action.
+/// @post Action can be rendered as button on frontend.
+/// @pre type and label are provided by orchestration logic.
+/// @}
+void AssistantAction(void);
+
+/// @defgroup AssistantMessageResponse "AssistantMessageResponse"
+/// @{
+/// @brief Output payload contract for assistant interaction endpoints.
+/// @invariant created_at and state are always present in endpoint responses.
+/// @post Payload may include task_id/confirmation_id/actions for UI follow-up.
+/// @pre Response includes deterministic state and text.
+/// @}
+void AssistantMessageResponse(void);
+
+/// @defgroup ConfirmationRecord "ConfirmationRecord"
+/// @{
+/// @brief In-memory confirmation token model for risky operation dispatch.
+/// @invariant state defaults to "pending" and expires_at bounds confirmation validity.
+/// @post Record tracks lifecycle state and expiry timestamp.
+/// @pre intent/dispatch/user_id are populated at confirmation request time.
+/// @}
+void ConfirmationRecord(void);
+
+/// @defgroup CONVERSATIONS "CONVERSATIONS"
+/// @{
+/// @brief In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}
+/// @}
+void CONVERSATIONS(void);
+
+/// @defgroup ASSISTANT_AUDIT "ASSISTANT_AUDIT"
+/// @{
+/// @brief In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.
+/// @}
+void ASSISTANT_AUDIT(void);
+
+/// @defgroup CleanReleaseApi "CleanReleaseApi"
+/// @{
+/// @brief Expose clean release endpoints for candidate preparation and subsequent compliance flow.
+/// @invariant API never reports prepared status if preparation errors are present.
+/// @post Candidate preparation, manifest, and compliance routes expose deterministic API payloads without reporting prepared state on failed preparation.
+/// @pre Clean release repository and preparation service dependencies are configured for the current request scope.
+/// @}
+void CleanReleaseApi(void);
+
+/// @defgroup PrepareCandidateRequest "PrepareCandidateRequest"
+/// @{
+/// @brief Request schema for candidate preparation endpoint.
+/// @}
+void PrepareCandidateRequest(void);
+
+/// @defgroup StartCheckRequest "StartCheckRequest"
+/// @{
+/// @brief Request schema for clean compliance check run startup.
+/// @}
+void StartCheckRequest(void);
+
+/// @defgroup RegisterCandidateRequest "RegisterCandidateRequest"
+/// @{
+/// @brief Request schema for candidate registration endpoint.
+/// @}
+void RegisterCandidateRequest(void);
+
+/// @defgroup ImportArtifactsRequest "ImportArtifactsRequest"
+/// @{
+/// @brief Request schema for candidate artifact import endpoint.
+/// @}
+void ImportArtifactsRequest(void);
+
+/// @defgroup BuildManifestRequest "BuildManifestRequest"
+/// @{
+/// @brief Request schema for manifest build endpoint.
+/// @}
+void BuildManifestRequest(void);
+
+/// @defgroup CreateComplianceRunRequest "CreateComplianceRunRequest"
+/// @{
+/// @brief Request schema for compliance run creation with optional manifest pinning.
+/// @}
+void CreateComplianceRunRequest(void);
+
+/// @defgroup register_candidate_v2_endpoint "register_candidate_v2_endpoint"
+/// @{
+/// @brief Register a clean-release candidate for headless lifecycle.
+/// @post Candidate is persisted in DRAFT status.
+/// @pre Candidate identifier is unique.
+/// @}
+void register_candidate_v2_endpoint(void);
+
+/// @defgroup import_candidate_artifacts_v2_endpoint "import_candidate_artifacts_v2_endpoint"
+/// @{
+/// @brief Import candidate artifacts in headless flow.
+/// @post Artifacts are persisted and candidate advances to PREPARED if it was DRAFT.
+/// @pre Candidate exists and artifacts array is non-empty.
+/// @}
+void import_candidate_artifacts_v2_endpoint(void);
+
+/// @defgroup build_candidate_manifest_v2_endpoint "build_candidate_manifest_v2_endpoint"
+/// @{
+/// @brief Build immutable manifest snapshot for prepared candidate.
+/// @post Returns created ManifestDTO with incremented version.
+/// @pre Candidate exists and has imported artifacts.
+/// @}
+void build_candidate_manifest_v2_endpoint(void);
+
+/// @defgroup get_candidate_overview_v2_endpoint "get_candidate_overview_v2_endpoint"
+/// @{
+/// @brief Return expanded candidate overview DTO for headless lifecycle visibility.
+/// @post Returns CandidateOverviewDTO built from the same repository state used by headless US1 endpoints.
+/// @pre Candidate exists.
+/// @}
+void get_candidate_overview_v2_endpoint(void);
+
+/// @defgroup prepare_candidate_endpoint "prepare_candidate_endpoint"
+/// @{
+/// @brief Prepare candidate with policy evaluation and deterministic manifest generation.
+/// @post Returns preparation result including manifest reference and violations.
+/// @pre Candidate and active policy exist in repository.
+/// @}
+void prepare_candidate_endpoint(void);
+
+/// @defgroup start_check "start_check"
+/// @{
+/// @brief Start and finalize a clean compliance check run and persist report artifacts.
+/// @post Returns accepted payload with check_run_id and started_at.
+/// @pre Active policy and candidate exist.
+/// @}
+void start_check(void);
+
+/// @defgroup get_check_status "get_check_status"
+/// @{
+/// @brief Return terminal/intermediate status payload for a check run.
+/// @post Deterministic payload shape includes checks and violations arrays.
+/// @pre check_run_id references an existing run.
+/// @}
+void get_check_status(void);
+
+/// @defgroup get_report "get_report"
+/// @{
+/// @brief Return persisted compliance report by report_id.
+/// @post Returns serialized report object.
+/// @pre report_id references an existing report.
+/// @}
+void get_report(void);
+
+/// @defgroup CleanReleaseV2Api "CleanReleaseV2Api"
+/// @{
+/// @brief Redesigned clean release API for headless candidate lifecycle.
+/// @post Candidate registration, approval, publication, and revocation routes are registered without behavior changes.
+/// @pre Clean release repository dependency is available for candidate lifecycle endpoints.
+/// @}
+void CleanReleaseV2Api(void);
+
+/// @defgroup ApprovalRequest "ApprovalRequest"
+/// @{
+/// @brief Schema for approval request payload.
+/// @}
+void ApprovalRequest(void);
+
+/// @defgroup PublishRequest "PublishRequest"
+/// @{
+/// @brief Schema for publication request payload.
+/// @}
+void PublishRequest(void);
+
+/// @defgroup RevokeRequest "RevokeRequest"
+/// @{
+/// @brief Schema for revocation request payload.
+/// @}
+void RevokeRequest(void);
+
+/// @defgroup register_candidate "register_candidate"
+/// @{
+/// @brief Register a new release candidate.
+/// @post Candidate is saved in repository.
+/// @pre Payload contains required fields (id, version, source_snapshot_ref, created_by).
+/// @}
+void register_candidate(void);
+
+/// @defgroup import_artifacts "import_artifacts"
+/// @{
+/// @brief Associate artifacts with a release candidate.
+/// @post Artifacts are processed (placeholder).
+/// @pre Candidate exists.
+/// @}
+void import_artifacts(void);
+
+/// @defgroup build_manifest "build_manifest"
+/// @{
+/// @brief Generate distribution manifest for a candidate.
+/// @post Manifest is created and saved.
+/// @pre Candidate exists.
+/// @}
+void build_manifest(void);
+
+/// @defgroup approve_candidate_endpoint "approve_candidate_endpoint"
+/// @{
+/// @brief Endpoint to record candidate approval.
+/// @}
+void approve_candidate_endpoint(void);
+
+/// @defgroup reject_candidate_endpoint "reject_candidate_endpoint"
+/// @{
+/// @brief Endpoint to record candidate rejection.
+/// @}
+void reject_candidate_endpoint(void);
+
+/// @defgroup publish_candidate_endpoint "publish_candidate_endpoint"
+/// @{
+/// @brief Endpoint to publish an approved candidate.
+/// @}
+void publish_candidate_endpoint(void);
+
+/// @defgroup revoke_publication_endpoint "revoke_publication_endpoint"
+/// @{
+/// @brief Endpoint to revoke a previous publication.
+/// @}
+void revoke_publication_endpoint(void);
+
+/// @defgroup DashboardsApi "DashboardsApi"
+/// @{
+/// @brief API endpoints for the Dashboard Hub - listing dashboards with Git and task status
+/// @invariant All dashboard responses include git_status and last_task metadata
+/// @post Dashboard responses are projected into DashboardsResponse DTO.
+/// @pre Valid environment configurations exist in ConfigManager.
+/// @}
+void DashboardsApi(void);
+
+/// @defgroup DashboardActionRoutes "DashboardActionRoutes"
+/// @{
+/// @brief Dashboard action route handlers — migrate, backup.
+/// @}
+void DashboardActionRoutes(void);
+
+/// @defgroup migrate_dashboards "migrate_dashboards"
+/// @{
+/// @brief Trigger bulk migration of dashboards from source to target environment
+/// @post Task is created and queued for execution
+/// @pre dashboard_ids is a non-empty list
+/// @}
+void migrate_dashboards(void);
+
+/// @defgroup backup_dashboards "backup_dashboards"
+/// @{
+/// @brief Trigger bulk backup of dashboards with optional cron schedule
+/// @post If schedule is provided, a scheduled task is created
+/// @pre dashboard_ids is a non-empty list
+/// @}
+void backup_dashboards(void);
+
+/// @defgroup DashboardDetailRoutes "DashboardDetailRoutes"
+/// @{
+/// @brief Dashboard detail, db-mappings, task history, thumbnail route handlers.
+/// @}
+void DashboardDetailRoutes(void);
+
+/// @defgroup get_database_mappings "get_database_mappings"
+/// @{
+/// @brief Get database mapping suggestions between source and target environments
+/// @post Returns list of suggested database mappings with confidence scores
+/// @pre source_env_id and target_env_id are valid environment IDs
+/// @}
+void get_database_mappings(void);
+
+/// @defgroup get_dashboard_detail "get_dashboard_detail"
+/// @{
+/// @brief Fetch detailed dashboard info with related charts and datasets
+/// @post Returns dashboard detail payload for overview page
+/// @pre env_id must be valid and dashboard ref (slug or id) must exist
+/// @}
+void get_dashboard_detail(void);
+
+/// @defgroup get_dashboard_tasks_history "get_dashboard_tasks_history"
+/// @{
+/// @brief Returns history of backup and LLM validation tasks for a dashboard.
+/// @post Response contains sorted task history (newest first).
+/// @pre dashboard ref (slug or id) is valid.
+/// @}
+void get_dashboard_tasks_history(void);
+
+/// @defgroup get_dashboard_thumbnail "get_dashboard_thumbnail"
+/// @{
+/// @brief Proxies Superset dashboard thumbnail with cache support.
+/// @post Returns image bytes or 202 when thumbnail is being prepared by Superset.
+/// @pre env_id must exist.
+/// @}
+void get_dashboard_thumbnail(void);
+
+/// @defgroup DashboardHelpers "DashboardHelpers"
+/// @{
+/// @brief Basic helper functions for dashboard route handlers — slug resolution, filter normalization.
+/// @}
+void DashboardHelpers(void);
+
+/// @defgroup _find_dashboard_id_by_slug "_find_dashboard_id_by_slug"
+/// @{
+/// @brief Resolve dashboard numeric ID by slug using Superset list endpoint.
+/// @post Returns dashboard ID when found, otherwise None.
+/// @pre `dashboard_slug` is non-empty.
+/// @}
+void _find_dashboard_id_by_slug(void);
+
+/// @defgroup _resolve_dashboard_id_from_ref "_resolve_dashboard_id_from_ref"
+/// @{
+/// @brief Resolve dashboard ID from slug-first reference with numeric fallback.
+/// @post Returns a valid dashboard ID or raises HTTPException(404).
+/// @pre `dashboard_ref` is provided in route path.
+/// @}
+void _resolve_dashboard_id_from_ref(void);
+
+/// @defgroup _find_dashboard_id_by_slug_async "_find_dashboard_id_by_slug_async"
+/// @{
+/// @brief Resolve dashboard numeric ID by slug using async Superset list endpoint.
+/// @post Returns dashboard ID when found, otherwise None.
+/// @pre dashboard_slug is non-empty.
+/// @}
+void _find_dashboard_id_by_slug_async(void);
+
+/// @defgroup _resolve_dashboard_id_from_ref_async "_resolve_dashboard_id_from_ref_async"
+/// @{
+/// @brief Resolve dashboard ID from slug-first reference using async Superset client.
+/// @post Returns valid dashboard ID or raises HTTPException(404).
+/// @pre dashboard_ref is provided in route path.
+/// @}
+void _resolve_dashboard_id_from_ref_async(void);
+
+/// @defgroup _normalize_filter_values "_normalize_filter_values"
+/// @{
+/// @brief Normalize query filter values to lower-cased non-empty tokens.
+/// @post Returns trimmed normalized list preserving input order.
+/// @pre values may be None or list of strings.
+/// @}
+void _normalize_filter_values(void);
+
+/// @defgroup _dashboard_git_filter_value "_dashboard_git_filter_value"
+/// @{
+/// @brief Build comparable git status token for dashboards filtering.
+/// @post Returns one of ok|diff|no_repo|error|pending.
+/// @pre dashboard payload may contain git_status or None.
+/// @}
+void _dashboard_git_filter_value(void);
+
+/// @defgroup DashboardListingRoutes "DashboardListingRoutes"
+/// @{
+/// @brief Dashboard listing route handler for Dashboard Hub.
+/// @}
+void DashboardListingRoutes(void);
+
+/// @defgroup get_dashboards "get_dashboards"
+/// @{
+/// @brief Fetch list of dashboards from a specific environment with Git status and last task status
+/// @post Response includes effective profile filter metadata for main dashboards page context
+/// @pre page_size must be between 1 and 100 if provided
+/// @}
+void get_dashboards(void);
+
+/// @defgroup DashboardProjection "DashboardProjection"
+/// @{
+/// @brief Dashboard response projection and profile-filter helpers for Dashboard Hub routes.
+/// @}
+void DashboardProjection(void);
+
+/// @defgroup _normalize_actor_alias_token "_normalize_actor_alias_token"
+/// @{
+/// @brief Normalize actor alias token to comparable trim+lower text.
+/// @}
+void _normalize_actor_alias_token(void);
+
+/// @defgroup _normalize_owner_display_token "_normalize_owner_display_token"
+/// @{
+/// @brief Project owner payload value into stable display string for API response contracts.
+/// @}
+void _normalize_owner_display_token(void);
+
+/// @defgroup _normalize_dashboard_owner_values "_normalize_dashboard_owner_values"
+/// @{
+/// @brief Normalize dashboard owners payload to optional list of display strings.
+/// @}
+void _normalize_dashboard_owner_values(void);
+
+/// @defgroup _project_dashboard_response_items "_project_dashboard_response_items"
+/// @{
+/// @brief Project dashboard payloads to response-contract-safe shape.
+/// @}
+void _project_dashboard_response_items(void);
+
+/// @defgroup _get_profile_filter_binding "_get_profile_filter_binding"
+/// @{
+/// @brief Resolve dashboard profile-filter binding through current or legacy profile service contracts.
+/// @}
+void _get_profile_filter_binding(void);
+
+/// @defgroup _resolve_profile_actor_aliases "_resolve_profile_actor_aliases"
+/// @{
+/// @brief Resolve stable actor aliases for profile filtering without per-dashboard detail fan-out.
+/// @}
+void _resolve_profile_actor_aliases(void);
+
+/// @defgroup _matches_dashboard_actor_aliases "_matches_dashboard_actor_aliases"
+/// @{
+/// @brief Apply profile actor matching against multiple aliases (username + optional display name).
+/// @}
+void _matches_dashboard_actor_aliases(void);
+
+/// @defgroup _task_matches_dashboard "_task_matches_dashboard"
+/// @{
+/// @brief Checks whether task params are tied to a specific dashboard and environment.
+/// @}
+void _task_matches_dashboard(void);
+
+/// @defgroup DashboardsRouter "DashboardsRouter"
+/// @{
+/// @brief Single APIRouter instance for all dashboard endpoints.
+/// @}
+void DashboardsRouter(void);
+
+/// @defgroup DashboardSchemas "DashboardSchemas"
+/// @{
+/// @brief DTO classes for the Dashboard Hub API.
+/// @}
+void DashboardSchemas(void);
+
+/// @defgroup GitStatus "GitStatus"
+/// @{
+/// @brief DTO for dashboard Git synchronization status.
+/// @}
+void GitStatus(void);
+
+/// @defgroup DashboardItem "DashboardItem"
+/// @{
+/// @brief DTO representing a single dashboard with projected metadata.
+/// @}
+void DashboardItem(void);
+
+/// @defgroup EffectiveProfileFilter "EffectiveProfileFilter"
+/// @{
+/// @brief Metadata about applied profile filters for UI context.
+/// @}
+void EffectiveProfileFilter(void);
+
+/// @defgroup DashboardsResponse "DashboardsResponse"
+/// @{
+/// @brief Envelope DTO for paginated dashboards list.
+/// @}
+void DashboardsResponse(void);
+
+/// @defgroup DashboardChartItem "DashboardChartItem"
+/// @{
+/// @brief DTO for a chart linked to a dashboard.
+/// @}
+void DashboardChartItem(void);
+
+/// @defgroup DashboardDatasetItem "DashboardDatasetItem"
+/// @{
+/// @brief DTO for a dataset associated with a dashboard.
+/// @}
+void DashboardDatasetItem(void);
+
+/// @defgroup DashboardDetailResponse "DashboardDetailResponse"
+/// @{
+/// @brief Detailed dashboard metadata including children.
+/// @}
+void DashboardDetailResponse(void);
+
+/// @defgroup DashboardTaskHistoryItem "DashboardTaskHistoryItem"
+/// @{
+/// @brief Individual history record entry.
+/// @}
+void DashboardTaskHistoryItem(void);
+
+/// @defgroup DashboardTaskHistoryResponse "DashboardTaskHistoryResponse"
+/// @{
+/// @brief Collection DTO for task history.
+/// @}
+void DashboardTaskHistoryResponse(void);
+
+/// @defgroup DatabaseMapping "DatabaseMapping"
+/// @{
+/// @brief DTO for cross-environment database ID mapping.
+/// @}
+void DatabaseMapping(void);
+
+/// @defgroup DatabaseMappingsResponse "DatabaseMappingsResponse"
+/// @{
+/// @brief Wrapper for database mappings.
+/// @}
+void DatabaseMappingsResponse(void);
+
+/// @defgroup MigrateRequest "MigrateRequest"
+/// @{
+/// @brief DTO for dashboard migration requests.
+/// @}
+void MigrateRequest(void);
+
+/// @defgroup BackupRequest "BackupRequest"
+/// @{
+/// @brief DTO for dashboard backup requests.
+/// @}
+void BackupRequest(void);
+
+/// @defgroup DatasetReviewDependencies "DatasetReviewDependencies"
+/// @{
+/// @brief Dependency injection, serialization helpers, and feature-flag guards for dataset review endpoints.
+/// @}
+void DatasetReviewDependencies(void);
+
+/// @defgroup StartSessionRequest "StartSessionRequest"
+/// @{
+/// @brief Request DTO for starting one dataset review session.
+/// @}
+void StartSessionRequest(void);
+
+/// @defgroup UpdateSessionRequest "UpdateSessionRequest"
+/// @{
+/// @brief Request DTO for lifecycle state updates on an existing session.
+/// @}
+void UpdateSessionRequest(void);
+
+/// @defgroup SessionCollectionResponse "SessionCollectionResponse"
+/// @{
+/// @brief Paginated session collection response.
+/// @}
+void SessionCollectionResponse(void);
+
+/// @defgroup ExportArtifactResponse "ExportArtifactResponse"
+/// @{
+/// @brief Inline export response for documentation or validation outputs.
+/// @}
+void ExportArtifactResponse(void);
+
+/// @defgroup FieldSemanticUpdateRequest "FieldSemanticUpdateRequest"
+/// @{
+/// @brief Request DTO for field-level semantic candidate acceptance or manual override.
+/// @}
+void FieldSemanticUpdateRequest(void);
+
+/// @defgroup FeedbackRequest "FeedbackRequest"
+/// @{
+/// @brief Request DTO for thumbs up/down feedback.
+/// @}
+void FeedbackRequest(void);
+
+/// @defgroup ClarificationAnswerRequest "ClarificationAnswerRequest"
+/// @{
+/// @brief Request DTO for submitting one clarification answer.
+/// @}
+void ClarificationAnswerRequest(void);
+
+/// @defgroup ClarificationSessionSummaryResponse "ClarificationSessionSummaryResponse"
+/// @{
+/// @brief Summary DTO for current clarification session state.
+/// @}
+void ClarificationSessionSummaryResponse(void);
+
+/// @defgroup ClarificationStateResponse "ClarificationStateResponse"
+/// @{
+/// @brief Response DTO for current clarification state and active question payload.
+/// @}
+void ClarificationStateResponse(void);
+
+/// @defgroup ClarificationAnswerResultResponse "ClarificationAnswerResultResponse"
+/// @{
+/// @brief Response DTO for one clarification answer mutation result.
+/// @}
+void ClarificationAnswerResultResponse(void);
+
+/// @defgroup FeedbackResponse "FeedbackResponse"
+/// @{
+/// @brief Minimal response DTO for persisted AI feedback actions.
+/// @}
+void FeedbackResponse(void);
+
+/// @defgroup ApproveMappingRequest "ApproveMappingRequest"
+/// @{
+/// @brief Optional request DTO for explicit mapping approval audit notes.
+/// @}
+void ApproveMappingRequest(void);
+
+/// @defgroup BatchApproveSemanticItemRequest "BatchApproveSemanticItemRequest"
+/// @{
+/// @brief Request DTO for one batch semantic-approval item.
+/// @}
+void BatchApproveSemanticItemRequest(void);
+
+/// @defgroup BatchApproveSemanticRequest "BatchApproveSemanticRequest"
+/// @{
+/// @brief Request DTO for explicit batch semantic approvals.
+/// @}
+void BatchApproveSemanticRequest(void);
+
+/// @defgroup BatchApproveMappingRequest "BatchApproveMappingRequest"
+/// @{
+/// @brief Request DTO for explicit batch mapping approvals.
+/// @}
+void BatchApproveMappingRequest(void);
+
+/// @defgroup PreviewEnqueueResultResponse "PreviewEnqueueResultResponse"
+/// @{
+/// @brief Async preview trigger response exposing only enqueue state.
+/// @}
+void PreviewEnqueueResultResponse(void);
+
+/// @defgroup MappingCollectionResponse "MappingCollectionResponse"
+/// @{
+/// @brief Wrapper for execution mapping list responses.
+/// @}
+void MappingCollectionResponse(void);
+
+/// @defgroup UpdateExecutionMappingRequest "UpdateExecutionMappingRequest"
+/// @{
+/// @brief Request DTO for one manual execution-mapping override update.
+/// @}
+void UpdateExecutionMappingRequest(void);
+
+/// @defgroup LaunchDatasetResponse "LaunchDatasetResponse"
+/// @{
+/// @brief Launch result exposing audited run context and SQL Lab redirect target.
+/// @}
+void LaunchDatasetResponse(void);
+
+/// @defgroup _require_auto_review_flag "_require_auto_review_flag"
+/// @{
+/// @brief Guard US1 dataset review endpoints behind the configured feature flag.
+/// @}
+void _require_auto_review_flag(void);
+
+/// @defgroup _require_clarification_flag "_require_clarification_flag"
+/// @{
+/// @brief Guard clarification-specific US2 endpoints behind the configured feature flag.
+/// @}
+void _require_clarification_flag(void);
+
+/// @defgroup _require_execution_flag "_require_execution_flag"
+/// @{
+/// @brief Guard US3 execution endpoints behind the configured feature flag.
+/// @}
+void _require_execution_flag(void);
+
+/// @defgroup _get_repository "_get_repository"
+/// @{
+/// @brief Build repository dependency.
+/// @}
+void _get_repository(void);
+
+/// @defgroup _get_orchestrator "_get_orchestrator"
+/// @{
+/// @brief Build orchestrator dependency.
+/// @}
+void _get_orchestrator(void);
+
+/// @defgroup _get_clarification_engine "_get_clarification_engine"
+/// @{
+/// @brief Build clarification engine dependency.
+/// @}
+void _get_clarification_engine(void);
+
+/// @defgroup _serialize_session_summary "_serialize_session_summary"
+/// @{
+/// @brief Map session aggregate into stable API summary DTO.
+/// @}
+void _serialize_session_summary(void);
+
+/// @defgroup _serialize_session_detail "_serialize_session_detail"
+/// @{
+/// @brief Map session aggregate into stable API detail DTO.
+/// @}
+void _serialize_session_detail(void);
+
+/// @defgroup _require_session_version_header "_require_session_version_header"
+/// @{
+/// @brief Read the optimistic-lock session version header.
+/// @}
+void _require_session_version_header(void);
+
+/// @defgroup _build_session_version_conflict_http_exception "_build_session_version_conflict_http_exception"
+/// @{
+/// @brief Normalize optimistic-lock conflict errors into HTTP 409 responses.
+/// @}
+void _build_session_version_conflict_http_exception(void);
+
+/// @defgroup _enforce_session_version "_enforce_session_version"
+/// @{
+/// @brief Convert repository optimistic-lock conflicts into deterministic HTTP 409 responses.
+/// @}
+void _enforce_session_version(void);
+
+/// @defgroup _get_owned_session_or_404 "_get_owned_session_or_404"
+/// @{
+/// @brief Resolve one session for current user or collaborator scope, returning 404 when inaccessible.
+/// @}
+void _get_owned_session_or_404(void);
+
+/// @defgroup _require_owner_mutation_scope "_require_owner_mutation_scope"
+/// @{
+/// @brief Enforce owner-only mutation scope.
+/// @}
+void _require_owner_mutation_scope(void);
+
+/// @defgroup _prepare_owned_session_mutation "_prepare_owned_session_mutation"
+/// @{
+/// @brief Resolve owner-scoped mutation session and enforce optimistic-lock version.
+/// @}
+void _prepare_owned_session_mutation(void);
+
+/// @defgroup _commit_owned_session_mutation "_commit_owned_session_mutation"
+/// @{
+/// @brief Centralize session version bumping and commit semantics.
+/// @}
+void _commit_owned_session_mutation(void);
+
+/// @defgroup _record_session_event "_record_session_event"
+/// @{
+/// @brief Persist one explicit audit event for an owned mutation endpoint.
+/// @}
+void _record_session_event(void);
+
+/// @defgroup _serialize_semantic_field "_serialize_semantic_field"
+/// @{
+/// @brief Map one semantic field into stable DTO.
+/// @}
+void _serialize_semantic_field(void);
+
+/// @defgroup _serialize_execution_mapping "_serialize_execution_mapping"
+/// @{
+/// @brief Map one execution mapping into stable DTO.
+/// @}
+void _serialize_execution_mapping(void);
+
+/// @defgroup _serialize_preview "_serialize_preview"
+/// @{
+/// @brief Map one preview into stable DTO.
+/// @}
+void _serialize_preview(void);
+
+/// @defgroup _serialize_run_context "_serialize_run_context"
+/// @{
+/// @brief Map one run context into stable DTO.
+/// @}
+void _serialize_run_context(void);
+
+/// @defgroup _serialize_clarification_question_payload "_serialize_clarification_question_payload"
+/// @{
+/// @brief Convert clarification engine payload into API DTO.
+/// @}
+void _serialize_clarification_question_payload(void);
+
+/// @defgroup _serialize_clarification_state "_serialize_clarification_state"
+/// @{
+/// @brief Convert clarification engine state into API response.
+/// @}
+void _serialize_clarification_state(void);
+
+/// @defgroup _serialize_empty_clarification_state "_serialize_empty_clarification_state"
+/// @{
+/// @brief Return empty clarification payload.
+/// @}
+void _serialize_empty_clarification_state(void);
+
+/// @defgroup _get_latest_clarification_session_or_404 "_get_latest_clarification_session_or_404"
+/// @{
+/// @brief Resolve the latest clarification aggregate or raise.
+/// @}
+void _get_latest_clarification_session_or_404(void);
+
+/// @defgroup _get_owned_mapping_or_404 "_get_owned_mapping_or_404"
+/// @{
+/// @brief Resolve one execution mapping inside one owned session.
+/// @}
+void _get_owned_mapping_or_404(void);
+
+/// @defgroup _get_owned_field_or_404 "_get_owned_field_or_404"
+/// @{
+/// @brief Resolve a semantic field inside one owned session.
+/// @}
+void _get_owned_field_or_404(void);
+
+/// @defgroup _map_candidate_provenance "_map_candidate_provenance"
+/// @{
+/// @brief Translate accepted semantic candidate type into stable field provenance.
+/// @}
+void _map_candidate_provenance(void);
+
+/// @defgroup _resolve_candidate_source_version "_resolve_candidate_source_version"
+/// @{
+/// @brief Resolve the semantic source version for one accepted candidate.
+/// @}
+void _resolve_candidate_source_version(void);
+
+/// @defgroup _update_semantic_field_state "_update_semantic_field_state"
+/// @{
+/// @brief Apply field-level semantic manual override or candidate acceptance.
+/// @post Manual overrides always set manual provenance plus lock.
+/// @}
+void _update_semantic_field_state(void);
+
+/// @defgroup _build_sql_lab_redirect_url "_build_sql_lab_redirect_url"
+/// @{
+/// @brief Build SQL Lab redirect URL.
+/// @}
+void _build_sql_lab_redirect_url(void);
+
+/// @defgroup _build_documentation_export "_build_documentation_export"
+/// @{
+/// @brief Produce session documentation export content.
+/// @}
+void _build_documentation_export(void);
+
+/// @defgroup _build_validation_export "_build_validation_export"
+/// @{
+/// @brief Produce validation-focused export content.
+/// @}
+void _build_validation_export(void);
+
+/// @defgroup DatasetReviewRoutes "DatasetReviewRoutes"
+/// @{
+/// @brief Persist thumbs up/down feedback for clarification question/answer content.
+/// @}
+void DatasetReviewRoutes(void);
+
+/// @defgroup list_sessions "list_sessions"
+/// @{
+/// @brief List resumable dataset review sessions for the current user.
+/// @}
+void list_sessions(void);
+
+/// @defgroup start_session "start_session"
+/// @{
+/// @brief Start a new dataset review session from a Superset link or dataset selection.
+/// @}
+void start_session(void);
+
+/// @defgroup get_session_detail "get_session_detail"
+/// @{
+/// @brief Return the full accessible dataset review session aggregate.
+/// @}
+void get_session_detail(void);
+
+/// @defgroup update_session "update_session"
+/// @{
+/// @brief Update resumable lifecycle status for an owned session.
+/// @}
+void update_session(void);
+
+/// @defgroup delete_session "delete_session"
+/// @{
+/// @brief Archive or hard-delete a session owned by the current user.
+/// @}
+void delete_session(void);
+
+/// @defgroup export_documentation "export_documentation"
+/// @{
+/// @brief Export documentation output for the current session.
+/// @}
+void export_documentation(void);
+
+/// @defgroup export_validation "export_validation"
+/// @{
+/// @brief Export validation findings for the current session.
+/// @}
+void export_validation(void);
+
+/// @defgroup get_clarification_state "get_clarification_state"
+/// @{
+/// @brief Return the current clarification session summary and active question payload.
+/// @}
+void get_clarification_state(void);
+
+/// @defgroup resume_clarification "resume_clarification"
+/// @{
+/// @brief Resume clarification mode on the highest-priority unresolved question.
+/// @}
+void resume_clarification(void);
+
+/// @defgroup record_clarification_answer "record_clarification_answer"
+/// @{
+/// @brief Persist one clarification answer before advancing the active pointer.
+/// @}
+void record_clarification_answer(void);
+
+/// @defgroup update_field_semantic "update_field_semantic"
+/// @{
+/// @brief Apply one field-level semantic candidate decision or manual override.
+/// @}
+void update_field_semantic(void);
+
+/// @defgroup lock_field_semantic "lock_field_semantic"
+/// @{
+/// @brief Lock one semantic field against later automatic overwrite.
+/// @}
+void lock_field_semantic(void);
+
+/// @defgroup unlock_field_semantic "unlock_field_semantic"
+/// @{
+/// @brief Unlock one semantic field so later automated candidate application may replace it.
+/// @}
+void unlock_field_semantic(void);
+
+/// @defgroup approve_batch_semantic_fields "approve_batch_semantic_fields"
+/// @{
+/// @brief Approve multiple semantic candidate decisions in one batch.
+/// @}
+void approve_batch_semantic_fields(void);
+
+/// @defgroup list_execution_mappings "list_execution_mappings"
+/// @{
+/// @brief Return the current mapping-review set for one accessible session.
+/// @}
+void list_execution_mappings(void);
+
+/// @defgroup update_execution_mapping "update_execution_mapping"
+/// @{
+/// @brief Persist one owner-authorized execution-mapping effective value override.
+/// @}
+void update_execution_mapping(void);
+
+/// @defgroup approve_execution_mapping "approve_execution_mapping"
+/// @{
+/// @brief Explicitly approve a warning-sensitive mapping transformation.
+/// @}
+void approve_execution_mapping(void);
+
+/// @defgroup approve_batch_execution_mappings "approve_batch_execution_mappings"
+/// @{
+/// @brief Approve multiple warning-sensitive execution mappings in one batch.
+/// @}
+void approve_batch_execution_mappings(void);
+
+/// @defgroup trigger_preview_generation "trigger_preview_generation"
+/// @{
+/// @brief Trigger Superset-side preview compilation for the current owned execution context.
+/// @}
+void trigger_preview_generation(void);
+
+/// @defgroup launch_dataset "launch_dataset"
+/// @{
+/// @brief Execute the current owned session launch handoff and return audited SQL Lab run context.
+/// @}
+void launch_dataset(void);
+
+/// @defgroup record_field_feedback "record_field_feedback"
+/// @{
+/// @brief Persist thumbs up/down feedback for AI-assisted semantic field content.
+/// @}
+void record_field_feedback(void);
+
+/// @defgroup record_clarification_feedback "record_clarification_feedback"
+/// @{
+/// @brief Persist thumbs up/down feedback for clarification question/answer content.
+/// @}
+void record_clarification_feedback(void);
+
+/// @defgroup DatasetsApi "DatasetsApi"
+/// @{
+/// @brief API endpoints for the Dataset Hub - listing datasets with mapping progress
+/// @invariant All dataset responses include last_task metadata
+/// @post Returns dataset metadata with mapping status.
+/// @pre SupersetClient is available; env_id is valid.
+/// @}
+void DatasetsApi(void);
+
+/// @defgroup MappedFields "MappedFields"
+/// @{
+/// @brief DTO for dataset mapping progress statistics
+/// @}
+void MappedFields(void);
+
+/// @defgroup LastTask "LastTask"
+/// @{
+/// @brief DTO for the most recent task associated with a dataset
+/// @}
+void LastTask(void);
+
+/// @defgroup DatasetItem "DatasetItem"
+/// @{
+/// @brief Summary DTO for a dataset in the hub listing
+/// @}
+void DatasetItem(void);
+
+/// @defgroup LinkedDashboard "LinkedDashboard"
+/// @{
+/// @brief DTO for a dashboard linked to a dataset
+/// @}
+void LinkedDashboard(void);
+
+/// @defgroup DatasetColumn "DatasetColumn"
+/// @{
+/// @brief DTO for a single dataset column's metadata
+/// @}
+void DatasetColumn(void);
+
+/// @defgroup MetricItem "MetricItem"
+/// @{
+/// @brief Pydantic DTO for a dataset metric — carries Superset metric metadata.
+/// @}
+void MetricItem(void);
+
+/// @defgroup DatasetDetailResponse "DatasetDetailResponse"
+/// @{
+/// @brief Detailed DTO for a dataset including columns, linked dashboards, and metrics.
+/// @}
+void DatasetDetailResponse(void);
+
+/// @defgroup StatsCounts "StatsCounts"
+/// @{
+/// @brief Aggregate statistics for the Stats Bar — computed from full dataset list.
+/// @}
+void StatsCounts(void);
+
+/// @defgroup DatasetsResponse "DatasetsResponse"
+/// @{
+/// @brief Paginated response DTO for dataset listings with stats.
+/// @}
+void DatasetsResponse(void);
+
+/// @defgroup TaskResponse "TaskResponse"
+/// @{
+/// @brief Response DTO containing a task ID for tracking
+/// @}
+void TaskResponse(void);
+
+/// @defgroup ColumnDescriptionUpdate "ColumnDescriptionUpdate"
+/// @{
+/// @brief Request DTO for inline-edit of a column description.
+/// @}
+void ColumnDescriptionUpdate(void);
+
+/// @defgroup MetricDescriptionUpdate "MetricDescriptionUpdate"
+/// @{
+/// @brief Request DTO for inline-edit of a metric description.
+/// @}
+void MetricDescriptionUpdate(void);
+
+/// @defgroup get_dataset_ids "get_dataset_ids"
+/// @{
+/// @brief Fetch list of all dataset IDs from a specific environment (without pagination)
+/// @post Returns a list of all dataset IDs
+/// @pre env_id must be a valid environment ID
+/// @}
+void get_dataset_ids(void);
+
+/// @defgroup get_datasets "get_datasets"
+/// @{
+/// @brief Fetch list of datasets from a specific environment with mapping progress and stats.
+/// @post Response includes pagination metadata (page, page_size, total, total_pages) and stats object.
+/// @pre page_size must be between 1 and 100 if provided
+/// @}
+void get_datasets(void);
+
+/// @defgroup MapColumnsRequest "MapColumnsRequest"
+/// @{
+/// @brief Request DTO for initiating column mapping
+/// @}
+void MapColumnsRequest(void);
+
+/// @defgroup map_columns "map_columns"
+/// @{
+/// @brief Trigger bulk column mapping for datasets
+/// @post Task is created and queued for execution
+/// @pre dataset_ids is a non-empty list
+/// @}
+void map_columns(void);
+
+/// @defgroup GenerateDocsRequest "GenerateDocsRequest"
+/// @{
+/// @brief Request DTO for initiating documentation generation
+/// @}
+void GenerateDocsRequest(void);
+
+/// @defgroup generate_docs "generate_docs"
+/// @{
+/// @brief Trigger bulk documentation generation for datasets
+/// @post Task is created and queued for execution
+/// @pre dataset_ids is a non-empty list
+/// @}
+void generate_docs(void);
+
+/// @defgroup get_dataset_detail "get_dataset_detail"
+/// @{
+/// @brief Get detailed dataset information including columns and linked dashboards
+/// @post Returns detailed dataset info with columns and linked dashboards
+/// @pre dataset_id is a valid dataset ID
+/// @}
+void get_dataset_detail(void);
+
+/// @defgroup _strip_html_tags "_strip_html_tags"
+/// @{
+/// @brief Detect and strip HTML tags from a text string. Uses simple regex <[^>]*>.
+/// @}
+void _strip_html_tags(void);
+
+/// @defgroup update_column_description "update_column_description"
+/// @{
+/// @brief Save description for a single dataset column. Internal: GET full dataset from Superset, modify one column's description, PUT back.
+/// @post Column description in Superset is updated. Response confirms success.
+/// @pre dataset_id and column_id must exist in the target environment.
+/// @}
+void update_column_description(void);
+
+/// @defgroup update_metric_description "update_metric_description"
+/// @{
+/// @brief Save description for a single dataset metric. Mirror of update_column_description for metrics.
+/// @post Metric description in Superset is updated.
+/// @pre dataset_id and metric_id must exist in the target environment.
+/// @}
+void update_metric_description(void);
+
+/// @defgroup EnvironmentsApi "EnvironmentsApi"
+/// @{
+/// @brief API endpoints for listing environments and their databases.
+/// @invariant Environment IDs must exist in the configuration.
+/// @}
+void EnvironmentsApi(void);
+
+/// @defgroup _normalize_superset_env_url "_normalize_superset_env_url"
+/// @{
+/// @brief Canonicalize Superset environment URL to base host/path without trailing /api/v1.
+/// @post Returns normalized base URL.
+/// @pre raw_url can be empty.
+/// @}
+void _normalize_superset_env_url(void);
+
+/// @defgroup ScheduleSchema "ScheduleSchema"
+/// @{
+/// @}
+void ScheduleSchema(void);
+
+/// @defgroup EnvironmentResponse "EnvironmentResponse"
+/// @{
+/// @}
+void EnvironmentResponse(void);
+
+/// @defgroup DatabaseResponse "DatabaseResponse"
+/// @{
+/// @}
+void DatabaseResponse(void);
+
+/// @defgroup update_environment_schedule "update_environment_schedule"
+/// @{
+/// @brief Update backup schedule for an environment.
+/// @post Backup schedule updated and scheduler reloaded.
+/// @pre Environment id exists, schedule is valid ScheduleSchema.
+/// @}
+void update_environment_schedule(void);
+
+/// @defgroup get_environment_databases "get_environment_databases"
+/// @{
+/// @brief Fetch the list of databases from a specific environment.
+/// @post Returns a list of database summaries from the environment.
+/// @pre Environment id exists.
+/// @}
+void get_environment_databases(void);
+
+/// @defgroup GitPackage "GitPackage"
+/// @{
+/// @brief Package root for decomposed git routes. Re-exports all public symbols from submodules.
+/// @invariant git_service and os are module-level attributes for test monkeypatch compatibility.
+/// @post Git API package exported
+/// @pre Git service initialized
+/// @}
+void GitPackage(void);
+
+/// @defgroup GitConfigRoutes "GitConfigRoutes"
+/// @{
+/// @brief FastAPI endpoints for Git server configuration CRUD and connection testing.
+/// @}
+void GitConfigRoutes(void);
+
+/// @defgroup get_git_configs "get_git_configs"
+/// @{
+/// @brief List all configured Git servers.
+/// @}
+void get_git_configs(void);
+
+/// @defgroup create_git_config "create_git_config"
+/// @{
+/// @brief Register a new Git server configuration.
+/// @}
+void create_git_config(void);
+
+/// @defgroup update_git_config "update_git_config"
+/// @{
+/// @brief Update an existing Git server configuration.
+/// @}
+void update_git_config(void);
+
+/// @defgroup delete_git_config "delete_git_config"
+/// @{
+/// @brief Remove a Git server configuration.
+/// @}
+void delete_git_config(void);
+
+/// @defgroup test_git_config "test_git_config"
+/// @{
+/// @brief Validate connection to a Git server using provided credentials.
+/// @}
+void test_git_config(void);
+
+/// @defgroup GitDeps "GitDeps"
+/// @{
+/// @brief Shared dependency wiring for monkeypatch-safe git_service access and constants.
+/// @invariant get_git_service() resolves from sys.modules at call time so test monkeypatching
+/// @}
+void GitDeps(void);
+
+/// @defgroup GitEnvironmentRoutes "GitEnvironmentRoutes"
+/// @{
+/// @brief FastAPI endpoint for listing deployment environments.
+/// @}
+void GitEnvironmentRoutes(void);
+
+/// @defgroup GitGiteaRoutes "GitGiteaRoutes"
+/// @{
+/// @brief FastAPI endpoints for Gitea-specific repository operations.
+/// @}
+void GitGiteaRoutes(void);
+
+/// @defgroup list_gitea_repositories "list_gitea_repositories"
+/// @{
+/// @brief List repositories in Gitea for a saved Gitea config.
+/// @}
+void list_gitea_repositories(void);
+
+/// @defgroup create_gitea_repository "create_gitea_repository"
+/// @{
+/// @brief Create a repository in Gitea for a saved Gitea config.
+/// @}
+void create_gitea_repository(void);
+
+/// @defgroup delete_gitea_repository "delete_gitea_repository"
+/// @{
+/// @brief Delete repository in Gitea for a saved Gitea config.
+/// @}
+void delete_gitea_repository(void);
+
+/// @defgroup create_remote_repository "create_remote_repository"
+/// @{
+/// @brief Create repository on remote Git server using selected provider config.
+/// @}
+void create_remote_repository(void);
+
+/// @defgroup GitHelpers "GitHelpers"
+/// @{
+/// @brief Shared helper functions for Git route modules.
+/// @}
+void GitHelpers(void);
+
+/// @defgroup _build_no_repo_status_payload "_build_no_repo_status_payload"
+/// @{
+/// @brief Build a consistent status payload for dashboards without initialized repositories.
+/// @post Returns a stable payload compatible with frontend repository status parsing.
+/// @}
+void _build_no_repo_status_payload(void);
+
+/// @defgroup _handle_unexpected_git_route_error "_handle_unexpected_git_route_error"
+/// @{
+/// @brief Convert unexpected route-level exceptions to stable 500 API responses.
+/// @post Raises HTTPException(500) with route-specific context.
+/// @pre `error` is a non-HTTPException instance.
+/// @}
+void _handle_unexpected_git_route_error(void);
+
+/// @defgroup _resolve_repository_status "_resolve_repository_status"
+/// @{
+/// @brief Resolve repository status for one dashboard with graceful NO_REPO semantics.
+/// @post Returns standard status payload or `NO_REPO` payload when repository path is absent.
+/// @pre `dashboard_id` is a valid integer.
+/// @}
+void _resolve_repository_status(void);
+
+/// @defgroup _get_git_config_or_404 "_get_git_config_or_404"
+/// @{
+/// @brief Resolve GitServerConfig by id or raise 404.
+/// @}
+void _get_git_config_or_404(void);
+
+/// @defgroup _resolve_repo_key_from_ref "_resolve_repo_key_from_ref"
+/// @{
+/// @brief Resolve repository folder key with slug-first strategy and deterministic fallback.
+/// @}
+void _resolve_repo_key_from_ref(void);
+
+/// @defgroup _sanitize_optional_identity_value "_sanitize_optional_identity_value"
+/// @{
+/// @brief Normalize optional identity value into trimmed string or None.
+/// @}
+void _sanitize_optional_identity_value(void);
+
+/// @defgroup _resolve_current_user_git_identity "_resolve_current_user_git_identity"
+/// @{
+/// @brief Resolve configured Git username/email from current user's profile preferences.
+/// @}
+void _resolve_current_user_git_identity(void);
+
+/// @defgroup _apply_git_identity_from_profile "_apply_git_identity_from_profile"
+/// @{
+/// @brief Apply user-scoped Git identity to repository-local config before write/pull operations.
+/// @}
+void _apply_git_identity_from_profile(void);
+
+/// @defgroup GitMergeRoutes "GitMergeRoutes"
+/// @{
+/// @brief FastAPI endpoints for merge operations (status, conflicts, resolve, abort, continue).
+/// @}
+void GitMergeRoutes(void);
+
+/// @defgroup get_merge_status "get_merge_status"
+/// @{
+/// @brief Return unfinished-merge status for repository (web-only recovery support).
+/// @}
+void get_merge_status(void);
+
+/// @defgroup get_merge_conflicts "get_merge_conflicts"
+/// @{
+/// @brief Return conflicted files with mine/theirs previews for web conflict resolver.
+/// @}
+void get_merge_conflicts(void);
+
+/// @defgroup resolve_merge_conflicts "resolve_merge_conflicts"
+/// @{
+/// @brief Apply mine/theirs/manual conflict resolutions from WebUI and stage files.
+/// @}
+void resolve_merge_conflicts(void);
+
+/// @defgroup abort_merge "abort_merge"
+/// @{
+/// @brief Abort unfinished merge from WebUI flow.
+/// @}
+void abort_merge(void);
+
+/// @defgroup continue_merge "continue_merge"
+/// @{
+/// @brief Finalize unfinished merge from WebUI flow.
+/// @}
+void continue_merge(void);
+
+/// @defgroup GitRepoLifecycleRoutes "GitRepoLifecycleRoutes"
+/// @{
+/// @brief FastAPI endpoints for Git lifecycle operations (sync, promote, deploy).
+/// @}
+void GitRepoLifecycleRoutes(void);
+
+/// @defgroup sync_dashboard "sync_dashboard"
+/// @{
+/// @brief Sync dashboard state from Superset to Git using the GitPlugin.
+/// @}
+void sync_dashboard(void);
+
+/// @defgroup promote_dashboard "promote_dashboard"
+/// @{
+/// @brief Promote changes between branches via MR or direct merge.
+/// @}
+void promote_dashboard(void);
+
+/// @defgroup deploy_dashboard "deploy_dashboard"
+/// @{
+/// @brief Deploy dashboard from Git to a target environment.
+/// @}
+void deploy_dashboard(void);
+
+/// @defgroup GitRepoOperationsRoutes "GitRepoOperationsRoutes"
+/// @{
+/// @brief FastAPI endpoints for Git repository operations (commit, push, pull, status, diff, history).
+/// @}
+void GitRepoOperationsRoutes(void);
+
+/// @defgroup commit_changes "commit_changes"
+/// @{
+/// @brief Stage and commit changes in the dashboard's repository.
+/// @}
+void commit_changes(void);
+
+/// @defgroup push_changes "push_changes"
+/// @{
+/// @brief Push local commits to the remote repository.
+/// @}
+void push_changes(void);
+
+/// @defgroup pull_changes "pull_changes"
+/// @{
+/// @brief Pull changes from the remote repository.
+/// @}
+void pull_changes(void);
+
+/// @defgroup get_repository_status "get_repository_status"
+/// @{
+/// @brief Get current Git status for a dashboard repository.
+/// @}
+void get_repository_status(void);
+
+/// @defgroup get_repository_status_batch "get_repository_status_batch"
+/// @{
+/// @brief Get Git statuses for multiple dashboard repositories in one request.
+/// @}
+void get_repository_status_batch(void);
+
+/// @defgroup get_repository_diff "get_repository_diff"
+/// @{
+/// @brief Get Git diff for a dashboard repository.
+/// @}
+void get_repository_diff(void);
+
+/// @defgroup generate_commit_message "generate_commit_message"
+/// @{
+/// @brief Generate a suggested commit message using LLM.
+/// @}
+void generate_commit_message(void);
+
+/// @defgroup GitRepoRoutes "GitRepoRoutes"
+/// @{
+/// @brief FastAPI endpoints for core Git repository operations (init, binding, branches, checkout).
+/// @}
+void GitRepoRoutes(void);
+
+/// @defgroup init_repository "init_repository"
+/// @{
+/// @brief Link a dashboard to a Git repository and perform initial clone/init.
+/// @}
+void init_repository(void);
+
+/// @defgroup get_repository_binding "get_repository_binding"
+/// @{
+/// @brief Return repository binding with provider metadata for selected dashboard.
+/// @}
+void get_repository_binding(void);
+
+/// @defgroup delete_repository "delete_repository"
+/// @{
+/// @brief Delete local repository workspace and DB binding for selected dashboard.
+/// @}
+void delete_repository(void);
+
+/// @defgroup get_branches "get_branches"
+/// @{
+/// @brief List all branches for a dashboard's repository.
+/// @}
+void get_branches(void);
+
+/// @defgroup create_branch "create_branch"
+/// @{
+/// @brief Create a new branch in the dashboard's repository.
+/// @}
+void create_branch(void);
+
+/// @defgroup checkout_branch "checkout_branch"
+/// @{
+/// @brief Switch the dashboard's repository to a specific branch.
+/// @}
+void checkout_branch(void);
+
+/// @defgroup GitRouter "GitRouter"
+/// @{
+/// @brief Shared APIRouter for all Git route modules.
+/// @}
+void GitRouter(void);
+
+/// @defgroup GitSchemas "GitSchemas"
+/// @{
+/// @brief Defines Pydantic models for the Git integration API layer.
+/// @invariant All schemas must be compatible with the FastAPI router.
+/// @}
+void GitSchemas(void);
+
+/// @defgroup GitServerConfigBase "GitServerConfigBase"
+/// @{
+/// @brief Base schema for Git server configuration attributes.
+/// @}
+void GitServerConfigBase(void);
+
+/// @defgroup GitServerConfigUpdate "GitServerConfigUpdate"
+/// @{
+/// @brief Schema for updating an existing Git server configuration.
+/// @}
+void GitServerConfigUpdate(void);
+
+/// @defgroup GitServerConfigCreate "GitServerConfigCreate"
+/// @{
+/// @brief Schema for creating a new Git server configuration.
+/// @}
+void GitServerConfigCreate(void);
+
+/// @defgroup GitServerConfigSchema "GitServerConfigSchema"
+/// @{
+/// @brief Schema for representing a Git server configuration with metadata.
+/// @}
+void GitServerConfigSchema(void);
+
+/// @defgroup GitRepositorySchema "GitRepositorySchema"
+/// @{
+/// @brief Schema for tracking a local Git repository linked to a dashboard.
+/// @}
+void GitRepositorySchema(void);
+
+/// @defgroup BranchSchema "BranchSchema"
+/// @{
+/// @brief Schema for representing a Git branch metadata.
+/// @}
+void BranchSchema(void);
+
+/// @defgroup CommitSchema "CommitSchema"
+/// @{
+/// @brief Schema for representing Git commit details.
+/// @}
+void CommitSchema(void);
+
+/// @defgroup BranchCreate "BranchCreate"
+/// @{
+/// @brief Schema for branch creation requests.
+/// @}
+void BranchCreate(void);
+
+/// @defgroup BranchCheckout "BranchCheckout"
+/// @{
+/// @brief Schema for branch checkout requests.
+/// @}
+void BranchCheckout(void);
+
+/// @defgroup CommitCreate "CommitCreate"
+/// @{
+/// @brief Schema for staging and committing changes.
+/// @}
+void CommitCreate(void);
+
+/// @defgroup ConflictResolution "ConflictResolution"
+/// @{
+/// @brief Schema for resolving merge conflicts.
+/// @}
+void ConflictResolution(void);
+
+/// @defgroup MergeStatusSchema "MergeStatusSchema"
+/// @{
+/// @brief Schema representing unfinished merge status for repository.
+/// @}
+void MergeStatusSchema(void);
+
+/// @defgroup MergeConflictFileSchema "MergeConflictFileSchema"
+/// @{
+/// @brief Schema describing one conflicted file with optional side snapshots.
+/// @}
+void MergeConflictFileSchema(void);
+
+/// @defgroup MergeResolveRequest "MergeResolveRequest"
+/// @{
+/// @brief Request schema for resolving one or multiple merge conflicts.
+/// @}
+void MergeResolveRequest(void);
+
+/// @defgroup MergeContinueRequest "MergeContinueRequest"
+/// @{
+/// @brief Request schema for finishing merge with optional explicit commit message.
+/// @}
+void MergeContinueRequest(void);
+
+/// @defgroup DeploymentEnvironmentSchema "DeploymentEnvironmentSchema"
+/// @{
+/// @brief Schema for representing a target deployment environment.
+/// @}
+void DeploymentEnvironmentSchema(void);
+
+/// @defgroup DeployRequest "DeployRequest"
+/// @{
+/// @brief Schema for dashboard deployment requests.
+/// @}
+void DeployRequest(void);
+
+/// @defgroup RepoInitRequest "RepoInitRequest"
+/// @{
+/// @brief Schema for repository initialization requests.
+/// @}
+void RepoInitRequest(void);
+
+/// @defgroup RepositoryBindingSchema "RepositoryBindingSchema"
+/// @{
+/// @brief Schema describing repository-to-config binding and provider metadata.
+/// @}
+void RepositoryBindingSchema(void);
+
+/// @defgroup RepoStatusBatchRequest "RepoStatusBatchRequest"
+/// @{
+/// @brief Schema for requesting repository statuses for multiple dashboards in a single call.
+/// @}
+void RepoStatusBatchRequest(void);
+
+/// @defgroup RepoStatusBatchResponse "RepoStatusBatchResponse"
+/// @{
+/// @brief Schema for returning repository statuses keyed by dashboard ID.
+/// @}
+void RepoStatusBatchResponse(void);
+
+/// @defgroup GiteaRepoSchema "GiteaRepoSchema"
+/// @{
+/// @brief Schema describing a Gitea repository.
+/// @}
+void GiteaRepoSchema(void);
+
+/// @defgroup GiteaRepoCreateRequest "GiteaRepoCreateRequest"
+/// @{
+/// @brief Request schema for creating a Gitea repository.
+/// @}
+void GiteaRepoCreateRequest(void);
+
+/// @defgroup RemoteRepoSchema "RemoteRepoSchema"
+/// @{
+/// @brief Provider-agnostic remote repository payload.
+/// @}
+void RemoteRepoSchema(void);
+
+/// @defgroup RemoteRepoCreateRequest "RemoteRepoCreateRequest"
+/// @{
+/// @brief Provider-agnostic repository creation request.
+/// @}
+void RemoteRepoCreateRequest(void);
+
+/// @defgroup PromoteRequest "PromoteRequest"
+/// @{
+/// @brief Request schema for branch promotion workflow.
+/// @}
+void PromoteRequest(void);
+
+/// @defgroup PromoteResponse "PromoteResponse"
+/// @{
+/// @brief Response schema for promotion operation result.
+/// @}
+void PromoteResponse(void);
+
+/// @defgroup health_router "health_router"
+/// @{
+/// @brief API endpoints for dashboard health monitoring and status aggregation.
+/// @}
+void health_router(void);
+
+/// @defgroup get_health_summary "get_health_summary"
+/// @{
+/// @brief Get aggregated health status for all dashboards.
+/// @post Returns HealthSummaryResponse.
+/// @pre Caller has read permission for dashboard health view.
+/// @}
+void get_health_summary(void);
+
+/// @defgroup delete_health_report "delete_health_report"
+/// @{
+/// @brief Delete one persisted dashboard validation report from health summary.
+/// @post Validation record is removed; linked task/logs are cleaned when available.
+/// @pre Caller has write permission for tasks/report maintenance.
+/// @}
+void delete_health_report(void);
+
+/// @defgroup LlmRoutes "LlmRoutes"
+/// @{
+/// @brief API routes for LLM provider configuration and management.
+/// @}
+void LlmRoutes(void);
+
+/// @defgroup FetchModelsRequest "FetchModelsRequest"
+/// @{
+/// @brief Pydantic request model for the fetch-models endpoint.
+/// @}
+void FetchModelsRequest(void);
+
+/// @defgroup router "router"
+/// @{
+/// @brief APIRouter instance for LLM routes.
+/// @}
+void router(void);
+
+/// @defgroup _is_valid_runtime_api_key "_is_valid_runtime_api_key"
+/// @{
+/// @brief Validate decrypted runtime API key presence/shape.
+/// @post Returns True only for non-placeholder key.
+/// @pre value can be None.
+/// @}
+void _is_valid_runtime_api_key(void);
+
+/// @defgroup get_providers "get_providers"
+/// @{
+/// @brief Retrieve all LLM provider configurations.
+/// @post Returns list of LLMProviderConfig.
+/// @pre User is authenticated.
+/// @}
+void get_providers(void);
+
+/// @defgroup fetch_models "fetch_models"
+/// @{
+/// @brief Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.
+/// @post Returns a list of available model IDs.
+/// @pre User is authenticated. Either provider_id or base_url+provider_type must be provided.
+/// @}
+void fetch_models(void);
+
+/// @defgroup get_llm_status "get_llm_status"
+/// @{
+/// @brief Returns whether LLM runtime is configured for dashboard validation.
+/// @post configured=true only when an active provider with valid decrypted key exists.
+/// @pre User is authenticated.
+/// @}
+void get_llm_status(void);
+
+/// @defgroup create_provider "create_provider"
+/// @{
+/// @brief Create a new LLM provider configuration.
+/// @post Returns the created LLMProviderConfig.
+/// @pre User is authenticated and has admin permissions.
+/// @}
+void create_provider(void);
+
+/// @defgroup update_provider "update_provider"
+/// @{
+/// @brief Update an existing LLM provider configuration.
+/// @post Returns the updated LLMProviderConfig.
+/// @pre User is authenticated and has admin permissions.
+/// @}
+void update_provider(void);
+
+/// @defgroup delete_provider "delete_provider"
+/// @{
+/// @brief Delete an LLM provider configuration.
+/// @post Returns success status.
+/// @pre User is authenticated and has admin permissions.
+/// @}
+void delete_provider(void);
+
+/// @defgroup test_connection "test_connection"
+/// @{
+/// @brief Test connection to an LLM provider.
+/// @post Returns success status and message.
+/// @pre User is authenticated.
+/// @}
+void test_connection(void);
+
+/// @defgroup test_provider_config "test_provider_config"
+/// @{
+/// @brief Test connection with a provided configuration (not yet saved).
+/// @post Returns success status and message.
+/// @pre User is authenticated.
+/// @}
+void test_provider_config(void);
+
+/// @defgroup MaintenanceRoutesPackage "MaintenanceRoutesPackage"
+/// @{
+/// @brief Maintenance Banner API route package.
+/// @}
+void MaintenanceRoutesPackage(void);
+
+/// @defgroup MaintenanceRouter "MaintenanceRouter"
+/// @{
+/// @brief FastAPI APIRouter for the Maintenance Banner endpoints.
+/// @}
+void MaintenanceRouter(void);
+
+/// @defgroup MaintenanceRoutesModule "MaintenanceRoutesModule"
+/// @{
+/// @brief Route handler stubs for all 7 Maintenance Banner API endpoints with RBAC guards per FR-015.
+/// @invariant RBAC enforced per FR-015 matrix via has_permission() dependency.
+/// @}
+void MaintenanceRoutesModule(void);
+
+/// @defgroup list_dashboard_banners "list_dashboard_banners"
+/// @{
+/// @brief Get per-dashboard banner state for the Dashboard Hub indicator.
+/// @}
+void list_dashboard_banners(void);
+
+/// @defgroup list_events "list_events"
+/// @{
+/// @brief Get active and completed maintenance event lists with affected dashboard counts.
+/// @}
+void list_events(void);
+
+/// @defgroup start_maintenance "start_maintenance"
+/// @{
+/// @brief Start a maintenance event. Validates input, creates event, dispatches TaskManager task.
+/// @}
+void start_maintenance(void);
+
+/// @defgroup end_maintenance "end_maintenance"
+/// @{
+/// @brief End a specific maintenance event by ID. Removes banners from affected dashboards.
+/// @}
+void end_maintenance(void);
+
+/// @defgroup end_all_maintenance "end_all_maintenance"
+/// @{
+/// @brief End all active maintenance events. Removes all banners from all dashboards.
+/// @}
+void end_all_maintenance(void);
+
+/// @defgroup get_maintenance_settings "get_maintenance_settings"
+/// @{
+/// @brief Get current maintenance settings configuration.
+/// @}
+void get_maintenance_settings(void);
+
+/// @defgroup update_maintenance_settings "update_maintenance_settings"
+/// @{
+/// @brief Update maintenance settings. All fields optional for partial update.
+/// @}
+void update_maintenance_settings(void);
+
+/// @defgroup MaintenanceSchemasModule "MaintenanceSchemasModule"
+/// @{
+/// @brief Pydantic models for Maintenance Banner API: request/response schemas per data-model.md.
+/// @invariant All response schemas use the standard envelope shape: { status, data, error, meta }
+/// @}
+void MaintenanceSchemasModule(void);
+
+/// @defgroup MaintenanceStartRequest "MaintenanceStartRequest"
+/// @{
+/// @brief POST /api/maintenance/start request body with environment scoping.
+/// @}
+void MaintenanceStartRequest(void);
+
+/// @defgroup MaintenanceSettingsUpdate "MaintenanceSettingsUpdate"
+/// @{
+/// @brief PUT /api/maintenance/settings request body — all fields optional for partial update.
+/// @}
+void MaintenanceSettingsUpdate(void);
+
+/// @defgroup MaintenanceStartResponse "MaintenanceStartResponse"
+/// @{
+/// @brief Response for /api/maintenance/start — always 202 with task_id.
+/// @}
+void MaintenanceStartResponse(void);
+
+/// @defgroup MaintenanceDashboardResult "MaintenanceDashboardResult"
+/// @{
+/// @brief Describes a single dashboard affected by a maintenance operation.
+/// @}
+void MaintenanceDashboardResult(void);
+
+/// @defgroup MaintenanceFailedDashboard "MaintenanceFailedDashboard"
+/// @{
+/// @brief Describes a dashboard that failed during banner apply/removal.
+/// @}
+void MaintenanceFailedDashboard(void);
+
+/// @defgroup MaintenanceTaskResult "MaintenanceTaskResult"
+/// @{
+/// @brief Result payload for a completed maintenance start task.
+/// @}
+void MaintenanceTaskResult(void);
+
+/// @defgroup MaintenanceEndResponse "MaintenanceEndResponse"
+/// @{
+/// @brief Response for /api/maintenance/{id}/end and /api/maintenance/end-all — always 202 with task_id.
+/// @}
+void MaintenanceEndResponse(void);
+
+/// @defgroup MaintenanceEndTaskResult "MaintenanceEndTaskResult"
+/// @{
+/// @brief Result payload for a completed end maintenance task.
+/// @}
+void MaintenanceEndTaskResult(void);
+
+/// @defgroup MaintenanceEndAllTaskResult "MaintenanceEndAllTaskResult"
+/// @{
+/// @brief Result payload for a completed end-all maintenance task.
+/// @}
+void MaintenanceEndAllTaskResult(void);
+
+/// @defgroup MaintenanceSettingsResponse "MaintenanceSettingsResponse"
+/// @{
+/// @brief Response for GET /api/maintenance/settings.
+/// @}
+void MaintenanceSettingsResponse(void);
+
+/// @defgroup MaintenanceEventItem "MaintenanceEventItem"
+/// @{
+/// @brief Single maintenance event summary for GET /api/maintenance/events.
+/// @}
+void MaintenanceEventItem(void);
+
+/// @defgroup MaintenanceEventListResponse "MaintenanceEventListResponse"
+/// @{
+/// @brief Response for GET /api/maintenance/events.
+/// @}
+void MaintenanceEventListResponse(void);
+
+/// @defgroup MaintenanceDashboardBannerState "MaintenanceDashboardBannerState"
+/// @{
+/// @brief Per-dashboard banner state for GET /api/maintenance/dashboard-banners.
+/// @}
+void MaintenanceDashboardBannerState(void);
+
+/// @defgroup MaintenanceAlreadyActiveResponse "MaintenanceAlreadyActiveResponse"
+/// @{
+/// @brief Response for duplicate /start call — idempotency hit.
+/// @}
+void MaintenanceAlreadyActiveResponse(void);
+
+/// @defgroup MappingsApi "MappingsApi"
+/// @{
+/// @brief API endpoints for managing database mappings and getting suggestions.
+/// @}
+void MappingsApi(void);
+
+/// @defgroup MappingCreate "MappingCreate"
+/// @{
+/// @}
+void MappingCreate(void);
+
+/// @defgroup MappingResponse "MappingResponse"
+/// @{
+/// @}
+void MappingResponse(void);
+
+/// @defgroup SuggestRequest "SuggestRequest"
+/// @{
+/// @}
+void SuggestRequest(void);
+
+/// @defgroup get_mappings "get_mappings"
+/// @{
+/// @brief List all saved database mappings.
+/// @post Returns filtered list of DatabaseMapping records.
+/// @pre db session is injected.
+/// @}
+void get_mappings(void);
+
+/// @defgroup create_mapping "create_mapping"
+/// @{
+/// @brief Create or update a database mapping.
+/// @post DatabaseMapping created or updated in database.
+/// @pre mapping is valid MappingCreate, db session is injected.
+/// @}
+void create_mapping(void);
+
+/// @defgroup suggest_mappings_api "suggest_mappings_api"
+/// @{
+/// @brief Get suggested mappings based on fuzzy matching.
+/// @post Returns mapping suggestions.
+/// @pre request is valid SuggestRequest, config_manager is injected.
+/// @}
+void suggest_mappings_api(void);
+
+/// @defgroup MigrationApi "MigrationApi"
+/// @{
+/// @brief HTTP contract layer for migration orchestration, settings, dry-run, and mapping sync endpoints.
+/// @invariant Migration endpoints never execute with invalid environment references and always return explicit HTTP errors on guard failures.
+/// @post Migration tasks are enqueued or dry-run results are computed and returned.
+/// @pre Backend core services initialized and Database session available.
+/// @}
+void MigrationApi(void);
+
+/// @defgroup execute_migration "execute_migration"
+/// @{
+/// @brief Validate migration selection and enqueue asynchronous migration task execution.
+/// @invariant Migration task dispatch never occurs before source and target environment ids pass guard validation.
+/// @post Returns {"task_id": str, "message": str} when task creation succeeds; emits HTTP_400/HTTP_500 on failure.
+/// @pre DashboardSelection payload is valid and both source/target environments exist.
+/// @}
+void execute_migration(void);
+
+/// @defgroup dry_run_migration "dry_run_migration"
+/// @{
+/// @brief Build pre-flight migration diff and risk summary without mutating target systems.
+/// @invariant Dry-run flow remains read-only and rejects identical source/target environments before service execution.
+/// @post Returns deterministic dry-run payload; emits HTTP_400 for guard violations and HTTP_500 for orchestrator value errors.
+/// @pre DashboardSelection is valid, source and target environments exist, differ, and selected_ids is non-empty.
+/// @}
+void dry_run_migration(void);
+
+/// @defgroup get_migration_settings "get_migration_settings"
+/// @{
+/// @brief Read and return configured migration synchronization cron expression.
+/// @post Returns {"cron": str} reflecting current persisted settings value.
+/// @pre Configuration store is available and requester has READ permission.
+/// @}
+void get_migration_settings(void);
+
+/// @defgroup update_migration_settings "update_migration_settings"
+/// @{
+/// @brief Validate and persist migration synchronization cron expression update.
+/// @post Returns {"cron": str, "status": "updated"} and persists updated cron value.
+/// @pre Payload includes "cron" key and requester has WRITE permission.
+/// @}
+void update_migration_settings(void);
+
+/// @defgroup get_resource_mappings "get_resource_mappings"
+/// @{
+/// @brief Fetch synchronized resource mappings with optional filters and pagination for migration mappings view.
+/// @post Returns {"items": [...], "total": int} where items reflect applied filters and pagination.
+/// @pre skip>=0, 1<=limit<=500, DB session is active, requester has READ permission.
+/// @}
+void get_resource_mappings(void);
+
+/// @defgroup trigger_sync_now "trigger_sync_now"
+/// @{
+/// @brief Trigger immediate ID synchronization for every configured environment.
+/// @post Returns sync summary with synced/failed counts after attempting all environments.
+/// @pre At least one environment is configured and requester has EXECUTE permission.
+/// @}
+void trigger_sync_now(void);
+
+/// @defgroup PluginsRouter "PluginsRouter"
+/// @{
+/// @brief Defines the FastAPI router for plugin-related endpoints, allowing clients to list available plugins.
+/// @}
+void PluginsRouter(void);
+
+/// @defgroup list_plugins "list_plugins"
+/// @{
+/// @brief Retrieve a list of all available plugins.
+/// @post Returns a list of PluginConfig objects.
+/// @pre plugin_loader is injected via Depends.
+/// @}
+void list_plugins(void);
+
+/// @defgroup ProfileApiModule "ProfileApiModule"
+/// @{
+/// @brief Exposes self-scoped profile preference endpoints and environment-based Superset account lookup.
+/// @invariant Endpoints are self-scoped and never mutate another user preference.
+/// @post Profile endpoints registered
+/// @pre Auth middleware configured, database session available
+/// @}
+void ProfileApiModule(void);
+
+/// @defgroup _get_profile_service "_get_profile_service"
+/// @{
+/// @brief Build profile service for current request scope.
+/// @post Returns a ready ProfileService instance.
+/// @pre db session and config manager are available.
+/// @}
+void _get_profile_service(void);
+
+/// @defgroup get_preferences "get_preferences"
+/// @{
+/// @brief Get authenticated user's dashboard filter preference.
+/// @post Returns preference payload for current user only.
+/// @pre Valid JWT and authenticated user context.
+/// @}
+void get_preferences(void);
+
+/// @defgroup update_preferences "update_preferences"
+/// @{
+/// @brief Update authenticated user's dashboard filter preference.
+/// @post Persists normalized preference for current user or raises validation/authorization errors.
+/// @pre Valid JWT and valid request payload.
+/// @}
+void update_preferences(void);
+
+/// @defgroup lookup_superset_accounts "lookup_superset_accounts"
+/// @{
+/// @brief Lookup Superset account candidates in selected environment.
+/// @post Returns success or degraded lookup payload with stable shape.
+/// @pre Valid JWT, authenticated context, and environment_id query parameter.
+/// @}
+void lookup_superset_accounts(void);
+
+/// @defgroup ReportsRouter "ReportsRouter"
+/// @{
+/// @brief FastAPI router for unified task report list and detail retrieval endpoints.
+/// @invariant Endpoints are read-only and do not trigger long-running tasks.
+/// @post Router is configured and endpoints are ready for registration.
+/// @pre Reports service and dependencies are initialized.
+/// @}
+void ReportsRouter(void);
+
+/// @defgroup _parse_csv_enum_list "_parse_csv_enum_list"
+/// @{
+/// @brief Parse comma-separated query value into enum list.
+/// @post Returns enum list or raises HTTP 400 with deterministic machine-readable payload.
+/// @pre raw may be None/empty or comma-separated values.
+/// @}
+void _parse_csv_enum_list(void);
+
+/// @defgroup list_reports "list_reports"
+/// @{
+/// @brief Return paginated unified reports list.
+/// @post deterministic error payload for invalid filters.
+/// @pre authenticated/authorized request and validated query params.
+/// @}
+void list_reports(void);
+
+/// @defgroup get_report_detail "get_report_detail"
+/// @{
+/// @brief Return one normalized report detail with diagnostics and next actions.
+/// @post returns normalized detail envelope or 404 when report is not found.
+/// @pre authenticated/authorized request and existing report_id.
+/// @}
+void get_report_detail(void);
+
+/// @defgroup SettingsRouter "SettingsRouter"
+/// @{
+/// @brief Provides API endpoints for managing application settings and Superset environments.
+/// @invariant All settings changes must be persisted via ConfigManager.
+/// @post Settings are read or written via ConfigManager.
+/// @pre ConfigManager is initialized and accessible.
+/// @}
+void SettingsRouter(void);
+
+/// @defgroup LoggingConfigResponse "LoggingConfigResponse"
+/// @{
+/// @brief Response model for logging configuration with current task log level.
+/// @}
+void LoggingConfigResponse(void);
+
+/// @defgroup _validate_superset_connection_fast "_validate_superset_connection_fast"
+/// @{
+/// @brief Run lightweight Superset connectivity validation without full pagination scan.
+/// @post Raises on auth/API failures; returns None on success.
+/// @pre env contains valid URL and credentials.
+/// @}
+void _validate_superset_connection_fast(void);
+
+/// @defgroup get_settings "get_settings"
+/// @{
+/// @brief Retrieves all application settings.
+/// @post Returns masked AppConfig.
+/// @pre Config manager is available.
+/// @}
+void get_settings(void);
+
+/// @defgroup get_features "get_features"
+/// @{
+/// @brief Public endpoint returning feature flags for frontend sidebar filtering.
+/// @post Returns dict with dataset_review and health_monitor booleans.
+/// @pre Config manager is available.
+/// @}
+void get_features(void);
+
+/// @defgroup get_storage_settings "get_storage_settings"
+/// @{
+/// @brief Retrieves storage-specific settings.
+/// @}
+void get_storage_settings(void);
+
+/// @defgroup update_storage_settings "update_storage_settings"
+/// @{
+/// @brief Updates storage-specific settings.
+/// @post Storage settings are updated and saved.
+/// @}
+void update_storage_settings(void);
+
+/// @defgroup test_environment_connection "test_environment_connection"
+/// @{
+/// @brief Tests the connection to a Superset environment.
+/// @post Returns success or error status.
+/// @pre ID is provided.
+/// @}
+void test_environment_connection(void);
+
+/// @defgroup get_logging_config "get_logging_config"
+/// @{
+/// @brief Retrieves current logging configuration.
+/// @post Returns logging configuration.
+/// @pre Config manager is available.
+/// @}
+void get_logging_config(void);
+
+/// @defgroup update_logging_config "update_logging_config"
+/// @{
+/// @brief Updates logging configuration.
+/// @post Logging configuration is updated and saved.
+/// @pre New logging config is provided.
+/// @}
+void update_logging_config(void);
+
+/// @defgroup ConsolidatedSettingsResponse "ConsolidatedSettingsResponse"
+/// @{
+/// @brief Response model for consolidated application settings.
+/// @}
+void ConsolidatedSettingsResponse(void);
+
+/// @defgroup get_consolidated_settings "get_consolidated_settings"
+/// @{
+/// @brief Retrieves all settings categories in a single call.
+/// @post Returns consolidated settings, provider metadata, and persisted notification payload in one stable response.
+/// @pre Config manager is available and the caller holds admin settings read permission.
+/// @}
+void get_consolidated_settings(void);
+
+/// @defgroup update_consolidated_settings "update_consolidated_settings"
+/// @{
+/// @brief Bulk update application settings from the consolidated view.
+/// @post Settings are updated and saved via ConfigManager.
+/// @pre User has admin permissions, config is valid.
+/// @}
+void update_consolidated_settings(void);
+
+/// @defgroup get_validation_policies "get_validation_policies"
+/// @{
+/// @brief Lists all validation policies.
+/// @}
+void get_validation_policies(void);
+
+/// @defgroup create_validation_policy "create_validation_policy"
+/// @{
+/// @brief Creates a new validation policy.
+/// @}
+void create_validation_policy(void);
+
+/// @defgroup update_validation_policy "update_validation_policy"
+/// @{
+/// @brief Updates an existing validation policy.
+/// @}
+void update_validation_policy(void);
+
+/// @defgroup delete_validation_policy "delete_validation_policy"
+/// @{
+/// @brief Deletes a validation policy.
+/// @}
+void delete_validation_policy(void);
+
+/// @defgroup get_translation_schedules "get_translation_schedules"
+/// @{
+/// @brief Lists all translation schedules joined with translation job names.
+/// @}
+void get_translation_schedules(void);
+
+/// @defgroup storage_routes "storage_routes"
+/// @{
+/// @brief API endpoints for file storage management (backups and repositories).
+/// @invariant All paths must be validated against path traversal.
+/// @}
+void storage_routes(void);
+
+/// @defgroup list_files "list_files"
+/// @{
+/// @brief List all files and directories in the storage system.
+/// @post Returns a list of StoredFile objects.
+/// @pre None.
+/// @}
+void list_files(void);
+
+/// @defgroup delete_file "delete_file"
+/// @{
+/// @brief Delete a specific file or directory.
+/// @post Item is removed from storage.
+/// @pre category must be a valid FileCategory.
+/// @}
+void delete_file(void);
+
+/// @defgroup download_file "download_file"
+/// @{
+/// @brief Retrieve a file for download.
+/// @post Returns a FileResponse.
+/// @pre category must be a valid FileCategory.
+/// @}
+void download_file(void);
+
+/// @defgroup get_file_by_path "get_file_by_path"
+/// @{
+/// @brief Retrieve a file by validated absolute/relative path under storage root.
+/// @post Returns a FileResponse for existing files.
+/// @pre path must resolve under configured storage root.
+/// @}
+void get_file_by_path(void);
+
+/// @defgroup TasksRouter "TasksRouter"
+/// @{
+/// @brief Defines the FastAPI router for task-related endpoints, allowing clients to create, list, and get the status of tasks.
+/// @}
+void TasksRouter(void);
+
+/// @defgroup resume_task "resume_task"
+/// @{
+/// @brief Resume a task that is awaiting input (e.g., passwords).
+/// @post Task resumes execution with provided input.
+/// @pre task must be in AWAITING_INPUT status.
+/// @}
+void resume_task(void);
+
+/// @defgroup TranslateRoutes "TranslateRoutes"
+/// @{
+/// @brief API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.
+/// @post Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed.
+/// @pre API server is running, user is authenticated, database is accessible.
+/// @}
+void TranslateRoutes(void);
+
+/// @defgroup TranslateCorrectionRoutesModule "TranslateCorrectionRoutesModule"
+/// @{
+/// @brief Term correction submission endpoints.
+/// @}
+void TranslateCorrectionRoutesModule(void);
+
+/// @defgroup submit_correction "submit_correction"
+/// @{
+/// @brief Submit a term correction from a run result review.
+/// @post Correction applied with conflict detection.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void submit_correction(void);
+
+/// @defgroup submit_bulk_corrections "submit_bulk_corrections"
+/// @{
+/// @brief Submit multiple term corrections atomically.
+/// @post All corrections applied or none with conflict list.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void submit_bulk_corrections(void);
+
+/// @defgroup TranslateDictionaryRoutesModule "TranslateDictionaryRoutesModule"
+/// @{
+/// @brief Terminology Dictionary CRUD, entries management, and import routes.
+/// @}
+void TranslateDictionaryRoutesModule(void);
+
+/// @defgroup list_dictionaries "list_dictionaries"
+/// @{
+/// @brief List all terminology dictionaries.
+/// @post Returns list of dictionaries with total count.
+/// @pre User has translate.dictionary.view permission.
+/// @}
+void list_dictionaries(void);
+
+/// @defgroup get_dictionary "get_dictionary"
+/// @{
+/// @brief Get a single terminology dictionary by ID.
+/// @post Returns the dictionary with entry_count.
+/// @pre User has translate.dictionary.view permission.
+/// @}
+void get_dictionary(void);
+
+/// @defgroup create_dictionary "create_dictionary"
+/// @{
+/// @brief Create a new terminology dictionary.
+/// @post Returns the created dictionary.
+/// @pre User has translate.dictionary.create permission.
+/// @}
+void create_dictionary(void);
+
+/// @defgroup update_dictionary "update_dictionary"
+/// @{
+/// @brief Update an existing terminology dictionary.
+/// @post Returns the updated dictionary.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void update_dictionary(void);
+
+/// @defgroup delete_dictionary "delete_dictionary"
+/// @{
+/// @brief Delete a terminology dictionary, blocked if attached to active/scheduled jobs.
+/// @post Dictionary is deleted.
+/// @pre User has translate.dictionary.delete permission.
+/// @}
+void delete_dictionary(void);
+
+/// @defgroup list_dictionary_entries "list_dictionary_entries"
+/// @{
+/// @brief List entries for a dictionary, optionally filtered by language pair.
+/// @post Returns paginated list of entries with language pair fields.
+/// @pre User has translate.dictionary.view permission.
+/// @}
+void list_dictionary_entries(void);
+
+/// @defgroup add_dictionary_entry "add_dictionary_entry"
+/// @{
+/// @brief Add a new entry to a dictionary.
+/// @post Entry is created.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void add_dictionary_entry(void);
+
+/// @defgroup edit_dictionary_entry "edit_dictionary_entry"
+/// @{
+/// @brief Update an existing dictionary entry.
+/// @post Entry is updated.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void edit_dictionary_entry(void);
+
+/// @defgroup delete_dictionary_entry "delete_dictionary_entry"
+/// @{
+/// @brief Delete a dictionary entry.
+/// @post Entry is deleted.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void delete_dictionary_entry(void);
+
+/// @defgroup import_dictionary_entries "import_dictionary_entries"
+/// @{
+/// @brief Import entries into a terminology dictionary from CSV/TSV content.
+/// @post Entries are imported per conflict mode.
+/// @pre User has translate.dictionary.edit permission.
+/// @}
+void import_dictionary_entries(void);
+
+/// @defgroup TranslateHelpersModule "TranslateHelpersModule"
+/// @{
+/// @brief Shared helper functions for translate route handlers.
+/// @}
+void TranslateHelpersModule(void);
+
+/// @defgroup _run_to_response "_run_to_response"
+/// @{
+/// @brief Convert TranslationRun ORM to response dict.
+/// @}
+void _run_to_response(void);
+
+/// @defgroup _dict_to_response "_dict_to_response"
+/// @{
+/// @brief Convert a TerminologyDictionary ORM model to a response dict with computed entry_count.
+/// @}
+void _dict_to_response(void);
+
+/// @defgroup _get_dictionary_entry_counts "_get_dictionary_entry_counts"
+/// @{
+/// @brief Get entry counts for a list of dictionary IDs.
+/// @}
+void _get_dictionary_entry_counts(void);
+
+/// @defgroup TranslateJobRoutesModule "TranslateJobRoutesModule"
+/// @{
+/// @brief Translation Job CRUD and datasource column routes.
+/// @}
+void TranslateJobRoutesModule(void);
+
+/// @defgroup list_jobs "list_jobs"
+/// @{
+/// @brief List all translation jobs.
+/// @post Returns list of translation jobs.
+/// @pre User has translate.job.view permission.
+/// @}
+void list_jobs(void);
+
+/// @defgroup get_job "get_job"
+/// @{
+/// @brief Get a single translation job by ID.
+/// @post Returns the translation job.
+/// @pre User has translate.job.view permission.
+/// @}
+void get_job(void);
+
+/// @defgroup create_job "create_job"
+/// @{
+/// @brief Create a new translation job.
+/// @post Returns the created translation job.
+/// @pre User has translate.job.create permission.
+/// @}
+void create_job(void);
+
+/// @defgroup update_job "update_job"
+/// @{
+/// @brief Update an existing translation job.
+/// @post Returns the updated translation job.
+/// @pre User has translate.job.edit permission.
+/// @}
+void update_job(void);
+
+/// @defgroup delete_job "delete_job"
+/// @{
+/// @brief Delete a translation job.
+/// @post Job is deleted.
+/// @pre User has translate.job.delete permission.
+/// @}
+void delete_job(void);
+
+/// @defgroup duplicate_job "duplicate_job"
+/// @{
+/// @brief Duplicate a translation job.
+/// @post Returns the duplicated job with status DRAFT.
+/// @pre User has translate.job.create permission.
+/// @}
+void duplicate_job(void);
+
+/// @defgroup get_datasource_columns "get_datasource_columns"
+/// @{
+/// @brief Get column metadata and database dialect for a Superset datasource.
+/// @post Returns column list with metadata and database_dialect.
+/// @pre User has translate.job.view permission.
+/// @}
+void get_datasource_columns(void);
+
+/// @defgroup check_target_schema "check_target_schema"
+/// @{
+/// @brief Проверяет схему целевой таблицы: какие колонки ожидаются, какие есть, каких не хватает.
+/// @}
+void check_target_schema(void);
+
+/// @defgroup TranslateMetricsRoutesModule "TranslateMetricsRoutesModule"
+/// @{
+/// @brief Translation Metrics endpoints.
+/// @}
+void TranslateMetricsRoutesModule(void);
+
+/// @defgroup get_metrics "get_metrics"
+/// @{
+/// @brief Get translation metrics, optionally filtered by job.
+/// @post Returns metrics data.
+/// @pre User has translate.metrics.view permission.
+/// @}
+void get_metrics(void);
+
+/// @defgroup get_job_metrics "get_job_metrics"
+/// @{
+/// @brief Get aggregated metrics for a specific job.
+/// @post Returns metrics dict.
+/// @pre User has translate.metrics.view permission.
+/// @}
+void get_job_metrics(void);
+
+/// @defgroup TranslatePreviewRoutesModule "TranslatePreviewRoutesModule"
+/// @{
+/// @brief Translation Preview session management routes.
+/// @}
+void TranslatePreviewRoutesModule(void);
+
+/// @defgroup preview_translation "preview_translation"
+/// @{
+/// @brief Preview a translation before applying it.
+/// @post Returns a preview session with records and cost estimation.
+/// @pre User has translate.job.execute permission.
+/// @}
+void preview_translation(void);
+
+/// @defgroup update_preview_row "update_preview_row"
+/// @{
+/// @brief Approve, edit, or reject a preview row (optionally per language).
+/// @post Preview row status is updated.
+/// @pre User has translate.job.execute permission.
+/// @}
+void update_preview_row(void);
+
+/// @defgroup accept_preview_session "accept_preview_session"
+/// @{
+/// @brief Accept a preview session, marking it as the quality gate for full execution.
+/// @post Preview session is marked as APPLIED; full execution can proceed.
+/// @pre User has translate.job.execute permission. Job has an ACTIVE preview session.
+/// @}
+void accept_preview_session(void);
+
+/// @defgroup apply_preview "apply_preview"
+/// @{
+/// @brief Apply a preview session (alias for accept when accepting at session level).
+/// @post Preview is applied.
+/// @pre User has translate.job.execute permission.
+/// @}
+void apply_preview(void);
+
+/// @defgroup get_preview_records "get_preview_records"
+/// @{
+/// @brief Get records for a preview session.
+/// @post Returns list of preview records.
+/// @pre User has translate.job.view permission.
+/// @}
+void get_preview_records(void);
+
+/// @defgroup TranslateRouterModule "TranslateRouterModule"
+/// @{
+/// @brief APIRouter instance for translate routes.
+/// @}
+void TranslateRouterModule(void);
+
+/// @defgroup translate_router "translate_router"
+/// @{
+/// @brief APIRouter instance for all translate sub-routes.
+/// @}
+void translate_router(void);
+
+/// @defgroup TranslateRunListRoutesModule "TranslateRunListRoutesModule"
+/// @{
+/// @brief Translation Run listing, detail, and CSV download routes (cross-job).
+/// @}
+void TranslateRunListRoutesModule(void);
+
+/// @defgroup download_skipped_csv "download_skipped_csv"
+/// @{
+/// @brief Download a CSV of skipped translation records from a run.
+/// @post Returns CSV file of skipped records.
+/// @pre User has translate.job.view permission.
+/// @}
+void download_skipped_csv(void);
+
+/// @defgroup TranslateRunRoutesModule "TranslateRunRoutesModule"
+/// @{
+/// @brief Translation Run execution, history, status, records and batches routes.
+/// @}
+void TranslateRunRoutesModule(void);
+
+/// @defgroup run_translation "run_translation"
+/// @{
+/// @brief Execute a translation job (trigger a run).
+/// @post Returns the created translation run.
+/// @pre User has translate.job.execute permission.
+/// @}
+void run_translation(void);
+
+/// @defgroup retry_run "retry_run"
+/// @{
+/// @brief Retry failed batches in a translation run.
+/// @post Returns the updated translation run.
+/// @pre User has translate.job.execute permission.
+/// @}
+void retry_run(void);
+
+/// @defgroup retry_insert "retry_insert"
+/// @{
+/// @brief Retry the SQL insert phase for a completed run.
+/// @post Returns the updated run.
+/// @pre User has translate.job.execute permission.
+/// @}
+void retry_insert(void);
+
+/// @defgroup cancel_run "cancel_run"
+/// @{
+/// @brief Cancel a running translation.
+/// @post Run is cancelled.
+/// @pre User has translate.job.execute permission.
+/// @}
+void cancel_run(void);
+
+/// @defgroup get_run_history "get_run_history"
+/// @{
+/// @brief Get run history for a translation job.
+/// @post Returns list of runs.
+/// @pre User has translate.history.view permission.
+/// @}
+void get_run_history(void);
+
+/// @defgroup get_run_status "get_run_status"
+/// @{
+/// @brief Get status and statistics for a translation run.
+/// @post Returns run details with statistics.
+/// @pre User has translate.history.view permission.
+/// @}
+void get_run_status(void);
+
+/// @defgroup get_run_records "get_run_records"
+/// @{
+/// @brief Get paginated records for a translation run.
+/// @post Returns paginated records.
+/// @pre User has translate.history.view permission.
+/// @}
+void get_run_records(void);
+
+/// @defgroup get_batches "get_batches"
+/// @{
+/// @brief Get batches for a translation run.
+/// @post Returns list of batches.
+/// @pre User has translate.job.view permission.
+/// @}
+void get_batches(void);
+
+/// @defgroup override_detected_language "override_detected_language"
+/// @{
+/// @brief Manually override the detected source language for a specific translation language entry.
+/// @post TranslationLanguage.source_language_detected is updated; language_overridden is set to True.
+/// @pre User has translate.job.execute permission. Run, record, and language entry exist.
+/// @}
+void override_detected_language(void);
+
+/// @defgroup inline_edit_translation "inline_edit_translation"
+/// @{
+/// @brief Apply an inline correction to a translated value on a completed run result.
+/// @post TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.
+/// @pre User has translate.job.execute permission. Run, record, and language entry exist.
+/// @}
+void inline_edit_translation(void);
+
+/// @defgroup bulk_find_replace "bulk_find_replace"
+/// @{
+/// @brief Perform bulk find-and-replace on translated values within a run.
+/// @post If preview=false, matching translations are updated. Optional dictionary submission.
+/// @pre User has translate.job.execute permission. Run exists.
+/// @}
+void bulk_find_replace(void);
+
+/// @defgroup TranslateScheduleRoutesModule "TranslateScheduleRoutesModule"
+/// @{
+/// @brief Translation Schedule management routes.
+/// @}
+void TranslateScheduleRoutesModule(void);
+
+/// @defgroup get_schedule "get_schedule"
+/// @{
+/// @brief Get the schedule for a translation job.
+/// @post Returns the schedule configuration.
+/// @pre User has translate.schedule.view permission.
+/// @}
+void get_schedule(void);
+
+/// @defgroup set_schedule "set_schedule"
+/// @{
+/// @brief Set or update the schedule for a translation job.
+/// @post Schedule is created or updated.
+/// @pre User has translate.schedule.manage permission.
+/// @}
+void set_schedule(void);
+
+/// @defgroup enable_schedule "enable_schedule"
+/// @{
+/// @brief Enable a schedule for a translation job.
+/// @post Schedule is enabled.
+/// @pre User has translate.schedule.manage permission.
+/// @}
+void enable_schedule(void);
+
+/// @defgroup disable_schedule "disable_schedule"
+/// @{
+/// @brief Disable a schedule for a translation job.
+/// @post Schedule is disabled.
+/// @pre User has translate.schedule.manage permission.
+/// @}
+void disable_schedule(void);
+
+/// @defgroup delete_schedule "delete_schedule"
+/// @{
+/// @brief Delete the schedule for a translation job.
+/// @post Schedule is removed.
+/// @pre User has translate.schedule.manage permission.
+/// @}
+void delete_schedule(void);
+
+/// @defgroup get_next_executions "get_next_executions"
+/// @{
+/// @brief Preview next N executions for a job's schedule.
+/// @post Returns next execution times.
+/// @pre User has translate.schedule.view permission.
+/// @}
+void get_next_executions(void);
+
+/// @defgroup ValidationRoutes "ValidationRoutes"
+/// @{
+/// @brief API routes for validation task management and run history.
+/// @}
+void ValidationRoutes(void);
+
+/// @defgroup _get_task_service "_get_task_service"
+/// @{
+/// @}
+void _get_task_service(void);
+
+/// @defgroup _get_run_service "_get_run_service"
+/// @{
+/// @}
+void _get_run_service(void);
+
+/// @defgroup list_tasks "list_tasks"
+/// @{
+/// @}
+void list_tasks(void);
+
+/// @defgroup update_task "update_task"
+/// @{
+/// @}
+void update_task(void);
+
+/// @defgroup delete_task "delete_task"
+/// @{
+/// @}
+void delete_task(void);
+
+/// @defgroup trigger_run "trigger_run"
+/// @{
+/// @}
+void trigger_run(void);
+
+/// @defgroup list_runs "list_runs"
+/// @{
+/// @}
+void list_runs(void);
+
+/// @defgroup get_run_detail "get_run_detail"
+/// @{
+/// @}
+void get_run_detail(void);
+
+/// @defgroup delete_run "delete_run"
+/// @{
+/// @}
+void delete_run(void);
+
+/// @defgroup ValidationApiTests "ValidationApiTests"
+/// @{
+/// @brief Unit tests for validation task CRUD and run history API endpoints.
+/// @invariant provider_id must reference a multimodal LLM provider for creation
+/// @}
+void ValidationApiTests(void);
+
+/// @defgroup test_list_tasks_success "test_list_tasks_success"
+/// @{
+/// @brief GET /validation/tasks returns paginated task list with filters.
+/// @}
+void test_list_tasks_success(void);
+
+/// @defgroup test_list_tasks_pagination "test_list_tasks_pagination"
+/// @{
+/// @brief Pagination query params are validated: page >= 1, page_size 1-100.
+/// @}
+void test_list_tasks_pagination(void);
+
+/// @defgroup test_list_tasks_service_error "test_list_tasks_service_error"
+/// @{
+/// @brief Service ValueError becomes 400 on list_tasks.
+/// @}
+void test_list_tasks_service_error(void);
+
+/// @defgroup test_create_task_success "test_create_task_success"
+/// @{
+/// @brief POST /validation/tasks with valid payload returns 201.
+/// @}
+void test_create_task_success(void);
+
+/// @defgroup test_create_task_missing_fields "test_create_task_missing_fields"
+/// @{
+/// @brief POST with missing required fields returns 422.
+/// @}
+void test_create_task_missing_fields(void);
+
+/// @defgroup test_create_task_invalid_provider "test_create_task_invalid_provider"
+/// @{
+/// @brief POST with non-multimodal provider returns 422.
+/// @}
+void test_create_task_invalid_provider(void);
+
+/// @defgroup test_get_task_success "test_get_task_success"
+/// @{
+/// @brief GET /validation/tasks/{id} returns task with recent_runs.
+/// @}
+void test_get_task_success(void);
+
+/// @defgroup test_get_task_not_found "test_get_task_not_found"
+/// @{
+/// @brief GET for nonexistent task returns 404.
+/// @}
+void test_get_task_not_found(void);
+
+/// @defgroup test_update_task_success "test_update_task_success"
+/// @{
+/// @brief PUT /validation/tasks/{id} updates task and returns updated object.
+/// @}
+void test_update_task_success(void);
+
+/// @defgroup test_update_task_not_found "test_update_task_not_found"
+/// @{
+/// @brief PUT for nonexistent task returns 404.
+/// @}
+void test_update_task_not_found(void);
+
+/// @defgroup test_delete_task_success "test_delete_task_success"
+/// @{
+/// @brief DELETE /validation/tasks/{id} returns 204.
+/// @}
+void test_delete_task_success(void);
+
+/// @defgroup test_delete_task_not_found "test_delete_task_not_found"
+/// @{
+/// @brief DELETE for nonexistent task returns 404.
+/// @}
+void test_delete_task_not_found(void);
+
+/// @defgroup test_delete_task_with_runs_flag "test_delete_task_with_runs_flag"
+/// @{
+/// @brief DELETE with delete_runs=true passes query param to service.
+/// @}
+void test_delete_task_with_runs_flag(void);
+
+/// @defgroup test_trigger_run_success "test_trigger_run_success"
+/// @{
+/// @brief POST /validation/tasks/{id}/run spawns a validation task.
+/// @}
+void test_trigger_run_success(void);
+
+/// @defgroup test_trigger_run_not_found "test_trigger_run_not_found"
+/// @{
+/// @brief POST for nonexistent task returns 422.
+/// @}
+void test_trigger_run_not_found(void);
+
+/// @defgroup test_trigger_run_no_dashboards "test_trigger_run_no_dashboards"
+/// @{
+/// @brief Trigger fails with 422 when task has no dashboard IDs.
+/// @}
+void test_trigger_run_no_dashboards(void);
+
+/// @defgroup test_list_runs_success "test_list_runs_success"
+/// @{
+/// @brief GET /validation/runs returns paginated run list.
+/// @}
+void test_list_runs_success(void);
+
+/// @defgroup test_list_runs_filters "test_list_runs_filters"
+/// @{
+/// @brief All 6 filter query params are accepted and forwarded to service.
+/// @}
+void test_list_runs_filters(void);
+
+/// @defgroup test_list_runs_pagination "test_list_runs_pagination"
+/// @{
+/// @brief Pagination boundary checks on runs list.
+/// @}
+void test_list_runs_pagination(void);
+
+/// @defgroup test_list_runs_invalid_status "test_list_runs_invalid_status"
+/// @{
+/// @brief Status is a free string; any value passes through to service.
+/// @}
+void test_list_runs_invalid_status(void);
+
+/// @defgroup test_get_run_detail_success "test_get_run_detail_success"
+/// @{
+/// @brief GET /validation/runs/{id} returns full detail with issues and raw_response.
+/// @}
+void test_get_run_detail_success(void);
+
+/// @defgroup test_get_run_detail_not_found "test_get_run_detail_not_found"
+/// @{
+/// @brief GET for nonexistent run returns 404.
+/// @}
+void test_get_run_detail_not_found(void);
+
+/// @defgroup test_delete_run_success "test_delete_run_success"
+/// @{
+/// @brief DELETE /validation/runs/{id} returns 204.
+/// @}
+void test_delete_run_success(void);
+
+/// @defgroup test_delete_run_not_found "test_delete_run_not_found"
+/// @{
+/// @brief DELETE for nonexistent run returns 404.
+/// @}
+void test_delete_run_not_found(void);
+
+/// @defgroup test_endpoints_require_authentication "test_endpoints_require_authentication"
+/// @{
+/// @brief Without current_user dependency, all 9 endpoints return 401.
+/// @}
+void test_endpoints_require_authentication(void);
+
+/// @defgroup test_permission_denied_non_admin "test_permission_denied_non_admin"
+/// @{
+/// @brief A non-admin user without validation.* permissions receives 403.
+/// @}
+void test_permission_denied_non_admin(void);
+
+/// @defgroup test_permission_denied_all_actions "test_permission_denied_all_actions"
+/// @{
+/// @brief Each action (VIEW, CREATE, EDIT, DELETE, EXECUTE) denied for non-admin.
+/// @}
+void test_permission_denied_all_actions(void);
+
+/// @defgroup test_delete_task_runs_default_false "test_delete_task_runs_default_false"
+/// @{
+/// @brief delete_runs query param defaults to False.
+/// @}
+void test_delete_task_runs_default_false(void);
+
+/// @defgroup AppModule "AppModule"
+/// @{
+/// @brief The main entry point for the FastAPI application.
+/// @invariant All WebSocket connections must be properly cleaned up on disconnect.
+/// @post FastAPI app instance is created, middleware configured, and routes registered.
+/// @pre Python environment and dependencies installed; configuration database available.
+/// @}
+void AppModule(void);
+
+/// @defgroup FastAPI_App "FastAPI_App"
+/// @{
+/// @brief Canonical FastAPI application instance for route, middleware, and websocket registration.
+/// @}
+void FastAPI_App(void);
+
+/// @defgroup ensure_initial_admin_user "ensure_initial_admin_user"
+/// @{
+/// @brief Ensures initial admin user exists when bootstrap env flags are enabled.
+/// @}
+void ensure_initial_admin_user(void);
+
+/// @defgroup startup_event "startup_event"
+/// @{
+/// @brief Handles application startup tasks, such as starting the scheduler.
+/// @post Scheduler is started.
+/// @pre None.
+/// @}
+void startup_event(void);
+
+/// @defgroup shutdown_event "shutdown_event"
+/// @{
+/// @brief Handles application shutdown tasks, such as stopping the scheduler.
+/// @post Scheduler is stopped.
+/// @pre None.
+/// @}
+void shutdown_event(void);
+
+/// @defgroup app_middleware "app_middleware"
+/// @{
+/// @brief Configure application-wide middleware (Session, CORS).
+/// @}
+void app_middleware(void);
+
+/// @defgroup network_error_handler "network_error_handler"
+/// @{
+/// @brief Global exception handler for NetworkError.
+/// @post Returns 503 HTTP Exception.
+/// @pre request is a FastAPI Request object.
+/// @}
+void network_error_handler(void);
+
+/// @defgroup log_requests "log_requests"
+/// @{
+/// @brief Middleware to log incoming HTTP requests and their response status.
+/// @post Logs request and response details.
+/// @pre request is a FastAPI Request object.
+/// @}
+void log_requests(void);
+
+/// @defgroup API_Routes "API_Routes"
+/// @{
+/// @brief Register all FastAPI route groups exposed by the application entrypoint.
+/// @}
+void API_Routes(void);
+
+/// @defgroup api_include_routers "api.include_routers"
+/// @{
+/// @brief Registers all API routers with the FastAPI application.
+/// @}
+void api_include_routers(void);
+
+/// @defgroup websocket_endpoint "websocket_endpoint"
+/// @{
+/// @brief Provides a WebSocket endpoint for real-time log streaming of a task with server-side filtering.
+/// @invariant Every accepted WebSocket subscription is unsubscribed exactly once even when streaming fails or the client disconnects.
+/// @post WebSocket connection is managed and logs are streamed until disconnect.
+/// @pre task_id must be a valid task ID.
+/// @}
+void websocket_endpoint(void);
+
+/// @defgroup dataset_websocket_endpoint "dataset_websocket_endpoint"
+/// @{
+/// @brief WebSocket endpoint for dataset.updated events — auto-refresh on task completion.
+/// @post WebSocket streams dataset.updated events until disconnect.
+/// @pre env_id must reference a known environment.
+/// @}
+void dataset_websocket_endpoint(void);
+
+/// @defgroup StaticFiles "StaticFiles"
+/// @{
+/// @brief Mounts the frontend build directory to serve static assets.
+/// @}
+void StaticFiles(void);
+
+/// @defgroup serve_spa "serve_spa"
+/// @{
+/// @brief Serves the SPA frontend for any path not matched by API routes.
+/// @post Returns the requested file or index.html.
+/// @pre frontend_path exists.
+/// @}
+void serve_spa(void);
+
+/// @defgroup read_root "read_root"
+/// @{
+/// @brief A simple root endpoint to confirm that the API is running when frontend is missing.
+/// @post Returns a JSON message indicating API status.
+/// @pre None.
+/// @}
+void read_root(void);
+
+/// @defgroup src_core "src.core"
+/// @{
+/// @brief Backend core services and infrastructure package root.
+/// @}
+void src_core(void);
+
+/// @defgroup TestConfigManagerCompat "TestConfigManagerCompat"
+/// @{
+/// @brief Verifies ConfigManager compatibility wrappers preserve legacy payload sections.
+/// @}
+void TestConfigManagerCompat(void);
+
+/// @defgroup test_get_payload_preserves_legacy_sections "test_get_payload_preserves_legacy_sections"
+/// @{
+/// @brief Ensure get_payload merges typed config into raw payload without dropping legacy sections.
+/// @}
+void test_get_payload_preserves_legacy_sections(void);
+
+/// @defgroup test_save_config_accepts_raw_payload_and_keeps_extras "test_save_config_accepts_raw_payload_and_keeps_extras"
+/// @{
+/// @brief Ensure save_config accepts raw dict payload, refreshes typed config, and preserves extra sections.
+/// @}
+void test_save_config_accepts_raw_payload_and_keeps_extras(void);
+
+/// @defgroup test_save_config_syncs_environment_records_for_fk_backed_flows "test_save_config_syncs_environment_records_for_fk_backed_flows"
+/// @{
+/// @brief Ensure saving config mirrors typed environments into relational records required by FK-backed session persistence.
+/// @}
+void test_save_config_syncs_environment_records_for_fk_backed_flows(void);
+
+/// @defgroup _FakeQuery "_FakeQuery"
+/// @{
+/// @brief Minimal query stub returning hardcoded existing environment record list for sync tests.
+/// @invariant all() always returns [existing_record]; no parameterization or filtering.
+/// @}
+void _FakeQuery(void);
+
+/// @defgroup _FakeSession "_FakeSession"
+/// @{
+/// @brief Minimal SQLAlchemy session stub that captures add/delete calls for environment sync assertions.
+/// @invariant query() always returns _FakeQuery; no real DB interaction.
+/// @}
+void _FakeSession(void);
+
+/// @defgroup test_save_config_syncs_deletions_to_persistence "test_save_config_syncs_deletions_to_persistence"
+/// @{
+/// @brief Ensure stale environment records are deleted during save (in _delete_stale_environment_records)
+/// @}
+void test_save_config_syncs_deletions_to_persistence(void);
+
+/// @defgroup _FakeQueryDel "_FakeQueryDel"
+/// @{
+/// @brief Minimal query stub for deletion test.
+/// @}
+void _FakeQueryDel(void);
+
+/// @defgroup _FakeSessionDel "_FakeSessionDel"
+/// @{
+/// @brief Minimal session stub that captures add/delete for deletion assertions.
+/// @}
+void _FakeSessionDel(void);
+
+/// @defgroup test_load_config_syncs_environment_records_from_existing_db_payload "test_load_config_syncs_environment_records_from_existing_db_payload"
+/// @{
+/// @brief Ensure loading an existing DB-backed config also mirrors environment rows required by FK-backed runtime flows.
+/// @}
+void test_load_config_syncs_environment_records_from_existing_db_payload(void);
+
+/// @defgroup NativeFilterExtractionTests "NativeFilterExtractionTests"
+/// @{
+/// @brief Verify native filter extraction from permalinks and native_filters_key URLs.
+/// @}
+void NativeFilterExtractionTests(void);
+
+/// @defgroup test_extract_native_filters_from_permalink "test_extract_native_filters_from_permalink"
+/// @{
+/// @brief Extract native filters from a permalink key.
+/// @}
+void test_extract_native_filters_from_permalink(void);
+
+/// @defgroup test_extract_native_filters_from_permalink_direct_response "test_extract_native_filters_from_permalink_direct_response"
+/// @{
+/// @brief Handle permalink response without result wrapper.
+/// @}
+void test_extract_native_filters_from_permalink_direct_response(void);
+
+/// @defgroup test_extract_native_filters_from_key "test_extract_native_filters_from_key"
+/// @{
+/// @brief Extract native filters from a native_filters_key.
+/// @}
+void test_extract_native_filters_from_key(void);
+
+/// @defgroup test_extract_native_filters_from_key_single_filter "test_extract_native_filters_from_key_single_filter"
+/// @{
+/// @brief Handle single filter format in native filter state.
+/// @}
+void test_extract_native_filters_from_key_single_filter(void);
+
+/// @defgroup test_extract_native_filters_from_key_dict_value "test_extract_native_filters_from_key_dict_value"
+/// @{
+/// @brief Handle filter state value as dict instead of JSON string.
+/// @}
+void test_extract_native_filters_from_key_dict_value(void);
+
+/// @defgroup test_parse_dashboard_url_for_filters_permalink "test_parse_dashboard_url_for_filters_permalink"
+/// @{
+/// @brief Parse permalink URL format.
+/// @}
+void test_parse_dashboard_url_for_filters_permalink(void);
+
+/// @defgroup test_parse_dashboard_url_for_filters_native_key "test_parse_dashboard_url_for_filters_native_key"
+/// @{
+/// @brief Parse native_filters_key URL format with numeric dashboard ID.
+/// @}
+void test_parse_dashboard_url_for_filters_native_key(void);
+
+/// @defgroup test_parse_dashboard_url_for_filters_native_key_slug "test_parse_dashboard_url_for_filters_native_key_slug"
+/// @{
+/// @brief Parse native_filters_key URL format when dashboard reference is a slug, not a numeric ID.
+/// @}
+void test_parse_dashboard_url_for_filters_native_key_slug(void);
+
+/// @defgroup test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails "test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails"
+/// @{
+/// @brief Gracefully handle slug resolution failure for native_filters_key URL.
+/// @}
+void test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails(void);
+
+/// @defgroup test_parse_dashboard_url_for_filters_native_filters_direct "test_parse_dashboard_url_for_filters_native_filters_direct"
+/// @{
+/// @brief Parse native_filters direct query param.
+/// @}
+void test_parse_dashboard_url_for_filters_native_filters_direct(void);
+
+/// @defgroup test_parse_dashboard_url_for_filters_no_filters "test_parse_dashboard_url_for_filters_no_filters"
+/// @{
+/// @brief Return empty result when no filters present.
+/// @}
+void test_parse_dashboard_url_for_filters_no_filters(void);
+
+/// @defgroup test_extra_form_data_merge "test_extra_form_data_merge"
+/// @{
+/// @brief Test ExtraFormDataMerge correctly merges dictionaries.
+/// @}
+void test_extra_form_data_merge(void);
+
+/// @defgroup test_filter_state_model "test_filter_state_model"
+/// @{
+/// @brief Test FilterState Pydantic model.
+/// @}
+void test_filter_state_model(void);
+
+/// @defgroup test_parsed_native_filters_model "test_parsed_native_filters_model"
+/// @{
+/// @brief Test ParsedNativeFilters Pydantic model.
+/// @}
+void test_parsed_native_filters_model(void);
+
+/// @defgroup test_parsed_native_filters_empty "test_parsed_native_filters_empty"
+/// @{
+/// @brief Test ParsedNativeFilters with no filters.
+/// @}
+void test_parsed_native_filters_empty(void);
+
+/// @defgroup test_native_filter_data_mask_model "test_native_filter_data_mask_model"
+/// @{
+/// @brief Test NativeFilterDataMask model.
+/// @}
+void test_native_filter_data_mask_model(void);
+
+/// @defgroup test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names "test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names"
+/// @{
+/// @brief Reconcile raw native filter ids from state to canonical metadata filter names.
+/// @}
+void test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names(void);
+
+/// @defgroup test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter "test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter"
+/// @{
+/// @brief Collapse raw-id state entries and metadata entries into one canonical filter.
+/// @}
+void test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter(void);
+
+/// @defgroup test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids "test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids"
+/// @{
+/// @brief Preserve unmatched raw native filter ids as fallback diagnostics when metadata mapping is unavailable.
+/// @}
+void test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids(void);
+
+/// @defgroup test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview "test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview"
+/// @{
+/// @brief Recovered native filter state should preserve exact Superset clause payload and time extras for preview compilation.
+/// @}
+void test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview(void);
+
+/// @defgroup test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values "test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values"
+/// @{
+/// @brief Assistant-facing imported-filter payload should redact likely PII while preserving structure metadata.
+/// @}
+void test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values(void);
+
+/// @defgroup SupersetPreviewPipelineTests "SupersetPreviewPipelineTests"
+/// @{
+/// @brief Verify explicit chart-data preview compilation and ensure non-dashboard 404 errors remain generic across sync and async clients.
+/// @}
+void SupersetPreviewPipelineTests(void);
+
+/// @defgroup _make_environment "_make_environment"
+/// @{
+/// @}
+void _make_environment(void);
+
+/// @defgroup _make_requests_http_error "_make_requests_http_error"
+/// @{
+/// @}
+void _make_requests_http_error(void);
+
+/// @defgroup _make_httpx_status_error "_make_httpx_status_error"
+/// @{
+/// @}
+void _make_httpx_status_error(void);
+
+/// @defgroup test_compile_dataset_preview_prefers_legacy_explore_form_data_strategy "test_compile_dataset_preview_prefers_legacy_explore_form_data_strategy"
+/// @{
+/// @brief Superset preview compilation should prefer the legacy form_data transport inferred from browser traffic before falling back to chart-data.
+/// @}
+void test_compile_dataset_preview_prefers_legacy_explore_form_data_strategy(void);
+
+/// @defgroup test_compile_dataset_preview_falls_back_to_chart_data_after_legacy_failures "test_compile_dataset_preview_falls_back_to_chart_data_after_legacy_failures"
+/// @{
+/// @brief Superset preview compilation should fall back to chart-data when legacy form_data strategies are rejected.
+/// @}
+void test_compile_dataset_preview_falls_back_to_chart_data_after_legacy_failures(void);
+
+/// @defgroup test_build_dataset_preview_query_context_places_recovered_filters_in_chart_style_form_data "test_build_dataset_preview_query_context_places_recovered_filters_in_chart_style_form_data"
+/// @{
+/// @brief Preview query context should mirror chart-style filter transport so recovered native filters reach Superset compilation.
+/// @}
+void test_build_dataset_preview_query_context_places_recovered_filters_in_chart_style_form_data(void);
+
+/// @defgroup test_build_dataset_preview_query_context_merges_dataset_template_params_and_preserves_user_values "test_build_dataset_preview_query_context_merges_dataset_template_params_and_preserves_user_values"
+/// @{
+/// @brief Preview query context should merge dataset template params for parity with real dataset definitions while preserving explicit session overrides.
+/// @}
+void test_build_dataset_preview_query_context_merges_dataset_template_params_and_preserves_user_values(void);
+
+/// @defgroup test_build_dataset_preview_query_context_preserves_time_range_from_native_filter_payload "test_build_dataset_preview_query_context_preserves_time_range_from_native_filter_payload"
+/// @{
+/// @brief Preview query context should preserve time-range native filter extras even when dataset defaults differ.
+/// @}
+void test_build_dataset_preview_query_context_preserves_time_range_from_native_filter_payload(void);
+
+/// @defgroup test_build_dataset_preview_legacy_form_data_preserves_native_filter_clauses "test_build_dataset_preview_legacy_form_data_preserves_native_filter_clauses"
+/// @{
+/// @brief Legacy preview form_data should preserve recovered native filter clauses in browser-style fields without duplicating datasource for QueryObjectFactory.
+/// @}
+void test_build_dataset_preview_legacy_form_data_preserves_native_filter_clauses(void);
+
+/// @defgroup test_sync_network_404_mapping_keeps_non_dashboard_endpoints_generic "test_sync_network_404_mapping_keeps_non_dashboard_endpoints_generic"
+/// @{
+/// @brief Sync network client should reserve dashboard-not-found translation for dashboard endpoints only.
+/// @}
+void test_sync_network_404_mapping_keeps_non_dashboard_endpoints_generic(void);
+
+/// @defgroup test_sync_network_404_mapping_translates_dashboard_endpoints "test_sync_network_404_mapping_translates_dashboard_endpoints"
+/// @{
+/// @brief Sync network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+/// @}
+void test_sync_network_404_mapping_translates_dashboard_endpoints(void);
+
+/// @defgroup test_async_network_404_mapping_keeps_non_dashboard_endpoints_generic "test_async_network_404_mapping_keeps_non_dashboard_endpoints_generic"
+/// @{
+/// @brief Async network client should reserve dashboard-not-found translation for dashboard endpoints only.
+/// @}
+void test_async_network_404_mapping_keeps_non_dashboard_endpoints_generic(void);
+
+/// @defgroup test_async_network_404_mapping_translates_dashboard_endpoints "test_async_network_404_mapping_translates_dashboard_endpoints"
+/// @{
+/// @brief Async network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+/// @}
+void test_async_network_404_mapping_translates_dashboard_endpoints(void);
+
+/// @defgroup TestSupersetProfileLookup "TestSupersetProfileLookup"
+/// @{
+/// @brief Verifies Superset profile lookup adapter payload normalization and fallback error precedence.
+/// @}
+void TestSupersetProfileLookup(void);
+
+/// @defgroup _RecordingNetworkClient "_RecordingNetworkClient"
+/// @{
+/// @brief Records request payloads and returns scripted responses for deterministic adapter tests.
+/// @invariant Each request consumes one scripted response in call order and persists call metadata.
+/// @}
+void _RecordingNetworkClient(void);
+
+/// @defgroup test_get_users_page_sends_lowercase_order_direction "test_get_users_page_sends_lowercase_order_direction"
+/// @{
+/// @brief Ensures adapter sends lowercase order_direction compatible with Superset rison schema.
+/// @post First request query payload contains order_direction='asc' for asc sort.
+/// @pre Adapter is initialized with recording network client.
+/// @}
+void test_get_users_page_sends_lowercase_order_direction(void);
+
+/// @defgroup test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error "test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error"
+/// @{
+/// @brief Ensures fallback auth error does not mask primary schema/query failure.
+/// @post Raised exception remains primary SupersetAPIError (non-auth) to preserve root cause.
+/// @pre Primary endpoint fails with SupersetAPIError and fallback fails with AuthenticationError.
+/// @}
+void test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error(void);
+
+/// @defgroup test_get_users_page_uses_fallback_endpoint_when_primary_fails "test_get_users_page_uses_fallback_endpoint_when_primary_fails"
+/// @{
+/// @brief Verifies adapter retries second users endpoint and succeeds when fallback is healthy.
+/// @post Result status is success and both endpoints were attempted in order.
+/// @pre Primary endpoint fails; fallback returns valid users payload.
+/// @}
+void test_get_users_page_uses_fallback_endpoint_when_primary_fails(void);
+
+/// @defgroup test_throttled_scheduler "test_throttled_scheduler"
+/// @{
+/// @brief Unit tests for ThrottledSchedulerConfigurator distribution logic.
+/// @}
+void test_throttled_scheduler(void);
+
+/// @defgroup test_calculate_schedule_even_distribution "test_calculate_schedule_even_distribution"
+/// @{
+/// @brief Validate even spacing across a two-hour scheduling window for three tasks.
+/// @}
+void test_calculate_schedule_even_distribution(void);
+
+/// @defgroup test_calculate_schedule_midnight_crossing "test_calculate_schedule_midnight_crossing"
+/// @{
+/// @brief Validate scheduler correctly rolls timestamps into the next day across midnight.
+/// @}
+void test_calculate_schedule_midnight_crossing(void);
+
+/// @defgroup test_calculate_schedule_single_task "test_calculate_schedule_single_task"
+/// @{
+/// @brief Validate single-task schedule returns only the window start timestamp.
+/// @}
+void test_calculate_schedule_single_task(void);
+
+/// @defgroup test_calculate_schedule_empty_list "test_calculate_schedule_empty_list"
+/// @{
+/// @brief Validate empty dashboard list produces an empty schedule.
+/// @}
+void test_calculate_schedule_empty_list(void);
+
+/// @defgroup test_calculate_schedule_zero_window "test_calculate_schedule_zero_window"
+/// @{
+/// @brief Validate zero-length window schedules all tasks at identical start timestamp.
+/// @}
+void test_calculate_schedule_zero_window(void);
+
+/// @defgroup test_calculate_schedule_very_small_window "test_calculate_schedule_very_small_window"
+/// @{
+/// @brief Validate sub-second interpolation when task count exceeds near-zero window granularity.
+/// @}
+void test_calculate_schedule_very_small_window(void);
+
+/// @defgroup AsyncSupersetClientModule "AsyncSupersetClientModule"
+/// @{
+/// @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+/// @}
+void AsyncSupersetClientModule(void);
+
+/// @defgroup AsyncSupersetClient "AsyncSupersetClient"
+/// @{
+/// @brief Async sibling of SupersetClient for dashboard read paths.
+/// @}
+void AsyncSupersetClient(void);
+
+/// @defgroup AsyncSupersetClientInit "AsyncSupersetClientInit"
+/// @{
+/// @brief Initialize async Superset client with AsyncAPIClient transport.
+/// @post Client uses async network transport and inherited projection helpers.
+/// @pre env is valid Environment instance.
+/// @}
+void AsyncSupersetClientInit(void);
+
+/// @defgroup AsyncSupersetClientClose "AsyncSupersetClientClose"
+/// @{
+/// @brief Close async transport resources.
+/// @post Underlying AsyncAPIClient is closed.
+/// @}
+void AsyncSupersetClientClose(void);
+
+/// @defgroup get_dashboards_page_async "get_dashboards_page_async"
+/// @{
+/// @brief Fetch one dashboards page asynchronously.
+/// @post Returns total count and page result list.
+/// @}
+void get_dashboards_page_async(void);
+
+/// @defgroup get_dashboard_async "get_dashboard_async"
+/// @{
+/// @brief Fetch one dashboard payload asynchronously.
+/// @post Returns raw dashboard payload from Superset API.
+/// @}
+void get_dashboard_async(void);
+
+/// @defgroup get_chart_async "get_chart_async"
+/// @{
+/// @brief Fetch one chart payload asynchronously.
+/// @post Returns raw chart payload from Superset API.
+/// @}
+void get_chart_async(void);
+
+/// @defgroup get_dashboard_detail_async "get_dashboard_detail_async"
+/// @{
+/// @brief Fetch dashboard detail asynchronously with concurrent charts/datasets requests.
+/// @post Returns dashboard detail payload for overview page.
+/// @}
+void get_dashboard_detail_async(void);
+
+/// @defgroup get_dashboard_permalink_state_async "get_dashboard_permalink_state_async"
+/// @{
+/// @brief Fetch stored dashboard permalink state asynchronously.
+/// @post Returns dashboard permalink state payload from Superset API.
+/// @}
+void get_dashboard_permalink_state_async(void);
+
+/// @defgroup get_native_filter_state_async "get_native_filter_state_async"
+/// @{
+/// @brief Fetch stored native filter state asynchronously.
+/// @post Returns native filter state payload from Superset API.
+/// @}
+void get_native_filter_state_async(void);
+
+/// @defgroup extract_native_filters_from_permalink_async "extract_native_filters_from_permalink_async"
+/// @{
+/// @brief Extract native filters dataMask from a permalink key asynchronously.
+/// @post Returns extracted dataMask with filter states.
+/// @}
+void extract_native_filters_from_permalink_async(void);
+
+/// @defgroup extract_native_filters_from_key_async "extract_native_filters_from_key_async"
+/// @{
+/// @brief Extract native filters from a native_filters_key URL parameter asynchronously.
+/// @post Returns extracted filter state with extraFormData.
+/// @}
+void extract_native_filters_from_key_async(void);
+
+/// @defgroup parse_dashboard_url_for_filters_async "parse_dashboard_url_for_filters_async"
+/// @{
+/// @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+/// @post Returns extracted filter state or empty dict if no filters found.
+/// @}
+void parse_dashboard_url_for_filters_async(void);
+
+/// @defgroup AuthPackage "AuthPackage"
+/// @{
+/// @brief Authentication and authorization package root.
+/// @}
+void AuthPackage(void);
+
+/// @defgroup test_auth "test_auth"
+/// @{
+/// @brief Unit tests for authentication module
+/// @}
+void test_auth(void);
+
+/// @defgroup test_create_user "test_create_user"
+/// @{
+/// @brief Verifies that a persisted user can be retrieved with intact credential hash.
+/// @}
+void test_create_user(void);
+
+/// @defgroup test_authenticate_user "test_authenticate_user"
+/// @{
+/// @brief Validates authentication outcomes for valid, wrong-password, and unknown-user cases.
+/// @}
+void test_authenticate_user(void);
+
+/// @defgroup test_create_session "test_create_session"
+/// @{
+/// @brief Ensures session creation returns bearer token payload fields.
+/// @}
+void test_create_session(void);
+
+/// @defgroup test_role_permission_association "test_role_permission_association"
+/// @{
+/// @brief Confirms role-permission many-to-many assignments persist and reload correctly.
+/// @}
+void test_role_permission_association(void);
+
+/// @defgroup test_user_role_association "test_user_role_association"
+/// @{
+/// @brief Confirms user-role assignment persists and is queryable from repository reads.
+/// @}
+void test_user_role_association(void);
+
+/// @defgroup test_ad_group_mapping "test_ad_group_mapping"
+/// @{
+/// @brief Verifies AD group mapping rows persist and reference the expected role.
+/// @}
+void test_ad_group_mapping(void);
+
+/// @defgroup test_authenticate_user_updates_last_login "test_authenticate_user_updates_last_login"
+/// @{
+/// @brief Verifies successful authentication updates last_login audit field.
+/// @}
+void test_authenticate_user_updates_last_login(void);
+
+/// @defgroup test_authenticate_inactive_user "test_authenticate_inactive_user"
+/// @{
+/// @brief Verifies inactive accounts are rejected during password authentication.
+/// @}
+void test_authenticate_inactive_user(void);
+
+/// @defgroup test_verify_password_empty_hash "test_verify_password_empty_hash"
+/// @{
+/// @brief Verifies password verification safely rejects empty or null password hashes.
+/// @}
+void test_verify_password_empty_hash(void);
+
+/// @defgroup test_provision_adfs_user_new "test_provision_adfs_user_new"
+/// @{
+/// @brief Verifies JIT provisioning creates a new ADFS user and maps group-derived roles.
+/// @}
+void test_provision_adfs_user_new(void);
+
+/// @defgroup test_provision_adfs_user_existing "test_provision_adfs_user_existing"
+/// @{
+/// @brief Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.
+/// @}
+void test_provision_adfs_user_existing(void);
+
+/// @defgroup APIKeyUtilities "APIKeyUtilities"
+/// @{
+/// @brief API key generation and hashing utilities for service-to-service authentication.
+/// @invariant hash_api_key() produces SHA-256 hex digest for lookup and storage.
+/// @}
+void APIKeyUtilities(void);
+
+/// @defgroup generate_api_key "generate_api_key"
+/// @{
+/// @brief Generate a new API key in ssk_ format with SHA-256 hash.
+/// @post Returns (raw_key, prefix, key_hash) — raw_key shown ONCE to caller, never stored.
+/// @}
+void generate_api_key(void);
+
+/// @defgroup hash_api_key "hash_api_key"
+/// @{
+/// @brief Hash an API key string to SHA-256 hex digest for lookup.
+/// @post Returns 64-character hex digest.
+/// @pre raw_key is a non-empty string.
+/// @}
+void hash_api_key(void);
+
+/// @defgroup AuthConfigModule "AuthConfigModule"
+/// @{
+/// @brief Centralized configuration for authentication and authorization.
+/// @invariant All sensitive configuration must be loaded from environment; no hardcoded secrets.
+/// @}
+void AuthConfigModule(void);
+
+/// @defgroup AuthConfig "AuthConfig"
+/// @{
+/// @brief Holds authentication-related settings.
+/// @post Returns a configuration object with validated settings.
+/// @pre Environment variables may be provided via .env file.
+/// @}
+void AuthConfig(void);
+
+/// @defgroup auth_config "auth_config"
+/// @{
+/// @brief Singleton instance of AuthConfig.
+/// @}
+void auth_config(void);
+
+/// @defgroup AuthJwtModule "AuthJwtModule"
+/// @{
+/// @brief JWT token generation and validation logic.
+/// @invariant Tokens must include expiration time and user identifier.
+/// @post Token encode/decode functions exported
+/// @pre JWT secret configured in environment
+/// @}
+void AuthJwtModule(void);
+
+/// @defgroup create_access_token "create_access_token"
+/// @{
+/// @brief Generates a new JWT access token.
+/// @post Returns a signed JWT string.
+/// @pre data dict contains 'sub' (user_id) and optional 'scopes' (roles).
+/// @}
+void create_access_token(void);
+
+/// @defgroup decode_token "decode_token"
+/// @{
+/// @brief Decodes and validates a JWT token.
+/// @post Returns the decoded payload if valid.
+/// @pre token is a signed JWT string.
+/// @}
+void decode_token(void);
+
+/// @defgroup AuthLoggerModule "AuthLoggerModule"
+/// @{
+/// @brief Structured auth logging module for audit trail generation.
+/// @invariant Must not log sensitive data like passwords or full tokens.
+/// @post Audit logging functions exported
+/// @pre Auth module initialized
+/// @}
+void AuthLoggerModule(void);
+
+/// @defgroup log_security_event "log_security_event"
+/// @{
+/// @brief Logs a security-related event for audit trails.
+/// @post Security event is written to the application log.
+/// @pre event_type and username are strings.
+/// @}
+void log_security_event(void);
+
+/// @defgroup AuthOauthModule "AuthOauthModule"
+/// @{
+/// @brief ADFS OIDC configuration and client using Authlib.
+/// @invariant Must use secure OIDC flows.
+/// @}
+void AuthOauthModule(void);
+
+/// @defgroup oauth "oauth"
+/// @{
+/// @brief Global Authlib OAuth registry.
+/// @}
+void oauth(void);
+
+/// @defgroup register_adfs "register_adfs"
+/// @{
+/// @brief Registers the ADFS OIDC client.
+/// @post ADFS client is registered in oauth registry.
+/// @pre ADFS configuration is provided in auth_config.
+/// @}
+void register_adfs(void);
+
+/// @defgroup is_adfs_configured "is_adfs_configured"
+/// @{
+/// @brief Checks if ADFS is properly configured.
+/// @post Returns True if ADFS client is registered, False otherwise.
+/// @pre None.
+/// @}
+void is_adfs_configured(void);
+
+/// @defgroup AuthRepositoryModule "AuthRepositoryModule"
+/// @{
+/// @brief Data access layer for authentication and user preference entities.
+/// @invariant All database read/write operations must execute via the injected SQLAlchemy session boundary.
+/// @post Provides valid access to identity data.
+/// @pre Database connection is active.
+/// @}
+void AuthRepositoryModule(void);
+
+/// @defgroup AuthRepository "AuthRepository"
+/// @{
+/// @brief Provides low-level CRUD operations for identity and authorization records.
+/// @post Entity instances returned safely.
+/// @pre Database session is bound.
+/// @}
+void AuthRepository(void);
+
+/// @defgroup get_user_by_id "get_user_by_id"
+/// @{
+/// @brief Retrieve user by UUID.
+/// @post Returns User object if found, else None.
+/// @pre user_id is a valid UUID string.
+/// @}
+void get_user_by_id(void);
+
+/// @defgroup get_user_by_username "get_user_by_username"
+/// @{
+/// @brief Retrieve user by username.
+/// @post Returns User object if found, else None.
+/// @pre username is a non-empty string.
+/// @}
+void get_user_by_username(void);
+
+/// @defgroup get_role_by_id "get_role_by_id"
+/// @{
+/// @brief Retrieve role by UUID with permissions preloaded.
+/// @}
+void get_role_by_id(void);
+
+/// @defgroup get_role_by_name "get_role_by_name"
+/// @{
+/// @brief Retrieve role by unique name.
+/// @}
+void get_role_by_name(void);
+
+/// @defgroup get_permission_by_id "get_permission_by_id"
+/// @{
+/// @brief Retrieve permission by UUID.
+/// @}
+void get_permission_by_id(void);
+
+/// @defgroup get_permission_by_resource_action "get_permission_by_resource_action"
+/// @{
+/// @brief Retrieve permission by resource and action tuple.
+/// @}
+void get_permission_by_resource_action(void);
+
+/// @defgroup list_permissions "list_permissions"
+/// @{
+/// @brief List all system permissions.
+/// @}
+void list_permissions(void);
+
+/// @defgroup get_user_dashboard_preference "get_user_dashboard_preference"
+/// @{
+/// @brief Retrieve dashboard filters/preferences for a user.
+/// @}
+void get_user_dashboard_preference(void);
+
+/// @defgroup get_roles_by_ad_groups "get_roles_by_ad_groups"
+/// @{
+/// @brief Retrieve roles that match a list of AD group names.
+/// @post Returns a list of Role objects mapped to the provided AD groups.
+/// @pre groups is a list of strings representing AD group identifiers.
+/// @}
+void get_roles_by_ad_groups(void);
+
+/// @defgroup AuthSecurityModule "AuthSecurityModule"
+/// @{
+/// @brief Utility for password hashing and verification using Passlib.
+/// @invariant Uses bcrypt for hashing with standard work factor.
+/// @}
+void AuthSecurityModule(void);
+
+/// @defgroup verify_password "verify_password"
+/// @{
+/// @brief Verifies a plain password against a hashed password.
+/// @post Returns True if password matches, False otherwise.
+/// @pre plain_password is a string, hashed_password is a bcrypt hash.
+/// @}
+void verify_password(void);
+
+/// @defgroup get_password_hash "get_password_hash"
+/// @{
+/// @brief Generates a bcrypt hash for a plain password.
+/// @post Returns a secure bcrypt hash string.
+/// @pre password is a string.
+/// @}
+void get_password_hash(void);
+
+/// @defgroup ConfigManager "ConfigManager"
+/// @{
+/// @brief Manages application configuration persistence in DB with one-time migration from legacy JSON.
+/// @invariant Configuration must always be representable by AppConfig and persisted under global record id.
+/// @post Configuration is loaded into memory and logger is configured.
+/// @pre Database schema for AppConfigRecord must be initialized.
+/// @}
+void ConfigManager(void);
+
+/// @defgroup _apply_features_from_env "_apply_features_from_env"
+/// @{
+/// @brief Read FEATURES__* env vars and apply them to a GlobalSettings features config.
+/// @}
+void _apply_features_from_env(void);
+
+/// @defgroup _default_config "_default_config"
+/// @{
+/// @brief Build default application configuration fallback.
+/// @}
+void _default_config(void);
+
+/// @defgroup _sync_raw_payload_from_config "_sync_raw_payload_from_config"
+/// @{
+/// @brief Merge typed AppConfig state into raw payload while preserving unsupported legacy sections.
+/// @}
+void _sync_raw_payload_from_config(void);
+
+/// @defgroup _load_from_legacy_file "_load_from_legacy_file"
+/// @{
+/// @brief Load legacy JSON configuration for migration fallback path.
+/// @}
+void _load_from_legacy_file(void);
+
+/// @defgroup _get_record "_get_record"
+/// @{
+/// @brief Resolve global configuration record from DB.
+/// @}
+void _get_record(void);
+
+/// @defgroup _load_config "_load_config"
+/// @{
+/// @brief Load configuration from DB or perform one-time migration from legacy JSON.
+/// @}
+void _load_config(void);
+
+/// @defgroup _sync_environment_records "_sync_environment_records"
+/// @{
+/// @brief Mirror configured environments into the relational environments table used by FK-backed domain models.
+/// @}
+void _sync_environment_records(void);
+
+/// @defgroup _delete_stale_environment_records "_delete_stale_environment_records"
+/// @{
+/// @brief Remove persisted environment records that are no longer in the configured environments.
+/// @post Stale Environment rows are deleted via the session (caller must commit).
+/// @pre _sync_environment_records must already have run so the query returns a current view.
+/// @}
+void _delete_stale_environment_records(void);
+
+/// @defgroup _save_config_to_db "_save_config_to_db"
+/// @{
+/// @brief Persist provided AppConfig into the global DB configuration record.
+/// @}
+void _save_config_to_db(void);
+
+/// @defgroup save "save"
+/// @{
+/// @brief Persist current in-memory configuration state.
+/// @}
+void save(void);
+
+/// @defgroup get_config "get_config"
+/// @{
+/// @brief Return current in-memory configuration snapshot.
+/// @}
+void get_config(void);
+
+/// @defgroup get_payload "get_payload"
+/// @{
+/// @brief Return full persisted payload including sections outside typed AppConfig schema.
+/// @}
+void get_payload(void);
+
+/// @defgroup save_config "save_config"
+/// @{
+/// @brief Persist configuration provided either as typed AppConfig or raw payload dict.
+/// @}
+void save_config(void);
+
+/// @defgroup update_global_settings "update_global_settings"
+/// @{
+/// @brief Replace global settings and persist the resulting configuration.
+/// @}
+void update_global_settings(void);
+
+/// @defgroup validate_path "validate_path"
+/// @{
+/// @brief Validate that path exists and is writable, creating it when absent.
+/// @}
+void validate_path(void);
+
+/// @defgroup get_environments "get_environments"
+/// @{
+/// @brief Return all configured environments.
+/// @}
+void get_environments(void);
+
+/// @defgroup has_environments "has_environments"
+/// @{
+/// @brief Check whether at least one environment exists in configuration.
+/// @}
+void has_environments(void);
+
+/// @defgroup get_environment "get_environment"
+/// @{
+/// @brief Resolve a configured environment by identifier.
+/// @}
+void get_environment(void);
+
+/// @defgroup add_environment "add_environment"
+/// @{
+/// @brief Upsert environment by id into configuration and persist.
+/// @}
+void add_environment(void);
+
+/// @defgroup update_environment "update_environment"
+/// @{
+/// @brief Update existing environment by id and preserve masked password placeholder behavior.
+/// @}
+void update_environment(void);
+
+/// @defgroup delete_environment "delete_environment"
+/// @{
+/// @brief Delete environment by id and persist when deletion occurs.
+/// @}
+void delete_environment(void);
+
+/// @defgroup ConfigModels "ConfigModels"
+/// @{
+/// @brief Defines the data models for application configuration using Pydantic.
+/// @}
+void ConfigModels(void);
+
+/// @defgroup CoreContracts "CoreContracts"
+/// @{
+/// @brief Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.
+/// @}
+void CoreContracts(void);
+
+/// @defgroup ConnectionContracts "ConnectionContracts"
+/// @{
+/// @brief Contract for database/environment connection configuration models.
+/// @}
+void ConnectionContracts(void);
+
+/// @defgroup Schedule "Schedule"
+/// @{
+/// @brief Represents a backup schedule configuration.
+/// @}
+void Schedule(void);
+
+/// @defgroup Environment "Environment"
+/// @{
+/// @brief Represents a Superset environment configuration.
+/// @}
+void Environment(void);
+
+/// @defgroup LoggingConfig "LoggingConfig"
+/// @{
+/// @brief Defines the configuration for the application's logging system.
+/// @}
+void LoggingConfig(void);
+
+/// @defgroup CleanReleaseConfig "CleanReleaseConfig"
+/// @{
+/// @brief Configuration for clean release compliance subsystem.
+/// @}
+void CleanReleaseConfig(void);
+
+/// @defgroup FeaturesConfig "FeaturesConfig"
+/// @{
+/// @brief Top-level feature flags that toggle entire project features on/off.
+/// @}
+void FeaturesConfig(void);
+
+/// @defgroup GlobalSettings "GlobalSettings"
+/// @{
+/// @brief Represents global application settings.
+/// @}
+void GlobalSettings(void);
+
+/// @defgroup AppConfig "AppConfig"
+/// @{
+/// @brief The root configuration model containing all application settings.
+/// @}
+void AppConfig(void);
+
+/// @defgroup CotLoggerModule "CotLoggerModule"
+/// @{
+/// @brief Structured JSON logger implementing the molecular CoT (Chain-of-Thought) logging protocol.
+/// @}
+void CotLoggerModule(void);
+
+/// @defgroup cot_trace_context "cot_trace_context"
+/// @{
+/// @brief ContextVars for trace ID and span ID propagation across async boundaries.
+/// @}
+void cot_trace_context(void);
+
+/// @defgroup cot_logger_instance "cot_logger_instance"
+/// @{
+/// @brief Dedicated Python logger for all CoT (molecular) log output.
+/// @}
+void cot_logger_instance(void);
+
+/// @defgroup seed_trace_id "seed_trace_id"
+/// @{
+/// @brief Generate a new UUID4 trace_id, set it in ContextVar, and return it.
+/// @}
+void seed_trace_id(void);
+
+/// @defgroup set_trace_id "set_trace_id"
+/// @{
+/// @brief Set an explicit trace_id into the ContextVar (e.g. from an incoming header).
+/// @}
+void set_trace_id(void);
+
+/// @defgroup get_trace_id "get_trace_id"
+/// @{
+/// @brief Get the current trace_id from ContextVar.
+/// @}
+void get_trace_id(void);
+
+/// @defgroup push_span "push_span"
+/// @{
+/// @brief Set a new span_id in ContextVar and return the previous span_id for later restoration.
+/// @}
+void push_span(void);
+
+/// @defgroup pop_span "pop_span"
+/// @{
+/// @brief Restore a previous span_id into the ContextVar.
+/// @}
+void pop_span(void);
+
+/// @defgroup cot_log_function "cot_log_function"
+/// @{
+/// @brief Core structured logging function that emits a single-line JSON record.
+/// @}
+void cot_log_function(void);
+
+/// @defgroup MarkerLogger "MarkerLogger"
+/// @{
+/// @brief Thin proxy class providing .reason(), .reflect(), .explore() convenience methods.
+/// @}
+void MarkerLogger(void);
+
+/// @defgroup MarkerLogger___init__ "MarkerLogger.__init__"
+/// @{
+/// @brief Store the module/component name used as the 'src' field in all log calls.
+/// @}
+void MarkerLogger___init__(void);
+
+/// @defgroup MarkerLogger_reason "MarkerLogger.reason"
+/// @{
+/// @brief Log a REASON marker — strict deduction, core logic.
+/// @}
+void MarkerLogger_reason(void);
+
+/// @defgroup MarkerLogger_reflect "MarkerLogger.reflect"
+/// @{
+/// @brief Log a REFLECT marker — self-check, structural validation.
+/// @}
+void MarkerLogger_reflect(void);
+
+/// @defgroup MarkerLogger_explore "MarkerLogger.explore"
+/// @{
+/// @brief Log an EXPLORE marker — searching, alternatives, violated assumptions.
+/// @}
+void MarkerLogger_explore(void);
+
+/// @defgroup DatabaseModule "DatabaseModule"
+/// @{
+/// @brief Configures database connection and session management (PostgreSQL-first).
+/// @invariant A single engine instance is used for the entire application.
+/// @}
+void DatabaseModule(void);
+
+/// @defgroup BASE_DIR "BASE_DIR"
+/// @{
+/// @brief Base directory for the backend.
+/// @}
+void BASE_DIR(void);
+
+/// @defgroup DATABASE_URL "DATABASE_URL"
+/// @{
+/// @brief URL for the main application database. Read from env; dev fallback only.
+/// @}
+void DATABASE_URL(void);
+
+/// @defgroup TASKS_DATABASE_URL "TASKS_DATABASE_URL"
+/// @{
+/// @brief URL for the tasks execution database.
+/// @}
+void TASKS_DATABASE_URL(void);
+
+/// @defgroup AUTH_DATABASE_URL "AUTH_DATABASE_URL"
+/// @{
+/// @brief URL for the authentication database.
+/// @}
+void AUTH_DATABASE_URL(void);
+
+/// @defgroup engine "engine"
+/// @{
+/// @brief SQLAlchemy engine for mappings database.
+/// @}
+void engine(void);
+
+/// @defgroup tasks_engine "tasks_engine"
+/// @{
+/// @brief SQLAlchemy engine for tasks database.
+/// @}
+void tasks_engine(void);
+
+/// @defgroup auth_engine "auth_engine"
+/// @{
+/// @brief SQLAlchemy engine for authentication database.
+/// @}
+void auth_engine(void);
+
+/// @defgroup SessionLocal "SessionLocal"
+/// @{
+/// @brief A session factory for the main mappings database.
+/// @pre engine is initialized.
+/// @}
+void SessionLocal(void);
+
+/// @defgroup TasksSessionLocal "TasksSessionLocal"
+/// @{
+/// @brief A session factory for the tasks execution database.
+/// @pre tasks_engine is initialized.
+/// @}
+void TasksSessionLocal(void);
+
+/// @defgroup AuthSessionLocal "AuthSessionLocal"
+/// @{
+/// @brief A session factory for the authentication database.
+/// @pre auth_engine is initialized.
+/// @}
+void AuthSessionLocal(void);
+
+/// @defgroup _ensure_user_dashboard_preferences_columns "_ensure_user_dashboard_preferences_columns"
+/// @{
+/// @brief Applies additive schema upgrades for user_dashboard_preferences table.
+/// @post Missing columns are added without data loss.
+/// @pre bind_engine points to application database where profile table is stored.
+/// @}
+void _ensure_user_dashboard_preferences_columns(void);
+
+/// @defgroup _ensure_user_dashboard_preferences_health_columns "_ensure_user_dashboard_preferences_health_columns"
+/// @{
+/// @brief Applies additive schema upgrades for user_dashboard_preferences table (health fields).
+/// @}
+void _ensure_user_dashboard_preferences_health_columns(void);
+
+/// @defgroup _ensure_llm_validation_results_columns "_ensure_llm_validation_results_columns"
+/// @{
+/// @brief Applies additive schema upgrades for llm_validation_results table.
+/// @}
+void _ensure_llm_validation_results_columns(void);
+
+/// @defgroup _ensure_git_server_configs_columns "_ensure_git_server_configs_columns"
+/// @{
+/// @brief Applies additive schema upgrades for git_server_configs table.
+/// @post Missing columns are added without data loss.
+/// @pre bind_engine points to application database.
+/// @}
+void _ensure_git_server_configs_columns(void);
+
+/// @defgroup _ensure_auth_users_columns "_ensure_auth_users_columns"
+/// @{
+/// @brief Applies additive schema upgrades for auth users table.
+/// @post Missing columns are added without data loss.
+/// @pre bind_engine points to authentication database.
+/// @}
+void _ensure_auth_users_columns(void);
+
+/// @defgroup _ensure_filter_source_enum_values "_ensure_filter_source_enum_values"
+/// @{
+/// @brief Adds missing FilterSource enum values to the PostgreSQL native filtersource type.
+/// @post New enum values are available without data loss.
+/// @pre bind_engine points to application database with imported_filters table.
+/// @}
+void _ensure_filter_source_enum_values(void);
+
+/// @defgroup _ensure_dataset_review_session_columns "_ensure_dataset_review_session_columns"
+/// @{
+/// @brief Apply additive schema upgrades for dataset review persistence required by optimistic-lock and recovery metadata semantics.
+/// @post Missing additive columns across legacy dataset review tables are created without removing existing data.
+/// @pre bind_engine points to the application database where dataset review tables are stored.
+/// @}
+void _ensure_dataset_review_session_columns(void);
+
+/// @defgroup _ensure_translation_schedules_columns "_ensure_translation_schedules_columns"
+/// @{
+/// @brief Applies additive schema upgrades for translation_schedules table.
+/// @post Missing columns are added without data loss.
+/// @pre bind_engine points to application database.
+/// @}
+void _ensure_translation_schedules_columns(void);
+
+/// @defgroup _ensure_dictionary_entries_columns "_ensure_dictionary_entries_columns"
+/// @{
+/// @brief Additive migration for dictionary_entries origin tracking columns.
+/// @}
+void _ensure_dictionary_entries_columns(void);
+
+/// @defgroup init_db "init_db"
+/// @{
+/// @brief Initializes the database by creating all tables.
+/// @post Database tables created in all databases.
+/// @pre engine, tasks_engine and auth_engine are initialized.
+/// @}
+void init_db(void);
+
+/// @defgroup get_db "get_db"
+/// @{
+/// @brief Dependency for getting a database session.
+/// @post Session is closed after use.
+/// @pre SessionLocal is initialized.
+/// @}
+void get_db(void);
+
+/// @defgroup get_tasks_db "get_tasks_db"
+/// @{
+/// @brief Dependency for getting a tasks database session.
+/// @post Session is closed after use.
+/// @pre TasksSessionLocal is initialized.
+/// @}
+void get_tasks_db(void);
+
+/// @defgroup get_auth_db "get_auth_db"
+/// @{
+/// @brief Dependency for getting an authentication database session.
+/// @post Session is closed after use.
+/// @pre AuthSessionLocal is initialized.
+/// @}
+void get_auth_db(void);
+
+/// @defgroup EncryptionKeyModule "EncryptionKeyModule"
+/// @{
+/// @brief Resolve and persist the Fernet encryption key required by runtime services.
+/// @invariant Runtime key resolution never falls back to an ephemeral secret.
+/// @post A valid Fernet key is available to runtime services via ENCRYPTION_KEY.
+/// @pre Runtime environment can read process variables and target .env path is writable when key generation is required.
+/// @}
+void EncryptionKeyModule(void);
+
+/// @defgroup ensure_encryption_key "ensure_encryption_key"
+/// @{
+/// @brief Ensure backend runtime has a persistent valid Fernet key.
+/// @post Returns a valid Fernet key and guarantees it is present in process environment.
+/// @pre env_file_path points to a writable backend .env file or ENCRYPTION_KEY exists in process environment.
+/// @}
+void ensure_encryption_key(void);
+
+/// @defgroup LoggerModule "LoggerModule"
+/// @{
+/// @brief Application logging system with CotJsonFormatter producing molecular CoT JSON output.
+/// @invariant CotJsonFormatter.format() always returns valid single-line JSON string.
+/// @post All log output is single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+/// @pre Python 3.7+ with cot_logger ContextVars available.
+/// @}
+void LoggerModule(void);
+
+/// @defgroup CotJsonFormatter "CotJsonFormatter"
+/// @{
+/// @brief JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+/// @}
+void CotJsonFormatter(void);
+
+/// @defgroup CotJsonFormatter_format "CotJsonFormatter.format"
+/// @{
+/// @brief Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.
+/// @invariant Output is always valid single-line JSON.
+/// @}
+void CotJsonFormatter_format(void);
+
+/// @defgroup BeliefFormatter "BeliefFormatter"
+/// @{
+/// @brief Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.
+/// @}
+void BeliefFormatter(void);
+
+/// @defgroup LogEntry "LogEntry"
+/// @{
+/// @brief A Pydantic model representing a single, structured log entry.
+/// @}
+void LogEntry(void);
+
+/// @defgroup belief_scope "belief_scope"
+/// @{
+/// @brief Context manager for Molecular CoT structured logging. Uses cot_logger.log() for JSON output.
+/// @post Thread-local belief state is updated; REASON/REFLECT/EXPLORE markers emitted via structured JSON logger.
+/// @pre anchor_id must be provided.
+/// @}
+void belief_scope(void);
+
+/// @defgroup configure_logger "configure_logger"
+/// @{
+/// @brief Configures the main logger and the CoT logger with CotJsonFormatter, file handlers, and global flags.
+/// @post Logger levels, handlers, formatters, belief state flag, and task log level are updated.
+/// @pre config is a valid LoggingConfig instance.
+/// @}
+void configure_logger(void);
+
+/// @defgroup get_task_log_level "get_task_log_level"
+/// @{
+/// @brief Returns the current task log level filter.
+/// @}
+void get_task_log_level(void);
+
+/// @defgroup should_log_task_level "should_log_task_level"
+/// @{
+/// @brief Checks if a log level should be recorded based on task_log_level setting.
+/// @}
+void should_log_task_level(void);
+
+/// @defgroup Logger "Logger"
+/// @{
+/// @brief The global application logger instance configured with CotJsonFormatter, console handler, and WebSocketLogHandler.
+/// @}
+void Logger(void);
+
+/// @defgroup believed "believed"
+/// @{
+/// @brief A decorator that wraps a function in a belief scope.
+/// @}
+void believed(void);
+
+/// @defgroup explore "explore"
+/// @{
+/// @brief Logs an EXPLORE marker (WARNING level) with structured extra data for CotJsonFormatter.
+/// @}
+void explore(void);
+
+/// @defgroup reason "reason"
+/// @{
+/// @brief Logs a REASON marker (DEBUG level) with structured extra data for CotJsonFormatter.
+/// @}
+void reason(void);
+
+/// @defgroup reflect "reflect"
+/// @{
+/// @brief Logs a REFLECT marker (DEBUG level) with structured extra data for CotJsonFormatter.
+/// @}
+void reflect(void);
+
+/// @defgroup test_logger "test_logger"
+/// @{
+/// @brief Unit tests for logger module
+/// @}
+void test_logger(void);
+
+/// @defgroup test_belief_scope_logs_reason_reflect_at_debug "test_belief_scope_logs_reason_reflect_at_debug"
+/// @{
+/// @brief Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.
+/// @post Logs are verified to contain REASON and REFLECT markers at DEBUG level.
+/// @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+/// @}
+void test_belief_scope_logs_reason_reflect_at_debug(void);
+
+/// @defgroup test_belief_scope_error_handling "test_belief_scope_error_handling"
+/// @{
+/// @brief Test that belief_scope logs EXPLORE on exception.
+/// @post Logs are verified to contain EXPLORE marker.
+/// @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+/// @}
+void test_belief_scope_error_handling(void);
+
+/// @defgroup test_belief_scope_success_reflect "test_belief_scope_success_reflect"
+/// @{
+/// @brief Test that belief_scope logs REFLECT on success.
+/// @post Logs are verified to contain REFLECT marker.
+/// @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+/// @}
+void test_belief_scope_success_reflect(void);
+
+/// @defgroup test_belief_scope_not_visible_at_info "test_belief_scope_not_visible_at_info"
+/// @{
+/// @brief Test that belief_scope REFLECT logs are NOT visible at INFO level.
+/// @post REASON is visible at INFO (uses info()); REFLECT is not (uses debug()).
+/// @pre belief_scope is available. caplog fixture is used.
+/// @}
+void test_belief_scope_not_visible_at_info(void);
+
+/// @defgroup test_task_log_level_default "test_task_log_level_default"
+/// @{
+/// @brief Test that default task log level is INFO.
+/// @post Default level is INFO.
+/// @pre None.
+/// @}
+void test_task_log_level_default(void);
+
+/// @defgroup test_should_log_task_level "test_should_log_task_level"
+/// @{
+/// @brief Test that should_log_task_level correctly filters log levels.
+/// @post Filtering works correctly for all level combinations.
+/// @pre None.
+/// @}
+void test_should_log_task_level(void);
+
+/// @defgroup test_configure_logger_task_log_level "test_configure_logger_task_log_level"
+/// @{
+/// @brief Test that configure_logger updates task_log_level.
+/// @post task_log_level is updated correctly.
+/// @pre LoggingConfig is available.
+/// @}
+void test_configure_logger_task_log_level(void);
+
+/// @defgroup test_enable_belief_state_flag "test_enable_belief_state_flag"
+/// @{
+/// @brief Test that enable_belief_state flag controls belief_scope logging.
+/// @post belief_scope explicit REASON logs are controlled by the flag; REFLECT always logged.
+/// @pre LoggingConfig is available. caplog fixture is used.
+/// @}
+void test_enable_belief_state_flag(void);
+
+/// @defgroup test_belief_scope_missing_anchor "test_belief_scope_missing_anchor"
+/// @{
+/// @brief Test @PRE condition: anchor_id must be provided
+/// @}
+void test_belief_scope_missing_anchor(void);
+
+/// @defgroup test_configure_logger_post_conditions "test_configure_logger_post_conditions"
+/// @{
+/// @brief Test @POST condition: Logger level, handlers, belief state flag, and task log level are updated.
+/// @}
+void test_configure_logger_post_conditions(void);
+
+/// @defgroup IdMappingServiceModule "IdMappingServiceModule"
+/// @{
+/// @brief Service for tracking and synchronizing Superset Resource IDs (UUID <-> Integer ID)
+/// @invariant sync_environment must handle remote API failures gracefully.
+/// @post Mapping synchronization and lookup APIs are available for environment-scoped UUID-to-integer resolution.
+/// @pre Database session is valid and Superset client factory returns authenticated clients for requested environments.
+/// @}
+void IdMappingServiceModule(void);
+
+/// @defgroup IdMappingService "IdMappingService"
+/// @{
+/// @brief Service handling the cataloging and retrieval of remote Superset Integer IDs.
+/// @invariant self.db remains the authoritative session for all mapping operations.
+/// @post Service instance provides scheduler control and environment-scoped mapping synchronization APIs.
+/// @pre db_session is an active SQLAlchemy Session bound to mapping tables.
+/// @}
+void IdMappingService(void);
+
+/// @defgroup start_scheduler "start_scheduler"
+/// @{
+/// @brief Starts the background scheduler with a given cron string.
+/// @param superset_client_factory - Function to get a client for an environment.
+/// @}
+void start_scheduler(void);
+
+/// @defgroup sync_environment "sync_environment"
+/// @{
+/// @brief Fully synchronizes mapping for a specific environment.
+/// @param superset_client - Instance capable of hitting the Superset API.
+/// @post ResourceMapping records for the environment are created or updated.
+/// @pre environment_id exists in the database.
+/// @}
+void sync_environment(void);
+
+/// @defgroup get_remote_id "get_remote_id"
+/// @{
+/// @brief Retrieves the remote integer ID for a given universal UUID.
+/// @param uuid (str)
+/// @return Optional[int]
+/// @}
+void get_remote_id(void);
+
+/// @defgroup get_remote_ids_batch "get_remote_ids_batch"
+/// @{
+/// @brief Retrieves remote integer IDs for a list of universal UUIDs efficiently.
+/// @param uuids (List[str])
+/// @return Dict[str, int] - Mapping of UUID -> Integer ID
+/// @}
+void get_remote_ids_batch(void);
+
+/// @defgroup middleware_package "middleware_package"
+/// @{
+/// @brief FastAPI/Starlette middleware package for request-level context and tracing.
+/// @}
+void middleware_package(void);
+
+/// @defgroup TraceContextMiddlewareModule "TraceContextMiddlewareModule"
+/// @{
+/// @brief FastAPI/Starlette middleware that seeds a trace_id for every incoming HTTP request.
+/// @}
+void TraceContextMiddlewareModule(void);
+
+/// @defgroup TraceContextMiddleware "TraceContextMiddleware"
+/// @{
+/// @brief Starlette BaseHTTPMiddleware that seeds a trace_id per request.
+/// @}
+void TraceContextMiddleware(void);
+
+/// @defgroup TraceContextMiddleware___init__ "TraceContextMiddleware.__init__"
+/// @{
+/// @brief Standard BaseHTTPMiddleware initialiser.
+/// @}
+void TraceContextMiddleware___init__(void);
+
+/// @defgroup TraceContextMiddleware_dispatch "TraceContextMiddleware.dispatch"
+/// @{
+/// @brief Dispatch handler that seeds trace_id before passing to the next middleware.
+/// @}
+void TraceContextMiddleware_dispatch(void);
+
+/// @defgroup MigrationPackage "MigrationPackage"
+/// @{
+/// @}
+void MigrationPackage(void);
+
+/// @defgroup MigrationArchiveParserModule "MigrationArchiveParserModule"
+/// @{
+/// @brief Parse Superset export ZIP archives into normalized object catalogs for diffing.
+/// @invariant Parsing is read-only and never mutates archive files.
+/// @post Parsed migration archive returned
+/// @pre Archive file path is valid and readable
+/// @}
+void MigrationArchiveParserModule(void);
+
+/// @defgroup MigrationArchiveParser "MigrationArchiveParser"
+/// @{
+/// @brief Extract normalized dashboards/charts/datasets metadata from ZIP archives.
+/// @}
+void MigrationArchiveParser(void);
+
+/// @defgroup extract_objects_from_zip "extract_objects_from_zip"
+/// @{
+/// @brief Extract object catalogs from Superset archive.
+/// @post Returns object lists grouped by resource type.
+/// @pre zip_path points to a valid readable ZIP.
+/// @return Dict[str, List[Dict[str, Any]]]
+/// @}
+void extract_objects_from_zip(void);
+
+/// @defgroup _collect_yaml_objects "_collect_yaml_objects"
+/// @{
+/// @brief Read and normalize YAML manifests for one object type.
+/// @post Returns only valid normalized objects.
+/// @pre object_type is one of dashboards/charts/datasets.
+/// @}
+void _collect_yaml_objects(void);
+
+/// @defgroup _normalize_object_payload "_normalize_object_payload"
+/// @{
+/// @brief Convert raw YAML payload to stable diff signature shape.
+/// @post Returns normalized descriptor with `uuid`, `title`, and `signature`.
+/// @pre payload is parsed YAML mapping.
+/// @}
+void _normalize_object_payload(void);
+
+/// @defgroup MigrationDryRunOrchestratorModule "MigrationDryRunOrchestratorModule"
+/// @{
+/// @brief Compute pre-flight migration diff and risk scoring without apply.
+/// @invariant Dry run is informative only and must not mutate target environment.
+/// @post Dry-run diff returned without mutation
+/// @pre Source and target environments configured
+/// @}
+void MigrationDryRunOrchestratorModule(void);
+
+/// @defgroup MigrationDryRunService "MigrationDryRunService"
+/// @{
+/// @brief Build deterministic diff/risk payload for migration pre-flight.
+/// @}
+void MigrationDryRunService(void);
+
+/// @defgroup run "run"
+/// @{
+/// @brief Execute full dry-run computation for selected dashboards.
+/// @post Returns JSON-serializable pre-flight payload with summary, diff and risk.
+/// @pre source/target clients are authenticated and selection validated by caller.
+/// @}
+void run(void);
+
+/// @defgroup _load_db_mapping "_load_db_mapping"
+/// @{
+/// @brief Resolve UUID mapping for optional DB config replacement.
+/// @}
+void _load_db_mapping(void);
+
+/// @defgroup _accumulate_objects "_accumulate_objects"
+/// @{
+/// @brief Merge extracted resources by UUID to avoid duplicates.
+/// @}
+void _accumulate_objects(void);
+
+/// @defgroup _index_by_uuid "_index_by_uuid"
+/// @{
+/// @brief Build UUID-index map for normalized resources.
+/// @}
+void _index_by_uuid(void);
+
+/// @defgroup _build_object_diff "_build_object_diff"
+/// @{
+/// @brief Compute create/update/delete buckets by UUID+signature.
+/// @}
+void _build_object_diff(void);
+
+/// @defgroup _build_target_signatures "_build_target_signatures"
+/// @{
+/// @brief Pull target metadata and normalize it into comparable signatures.
+/// @}
+void _build_target_signatures(void);
+
+/// @defgroup _build_risks "_build_risks"
+/// @{
+/// @brief Build risk items for missing datasource, broken refs, overwrite, owner mismatch.
+/// @}
+void _build_risks(void);
+
+/// @defgroup RiskAssessorModule "RiskAssessorModule"
+/// @{
+/// @brief Compute deterministic migration risk items and aggregate score for dry-run reporting.
+/// @invariant Risk scoring must remain bounded to [0,100] and preserve severity-to-weight mapping.
+/// @post Risk scoring output preserves item list and provides bounded score with derived level.
+/// @pre Risk assessor functions receive normalized migration object collections from dry-run orchestration.
+/// @}
+void RiskAssessorModule(void);
+
+/// @defgroup index_by_uuid "index_by_uuid"
+/// @{
+/// @brief Build UUID-index from normalized objects.
+/// @post Returns mapping keyed by string uuid; only truthy uuid values are included.
+/// @pre Input list items are dict-like payloads potentially containing "uuid".
+/// @}
+void index_by_uuid(void);
+
+/// @defgroup extract_owner_identifiers "extract_owner_identifiers"
+/// @{
+/// @brief Normalize owner payloads for stable comparison.
+/// @post Returns sorted unique owner identifiers as strings.
+/// @pre Owners may be list payload, scalar values, or None.
+/// @}
+void extract_owner_identifiers(void);
+
+/// @defgroup build_risks "build_risks"
+/// @{
+/// @brief Build risk list from computed diffs and target catalog state.
+/// @post Returns list of deterministic risk items derived from overwrite, missing datasource, reference, and owner mismatch checks.
+/// @pre target_client is authenticated/usable for database list retrieval.
+/// @}
+void build_risks(void);
+
+/// @defgroup score_risks "score_risks"
+/// @{
+/// @brief Aggregate risk list into score and level.
+/// @post Returns dict with score in [0,100], derived level, and original items.
+/// @pre risk_items contains optional severity fields expected in {high,medium,low} or defaults to low weight.
+/// @}
+void score_risks(void);
+
+/// @defgroup MigrationEngineModule "MigrationEngineModule"
+/// @{
+/// @brief Transforms Superset export ZIP archives while preserving archive integrity and patching mapped identifiers.
+/// @invariant ZIP structure and non-targeted metadata must remain valid after transformation.
+/// @post Migration engine contracts preserve ZIP integrity while exposing transformation entrypoints for import pipelines.
+/// @pre Input archives are readable Superset exports and optional mapping collaborators expose remote id lookup APIs.
+/// @}
+void MigrationEngineModule(void);
+
+/// @defgroup MigrationEngine "MigrationEngine"
+/// @{
+/// @brief Engine for transforming Superset export ZIPs.
+/// @}
+void MigrationEngine(void);
+
+/// @defgroup transform_zip "transform_zip"
+/// @{
+/// @brief Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.
+/// @param fix_cross_filters (bool) - Whether to patch dashboard json_metadata.
+/// @post Returns True only when extraction, transformation, and packaging complete without exception.
+/// @pre zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.
+/// @return bool - True if successful.
+/// @}
+void transform_zip(void);
+
+/// @defgroup _transform_yaml "_transform_yaml"
+/// @{
+/// @brief Replaces database_uuid in a single YAML file.
+/// @param db_mapping (Dict[str, str]) - UUID mapping dictionary.
+/// @post database_uuid is replaced in-place only when source UUID is present in db_mapping.
+/// @pre file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.
+/// @}
+void _transform_yaml(void);
+
+/// @defgroup _extract_chart_uuids_from_archive "_extract_chart_uuids_from_archive"
+/// @{
+/// @brief Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.
+/// @param temp_dir (Path) - Root dir of unpacked archive.
+/// @post Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.
+/// @pre temp_dir exists and points to extracted archive root with optional chart YAML resources.
+/// @return Dict[int, str] - Mapping of source Integer ID to UUID.
+/// @}
+void _extract_chart_uuids_from_archive(void);
+
+/// @defgroup _patch_dashboard_metadata "_patch_dashboard_metadata"
+/// @{
+/// @brief Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.
+/// @param source_map (Dict[int, str])
+/// @post json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.
+/// @pre file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.
+/// @}
+void _patch_dashboard_metadata(void);
+
+/// @defgroup PluginBase "PluginBase"
+/// @{
+/// @brief PluginLoader scans for subclasses of PluginBase.
+/// @invariant All plugins MUST inherit from this class.
+/// @}
+void PluginBase(void);
+
+/// @defgroup id "id"
+/// @{
+/// @brief Returns the unique identifier for the plugin.
+/// @post Returns string ID.
+/// @pre Plugin instance exists.
+/// @return str - Plugin ID.
+/// @}
+void id(void);
+
+/// @defgroup name "name"
+/// @{
+/// @brief Returns the human-readable name of the plugin.
+/// @post Returns string name.
+/// @pre Plugin instance exists.
+/// @return str - Plugin name.
+/// @}
+void name(void);
+
+/// @defgroup description "description"
+/// @{
+/// @brief Returns a brief description of the plugin.
+/// @post Returns string description.
+/// @pre Plugin instance exists.
+/// @return str - Plugin description.
+/// @}
+void description(void);
+
+/// @defgroup version "version"
+/// @{
+/// @brief Returns the version of the plugin.
+/// @post Returns string version.
+/// @pre Plugin instance exists.
+/// @return str - Plugin version.
+/// @}
+void version(void);
+
+/// @defgroup required_permission "required_permission"
+/// @{
+/// @brief Returns the required permission string to execute this plugin.
+/// @post Returns string permission.
+/// @pre Plugin instance exists.
+/// @return str - Required permission (e.g., "plugin:backup:execute").
+/// @}
+void required_permission(void);
+
+/// @defgroup ui_route "ui_route"
+/// @{
+/// @brief Returns the frontend route for the plugin's UI, if applicable.
+/// @post Returns string route or None.
+/// @pre Plugin instance exists.
+/// @return Optional[str] - Frontend route.
+/// @}
+void ui_route(void);
+
+/// @defgroup get_schema "get_schema"
+/// @{
+/// @brief Returns the JSON schema for the plugin's input parameters.
+/// @post Returns dict schema.
+/// @pre Plugin instance exists.
+/// @return Dict[str, Any] - JSON schema.
+/// @}
+void get_schema(void);
+
+/// @defgroup execute "execute"
+/// @{
+/// @brief Executes the plugin's core logic.
+/// @param params (Dict[str, Any]) - Validated input parameters.
+/// @post Plugin execution is completed.
+/// @pre params must be a dictionary.
+/// @}
+void execute(void);
+
+/// @defgroup PluginConfig "PluginConfig"
+/// @{
+/// @brief Validated PluginConfig exposed to API layer.
+/// @}
+void PluginConfig(void);
+
+/// @defgroup PluginLoader "PluginLoader"
+/// @{
+/// @brief Discovers and manages available PluginBase implementations.
+/// @}
+void PluginLoader(void);
+
+/// @defgroup _load_plugins "_load_plugins"
+/// @{
+/// @brief Scans the plugin directory and loads all valid plugins.
+/// @post _load_module is called for each .py file.
+/// @pre plugin_dir exists or can be created.
+/// @}
+void _load_plugins(void);
+
+/// @defgroup _load_module "_load_module"
+/// @{
+/// @brief Loads a single Python module and discovers PluginBase implementations.
+/// @param file_path (str) - The path to the module file.
+/// @post Plugin classes are instantiated and registered.
+/// @pre module_name and file_path are valid.
+/// @}
+void _load_module(void);
+
+/// @defgroup _register_plugin "_register_plugin"
+/// @{
+/// @brief Registers a PluginBase instance and its configuration.
+/// @param plugin_instance (PluginBase) - The plugin instance to register.
+/// @post Plugin is added to _plugins and _plugin_configs.
+/// @pre plugin_instance is a valid implementation of PluginBase.
+/// @}
+void _register_plugin(void);
+
+/// @defgroup get_plugin "get_plugin"
+/// @{
+/// @brief Retrieves a loaded plugin instance by its ID.
+/// @param plugin_id (str) - The unique identifier of the plugin.
+/// @post Returns plugin instance or None.
+/// @pre plugin_id is a string.
+/// @return Optional[PluginBase] - The plugin instance if found, otherwise None.
+/// @}
+void get_plugin(void);
+
+/// @defgroup get_all_plugin_configs "get_all_plugin_configs"
+/// @{
+/// @brief Returns a list of all registered plugin configurations.
+/// @post Returns list of all PluginConfig objects.
+/// @pre None.
+/// @return List[PluginConfig] - A list of plugin configurations.
+/// @}
+void get_all_plugin_configs(void);
+
+/// @defgroup has_plugin "has_plugin"
+/// @{
+/// @brief Checks if a plugin with the given ID is registered.
+/// @param plugin_id (str) - The unique identifier of the plugin.
+/// @post Returns True if plugin exists.
+/// @pre plugin_id is a string.
+/// @return bool - True if the plugin is registered, False otherwise.
+/// @}
+void has_plugin(void);
+
+/// @defgroup SchedulerModule "SchedulerModule"
+/// @{
+/// @brief Manages scheduled tasks using APScheduler.
+/// @}
+void SchedulerModule(void);
+
+/// @defgroup SchedulerService "SchedulerService"
+/// @{
+/// @brief Provides a service to manage scheduled backup tasks.
+/// @}
+void SchedulerService(void);
+
+/// @defgroup start "start"
+/// @{
+/// @brief Starts the background scheduler and loads initial schedules.
+/// @post Scheduler is running and schedules are loaded.
+/// @pre Scheduler should be initialized.
+/// @}
+void start(void);
+
+/// @defgroup stop "stop"
+/// @{
+/// @brief Stops the background scheduler.
+/// @post Scheduler is shut down.
+/// @pre Scheduler should be running.
+/// @}
+void stop(void);
+
+/// @defgroup load_schedules "load_schedules"
+/// @{
+/// @brief Load backup and active translation schedules from config and DB, re-registering all jobs.
+/// @post All enabled backup jobs and active translation schedules are re-registered in APScheduler.
+/// @pre config_manager must have valid configuration; database is accessible.
+/// @}
+void load_schedules(void);
+
+/// @defgroup add_backup_job "add_backup_job"
+/// @{
+/// @brief Adds a scheduled backup job for an environment.
+/// @param cron_expression (str) - The cron expression for the schedule.
+/// @post A new job is added to the scheduler or replaced if it already exists.
+/// @pre env_id and cron_expression must be valid strings.
+/// @}
+void add_backup_job(void);
+
+/// @defgroup add_translation_job "add_translation_job"
+/// @{
+/// @brief Register a translation schedule with APScheduler.
+/// @post A new APScheduler job is registered or replaced if it already exists.
+/// @pre schedule_id, job_id, and cron_expression are valid strings.
+/// @}
+void add_translation_job(void);
+
+/// @defgroup remove_translation_job "remove_translation_job"
+/// @{
+/// @brief Remove a translation schedule from APScheduler.
+/// @post The APScheduler job is removed if it exists; silently ignored otherwise.
+/// @pre schedule_id is a valid string.
+/// @}
+void remove_translation_job(void);
+
+/// @defgroup _trigger_backup "_trigger_backup"
+/// @{
+/// @brief Triggered by the scheduler to start a backup task.
+/// @param env_id (str) - The ID of the environment.
+/// @post A new backup task is created in the task manager if not already running.
+/// @pre env_id must be a valid environment ID.
+/// @}
+void _trigger_backup(void);
+
+/// @defgroup add_validation_job "add_validation_job"
+/// @{
+/// @brief Register a validation policy schedule with APScheduler.
+/// @post A new APScheduler job is registered or replaced if it already exists.
+/// @pre policy_id and cron_expression are valid strings.
+/// @}
+void add_validation_job(void);
+
+/// @defgroup remove_validation_job "remove_validation_job"
+/// @{
+/// @brief Remove a validation policy schedule from APScheduler.
+/// @post The APScheduler job is removed if it exists; silently ignored otherwise.
+/// @pre policy_id is a valid string.
+/// @}
+void remove_validation_job(void);
+
+/// @defgroup reload_validation_policy "reload_validation_policy"
+/// @{
+/// @brief Reload a single validation policy schedule — calls remove then add.
+/// @post Old job is removed; new job is registered if policy is active and has schedule_days.
+/// @pre policy_id is a valid ValidationPolicy id with schedule data in DB.
+/// @}
+void reload_validation_policy(void);
+
+/// @defgroup _trigger_validation "_trigger_validation"
+/// @{
+/// @brief APScheduler job handler — triggers validation runs for a policy.
+/// @post A validation task is spawned via TaskManager for each dashboard in the policy.
+/// @pre policy_id is a valid ValidationPolicy id with dashboard_ids.
+/// @}
+void _trigger_validation(void);
+
+/// @defgroup ThrottledSchedulerConfigurator "ThrottledSchedulerConfigurator"
+/// @{
+/// @brief Distributes validation tasks evenly within an execution window.
+/// @invariant Returned schedule size always matches number of dashboard IDs.
+/// @post Produces deterministic per-dashboard run timestamps within the configured window.
+/// @pre Validation policies provide a finite dashboard list and a valid execution window.
+/// @}
+void ThrottledSchedulerConfigurator(void);
+
+/// @defgroup calculate_schedule "calculate_schedule"
+/// @{
+/// @brief Calculates execution times for N tasks within a window.
+/// @invariant Tasks are distributed with near-even spacing.
+/// @post Returns List[EXT:Python:datetime] of scheduled times.
+/// @pre window_start, window_end (time), dashboard_ids (List), current_date (date).
+/// @}
+void calculate_schedule(void);
+
+/// @defgroup SupersetClientModule "SupersetClientModule"
+/// @{
+/// @brief Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
+/// @invariant All network operations must use the internal APIClient instance.
+/// @}
+void SupersetClientModule(void);
+
+/// @defgroup SupersetClient "SupersetClient"
+/// @{
+/// @brief Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
+/// @}
+void SupersetClient(void);
+
+/// @defgroup SupersetClientBase "SupersetClientBase"
+/// @{
+/// @brief Base class for SupersetClient providing initialization, authentication, pagination, and import/export helpers.
+/// @}
+void SupersetClientBase(void);
+
+/// @defgroup SupersetClientInit "SupersetClientInit"
+/// @{
+/// @brief Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
+/// @}
+void SupersetClientInit(void);
+
+/// @defgroup SupersetClientAuthenticate "SupersetClientAuthenticate"
+/// @{
+/// @brief Authenticates the client using the configured credentials.
+/// @}
+void SupersetClientAuthenticate(void);
+
+/// @defgroup SupersetClientHeaders "SupersetClientHeaders"
+/// @{
+/// @brief Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
+/// @}
+void SupersetClientHeaders(void);
+
+/// @defgroup SupersetClientValidateQueryParams "SupersetClientValidateQueryParams"
+/// @{
+/// @brief Ensures query parameters have default page and page_size.
+/// @}
+void SupersetClientValidateQueryParams(void);
+
+/// @defgroup SupersetClientFetchTotalObjectCount "SupersetClientFetchTotalObjectCount"
+/// @{
+/// @brief Fetches the total number of items for a given endpoint.
+/// @}
+void SupersetClientFetchTotalObjectCount(void);
+
+/// @defgroup SupersetClientFetchAllPages "SupersetClientFetchAllPages"
+/// @{
+/// @brief Iterates through all pages to collect all data items.
+/// @}
+void SupersetClientFetchAllPages(void);
+
+/// @defgroup SupersetClientDoImport "SupersetClientDoImport"
+/// @{
+/// @brief Performs the actual multipart upload for import.
+/// @}
+void SupersetClientDoImport(void);
+
+/// @defgroup SupersetClientValidateExportResponse "SupersetClientValidateExportResponse"
+/// @{
+/// @brief Validates that the export response is a non-empty ZIP archive.
+/// @}
+void SupersetClientValidateExportResponse(void);
+
+/// @defgroup SupersetClientResolveExportFilename "SupersetClientResolveExportFilename"
+/// @{
+/// @brief Determines the filename for an exported dashboard.
+/// @}
+void SupersetClientResolveExportFilename(void);
+
+/// @defgroup SupersetClientValidateImportFile "SupersetClientValidateImportFile"
+/// @{
+/// @brief Validates that the file to be imported is a valid ZIP with metadata.yaml.
+/// @}
+void SupersetClientValidateImportFile(void);
+
+/// @defgroup SupersetClientResolveTargetIdForDelete "SupersetClientResolveTargetIdForDelete"
+/// @{
+/// @brief Resolves a dashboard ID from either an ID or a slug.
+/// @}
+void SupersetClientResolveTargetIdForDelete(void);
+
+/// @defgroup SupersetClientGetAllResources "SupersetClientGetAllResources"
+/// @{
+/// @brief Fetches all resources of a given type with id, uuid, and name columns.
+/// @}
+void SupersetClientGetAllResources(void);
+
+/// @defgroup SupersetChartsMixin "SupersetChartsMixin"
+/// @{
+/// @brief Chart domain mixin for SupersetClient — list, get, extract IDs from layout.
+/// @}
+void SupersetChartsMixin(void);
+
+/// @defgroup SupersetClientGetChart "SupersetClientGetChart"
+/// @{
+/// @brief Fetches a single chart by ID.
+/// @}
+void SupersetClientGetChart(void);
+
+/// @defgroup SupersetClientGetCharts "SupersetClientGetCharts"
+/// @{
+/// @brief Fetches all charts with pagination support.
+/// @}
+void SupersetClientGetCharts(void);
+
+/// @defgroup SupersetClientExtractChartIdsFromLayout "SupersetClientExtractChartIdsFromLayout"
+/// @{
+/// @brief Traverses dashboard layout metadata and extracts chart IDs from common keys.
+/// @}
+void SupersetClientExtractChartIdsFromLayout(void);
+
+/// @defgroup SupersetDashboardsCrudMixin "SupersetDashboardsCrudMixin"
+/// @{
+/// @brief Dashboard CRUD mixin for SupersetClient — detail, export, import, delete.
+/// @}
+void SupersetDashboardsCrudMixin(void);
+
+/// @defgroup SupersetClientGetDashboardDetail "SupersetClientGetDashboardDetail"
+/// @{
+/// @brief Fetches detailed dashboard information including related charts and datasets.
+/// @}
+void SupersetClientGetDashboardDetail(void);
+
+/// @defgroup extract_dataset_id_from_form_data "extract_dataset_id_from_form_data"
+/// @{
+/// @}
+void extract_dataset_id_from_form_data(void);
+
+/// @defgroup SupersetClientExportDashboard "SupersetClientExportDashboard"
+/// @{
+/// @brief Экспортирует дашборд в виде ZIP-архива.
+/// @}
+void SupersetClientExportDashboard(void);
+
+/// @defgroup SupersetClientImportDashboard "SupersetClientImportDashboard"
+/// @{
+/// @brief Импортирует дашборд из ZIP-файла.
+/// @}
+void SupersetClientImportDashboard(void);
+
+/// @defgroup SupersetClientDeleteDashboard "SupersetClientDeleteDashboard"
+/// @{
+/// @brief Удаляет дашборд по его ID или slug.
+/// @}
+void SupersetClientDeleteDashboard(void);
+
+/// @defgroup SupersetDashboardsFiltersMixin "SupersetDashboardsFiltersMixin"
+/// @{
+/// @brief Dashboard native filter extraction mixin for SupersetClient.
+/// @}
+void SupersetDashboardsFiltersMixin(void);
+
+/// @defgroup SupersetClientGetDashboard "SupersetClientGetDashboard"
+/// @{
+/// @brief Fetches a single dashboard by ID or slug.
+/// @}
+void SupersetClientGetDashboard(void);
+
+/// @defgroup SupersetClientGetDashboardPermalinkState "SupersetClientGetDashboardPermalinkState"
+/// @{
+/// @brief Fetches stored dashboard permalink state by permalink key.
+/// @}
+void SupersetClientGetDashboardPermalinkState(void);
+
+/// @defgroup SupersetClientGetNativeFilterState "SupersetClientGetNativeFilterState"
+/// @{
+/// @brief Fetches stored native filter state by filter state key.
+/// @}
+void SupersetClientGetNativeFilterState(void);
+
+/// @defgroup SupersetClientExtractNativeFiltersFromPermalink "SupersetClientExtractNativeFiltersFromPermalink"
+/// @{
+/// @brief Extract native filters dataMask from a permalink key.
+/// @}
+void SupersetClientExtractNativeFiltersFromPermalink(void);
+
+/// @defgroup SupersetClientExtractNativeFiltersFromKey "SupersetClientExtractNativeFiltersFromKey"
+/// @{
+/// @brief Extract native filters from a native_filters_key URL parameter.
+/// @}
+void SupersetClientExtractNativeFiltersFromKey(void);
+
+/// @defgroup SupersetClientParseDashboardUrlForFilters "SupersetClientParseDashboardUrlForFilters"
+/// @{
+/// @brief Parse a Superset dashboard URL and extract native filter state if present.
+/// @}
+void SupersetClientParseDashboardUrlForFilters(void);
+
+/// @defgroup SupersetDashboardsListMixin "SupersetDashboardsListMixin"
+/// @{
+/// @brief Dashboard listing mixin for SupersetClient — paginated list, summary projection.
+/// @}
+void SupersetDashboardsListMixin(void);
+
+/// @defgroup SupersetClientGetDashboards "SupersetClientGetDashboards"
+/// @{
+/// @brief Получает полный список дашбордов, автоматически обрабатывая пагинацию.
+/// @}
+void SupersetClientGetDashboards(void);
+
+/// @defgroup SupersetClientGetDashboardsPage "SupersetClientGetDashboardsPage"
+/// @{
+/// @brief Fetches a single dashboards page from Superset without iterating all pages.
+/// @}
+void SupersetClientGetDashboardsPage(void);
+
+/// @defgroup SupersetClientGetDashboardsSummary "SupersetClientGetDashboardsSummary"
+/// @{
+/// @brief Fetches dashboard metadata optimized for the grid.
+/// @}
+void SupersetClientGetDashboardsSummary(void);
+
+/// @defgroup SupersetClientGetDashboardsSummaryPage "SupersetClientGetDashboardsSummaryPage"
+/// @{
+/// @brief Fetches one page of dashboard metadata optimized for the grid.
+/// @}
+void SupersetClientGetDashboardsSummaryPage(void);
+
+/// @defgroup SupersetDashboardsWriteMixin "SupersetDashboardsWriteMixin"
+/// @{
+/// @brief Dashboard write mixin for SupersetClient — markdown chart CRUD and layout manipulation for maintenance banners.
+/// @invariant All network operations use self.network.request()
+/// @}
+void SupersetDashboardsWriteMixin(void);
+
+/// @defgroup create_markdown_chart "create_markdown_chart"
+/// @{
+/// @brief Create a markdown chart and return the new chart ID.
+/// @post Returns chart_id (int). Chart is NOT yet placed in dashboard layout.
+/// @pre dashboard_id exists in Superset. markdown_text not empty.
+/// @}
+void create_markdown_chart(void);
+
+/// @defgroup update_markdown_chart "update_markdown_chart"
+/// @{
+/// @brief Update the markdown text of an existing markdown chart.
+/// @post Chart markdown content updated.
+/// @pre chart_id exists and is a markdown chart.
+/// @}
+void update_markdown_chart(void);
+
+/// @defgroup update_dashboard_layout "update_dashboard_layout"
+/// @{
+/// @brief Insert a native MARKDOWN element at (0,0) with full width (12 cols),
+/// @}
+void update_dashboard_layout(void);
+
+/// @defgroup remove_chart_from_layout "remove_chart_from_layout"
+/// @{
+/// @brief Remove banner markdown element from dashboard layout without deleting the chart.
+/// @post MARKDOWN element removed from position_json; items shifted up.
+/// @pre dashboard_id exists. chart_id exists in layout as MARKDOWN-banner-{chart_id}.
+/// @}
+void remove_chart_from_layout(void);
+
+/// @defgroup delete_chart "delete_chart"
+/// @{
+/// @brief Delete a chart from Superset by ID.
+/// @post Chart permanently deleted from Superset.
+/// @pre chart_id exists.
+/// @}
+void delete_chart(void);
+
+/// @defgroup update_banner_on_dashboard "update_banner_on_dashboard"
+/// @{
+/// @brief Update the content of a native MARKDOWN banner element on a dashboard.
+/// @post MARKDOWN element content updated on dashboard.
+/// @pre dashboard_id exists. chart_id used for key lookup.
+/// @}
+void update_banner_on_dashboard(void);
+
+/// @defgroup get_dashboard_layout "get_dashboard_layout"
+/// @{
+/// @brief Fetch the position_json layout of a dashboard.
+/// @post Returns the dashboard layout dict.
+/// @pre dashboard_id exists.
+/// @}
+void get_dashboard_layout(void);
+
+/// @defgroup _resolve_markdown_datasource "_resolve_markdown_datasource"
+/// @{
+/// @brief Find a valid datasource_id for markdown chart creation.
+/// @post Returns an integer datasource_id.
+/// @pre dashboard_id exists.
+/// @}
+void _resolve_markdown_datasource(void);
+
+/// @defgroup SupersetDatabasesMixin "SupersetDatabasesMixin"
+/// @{
+/// @brief Database domain mixin for SupersetClient — list, get, summary, by_uuid.
+/// @}
+void SupersetDatabasesMixin(void);
+
+/// @defgroup SupersetClientGetDatabases "SupersetClientGetDatabases"
+/// @{
+/// @brief Получает полный список баз данных.
+/// @}
+void SupersetClientGetDatabases(void);
+
+/// @defgroup SupersetClientGetDatabase "SupersetClientGetDatabase"
+/// @{
+/// @brief Получает информацию о конкретной базе данных по её ID.
+/// @}
+void SupersetClientGetDatabase(void);
+
+/// @defgroup SupersetClientGetDatabasesSummary "SupersetClientGetDatabasesSummary"
+/// @{
+/// @brief Fetch a summary of databases including uuid, name, and engine.
+/// @}
+void SupersetClientGetDatabasesSummary(void);
+
+/// @defgroup SupersetClientGetDatabaseByUuid "SupersetClientGetDatabaseByUuid"
+/// @{
+/// @brief Find a database by its UUID.
+/// @}
+void SupersetClientGetDatabaseByUuid(void);
+
+/// @defgroup SupersetDatasetsMixin "SupersetDatasetsMixin"
+/// @{
+/// @brief Dataset domain mixin for SupersetClient — list, get, detail, update.
+/// @}
+void SupersetDatasetsMixin(void);
+
+/// @defgroup SupersetClientGetDatasets "SupersetClientGetDatasets"
+/// @{
+/// @brief Получает полный список датасетов, автоматически обрабатывая пагинацию.
+/// @}
+void SupersetClientGetDatasets(void);
+
+/// @defgroup SupersetClientGetDatasetsSummary "SupersetClientGetDatasetsSummary"
+/// @{
+/// @brief Fetches dataset metadata optimized for the Dataset Hub grid.
+/// @}
+void SupersetClientGetDatasetsSummary(void);
+
+/// @defgroup SupersetClientGetDatasetLinkedDashboardCount "SupersetClientGetDatasetLinkedDashboardCount"
+/// @{
+/// @brief Fetch the number of dashboards linked to a dataset via related_objects endpoint.
+/// @}
+void SupersetClientGetDatasetLinkedDashboardCount(void);
+
+/// @defgroup SupersetClientGetDatasetDetail "SupersetClientGetDatasetDetail"
+/// @{
+/// @brief Fetches detailed dataset information including columns and linked dashboards.
+/// @}
+void SupersetClientGetDatasetDetail(void);
+
+/// @defgroup SupersetClientGetDataset "SupersetClientGetDataset"
+/// @{
+/// @brief Получает информацию о конкретном датасете по его ID.
+/// @}
+void SupersetClientGetDataset(void);
+
+/// @defgroup SupersetClientUpdateDataset "SupersetClientUpdateDataset"
+/// @{
+/// @brief Обновляет данные датасета по его ID.
+/// @}
+void SupersetClientUpdateDataset(void);
+
+/// @defgroup SupersetDatasetsPreviewMixin "SupersetDatasetsPreviewMixin"
+/// @{
+/// @brief Dataset preview compilation mixin for SupersetClient — build query context, compile SQL.
+/// @}
+void SupersetDatasetsPreviewMixin(void);
+
+/// @defgroup SupersetClientCompileDatasetPreview "SupersetClientCompileDatasetPreview"
+/// @{
+/// @brief Compile dataset preview SQL through the strongest supported Superset preview endpoint family and return normalized SQL output.
+/// @}
+void SupersetClientCompileDatasetPreview(void);
+
+/// @defgroup SupersetClientBuildDatasetPreviewLegacyFormData "SupersetClientBuildDatasetPreviewLegacyFormData"
+/// @{
+/// @brief Build browser-style legacy form_data payload for Superset preview endpoints inferred from observed deployment traffic.
+/// @}
+void SupersetClientBuildDatasetPreviewLegacyFormData(void);
+
+/// @defgroup SupersetClientBuildDatasetPreviewQueryContext "SupersetClientBuildDatasetPreviewQueryContext"
+/// @{
+/// @brief Build a reduced-scope chart-data query context for deterministic dataset preview compilation.
+/// @}
+void SupersetClientBuildDatasetPreviewQueryContext(void);
+
+/// @defgroup SupersetDatasetsPreviewFiltersMixin "SupersetDatasetsPreviewFiltersMixin"
+/// @{
+/// @brief Filter normalization and SQL extraction helpers for dataset preview compilation.
+/// @}
+void SupersetDatasetsPreviewFiltersMixin(void);
+
+/// @defgroup SupersetClientNormalizeEffectiveFiltersForQueryContext "SupersetClientNormalizeEffectiveFiltersForQueryContext"
+/// @{
+/// @brief Convert execution mappings into Superset chart-data filter objects.
+/// @}
+void SupersetClientNormalizeEffectiveFiltersForQueryContext(void);
+
+/// @defgroup SupersetClientExtractCompiledSqlFromPreviewResponse "SupersetClientExtractCompiledSqlFromPreviewResponse"
+/// @{
+/// @brief Normalize compiled SQL from either chart-data or legacy form_data preview responses.
+/// @}
+void SupersetClientExtractCompiledSqlFromPreviewResponse(void);
+
+/// @defgroup LayoutUtils "LayoutUtils"
+/// @{
+/// @brief Utility functions for manipulating Superset dashboard position_json layout.
+/// @}
+void LayoutUtils(void);
+
+/// @defgroup parse_position_json "parse_position_json"
+/// @{
+/// @brief Parse position_json from a dashboard API response (may be string or dict).
+/// @post Returns a dict.
+/// @pre raw_position is a string, dict, or None.
+/// @}
+void parse_position_json(void);
+
+/// @defgroup _estimate_markdown_height "_estimate_markdown_height"
+/// @{
+/// @brief Estimate grid height for a MARKDOWN element based on HTML content.
+/// @}
+void _estimate_markdown_height(void);
+
+/// @defgroup _generate_banner_id "_generate_banner_id"
+/// @{
+/// @brief Generate a deterministic row and markdown key for a banner chart.
+/// @}
+void _generate_banner_id(void);
+
+/// @defgroup insert_banner_markdown_at_top "insert_banner_markdown_at_top"
+/// @{
+/// @brief Insert a ROW + native MARKDOWN pair at the top of the dashboard grid.
+/// @}
+void insert_banner_markdown_at_top(void);
+
+/// @defgroup update_banner_markdown_content "update_banner_markdown_content"
+/// @{
+/// @brief Update the code content and adaptive height of an existing banner markdown element.
+/// @post position_json is mutated; markdown content and height updated.
+/// @pre position_json has markdown_key. content is the new HTML/markdown string.
+/// @}
+void update_banner_markdown_content(void);
+
+/// @defgroup remove_banner_from_position "remove_banner_from_position"
+/// @{
+/// @brief Remove the banner ROW + MARKDOWN pair from the position dict and GRID children.
+/// @}
+void remove_banner_from_position(void);
+
+/// @defgroup SupersetUserProjection "SupersetUserProjection"
+/// @{
+/// @brief User/owner payload normalization helpers for Superset client responses.
+/// @}
+void SupersetUserProjection(void);
+
+/// @defgroup SupersetUserProjectionMixin "SupersetUserProjectionMixin"
+/// @{
+/// @brief Mixin providing user/owner payload normalization for Superset API responses.
+/// @}
+void SupersetUserProjectionMixin(void);
+
+/// @defgroup SupersetClientExtractOwnerLabels "SupersetClientExtractOwnerLabels"
+/// @{
+/// @brief Normalize dashboard owners payload to stable display labels.
+/// @}
+void SupersetClientExtractOwnerLabels(void);
+
+/// @defgroup SupersetClientExtractUserDisplay "SupersetClientExtractUserDisplay"
+/// @{
+/// @brief Normalize user payload to a stable display name.
+/// @}
+void SupersetClientExtractUserDisplay(void);
+
+/// @defgroup SupersetClientSanitizeUserText "SupersetClientSanitizeUserText"
+/// @{
+/// @brief Convert scalar value to non-empty user-facing text.
+/// @}
+void SupersetClientSanitizeUserText(void);
+
+/// @defgroup SupersetProfileLookup "SupersetProfileLookup"
+/// @{
+/// @brief Provides environment-scoped Superset account lookup adapter with stable normalized output.
+/// @invariant Adapter never leaks raw upstream payload shape to API consumers.
+/// @}
+void SupersetProfileLookup(void);
+
+/// @defgroup SupersetAccountLookupAdapter "SupersetAccountLookupAdapter"
+/// @{
+/// @brief Lookup Superset users and normalize candidates for profile binding.
+/// @}
+void SupersetAccountLookupAdapter(void);
+
+/// @defgroup __init__ "__init__"
+/// @{
+/// @brief Initializes lookup adapter with authenticated API client and environment context.
+/// @post Adapter is ready to perform users lookup requests.
+/// @pre network_client supports request(method, endpoint, params=...).
+/// @}
+void __init__(void);
+
+/// @defgroup get_users_page "get_users_page"
+/// @{
+/// @brief Fetch one users page from Superset with passthrough search/sort parameters.
+/// @post Returns deterministic payload with normalized items and total count.
+/// @pre page_index >= 0 and page_size >= 1.
+/// @return Dict[str, Any]
+/// @}
+void get_users_page(void);
+
+/// @defgroup _normalize_lookup_payload "_normalize_lookup_payload"
+/// @{
+/// @brief Convert Superset users response variants into stable candidates payload.
+/// @post Output contains canonical keys: status, environment_id, page_index, page_size, total, items.
+/// @pre response can be dict/list in any supported upstream shape.
+/// @return Dict[str, Any]
+/// @}
+void _normalize_lookup_payload(void);
+
+/// @defgroup normalize_user_payload "normalize_user_payload"
+/// @{
+/// @brief Project raw Superset user object to canonical candidate shape.
+/// @post Returns normalized candidate keys (environment_id, username, display_name, email, is_active).
+/// @pre raw_user may have heterogenous key names between Superset versions.
+/// @return Dict[str, Any]
+/// @}
+void normalize_user_payload(void);
+
+/// @defgroup TaskManagerPackage "TaskManagerPackage"
+/// @{
+/// @}
+void TaskManagerPackage(void);
+
+/// @defgroup TestContext "TestContext"
+/// @{
+/// @brief Verify TaskContext preserves optional background task scheduler across sub-context creation.
+/// @}
+void TestContext(void);
+
+/// @defgroup test_task_context_preserves_background_tasks_across_sub_context "test_task_context_preserves_background_tasks_across_sub_context"
+/// @{
+/// @brief Plugins must be able to access background_tasks from both root and sub-context loggers.
+/// @post background_tasks remains available on root and derived sub-contexts.
+/// @pre TaskContext is initialized with a BackgroundTasks-like object.
+/// @}
+void test_task_context_preserves_background_tasks_across_sub_context(void);
+
+/// @defgroup __tests___test_task_logger "__tests__/test_task_logger"
+/// @{
+/// @brief Contract testing for TaskLogger
+/// @}
+void __tests___test_task_logger(void);
+
+/// @defgroup test_task_logger_initialization "test_task_logger_initialization"
+/// @{
+/// @brief Verify TaskLogger initializes with correct task_id and state.
+/// @}
+void test_task_logger_initialization(void);
+
+/// @defgroup test_log_methods_delegation "test_log_methods_delegation"
+/// @{
+/// @brief Verify TaskLogger delegates log method calls to the underlying persistence service.
+/// @}
+void test_log_methods_delegation(void);
+
+/// @defgroup test_with_source "test_with_source"
+/// @{
+/// @brief Verify TaskLogger.with_source returns a new logger with the correct source attribution.
+/// @}
+void test_with_source(void);
+
+/// @defgroup test_missing_task_id "test_missing_task_id"
+/// @{
+/// @brief Verify TaskLogger raises or handles missing task_id gracefully.
+/// @}
+void test_missing_task_id(void);
+
+/// @defgroup test_invalid_add_log_fn "test_invalid_add_log_fn"
+/// @{
+/// @brief Verify TaskLogger raises ValueError for invalid add_log_fn parameter.
+/// @}
+void test_invalid_add_log_fn(void);
+
+/// @defgroup test_progress_log "test_progress_log"
+/// @{
+/// @brief Verify TaskLogger correctly logs progress updates with percentage and message.
+/// @}
+void test_progress_log(void);
+
+/// @defgroup TaskCleanupModule "TaskCleanupModule"
+/// @{
+/// @brief Implements task cleanup and retention policies, including associated logs.
+/// @}
+void TaskCleanupModule(void);
+
+/// @defgroup TaskCleanupService "TaskCleanupService"
+/// @{
+/// @brief Provides methods to clean up old task records and their associated logs.
+/// @}
+void TaskCleanupService(void);
+
+/// @defgroup run_cleanup "run_cleanup"
+/// @{
+/// @brief Deletes tasks older than the configured retention period and their logs.
+/// @post Old tasks and their logs are deleted from persistence.
+/// @pre Config manager has valid settings.
+/// @}
+void run_cleanup(void);
+
+/// @defgroup delete_task_with_logs "delete_task_with_logs"
+/// @{
+/// @brief Delete a single task and all its associated logs.
+/// @param task_id (str) - The task ID to delete.
+/// @post Task and all its logs are deleted.
+/// @pre task_id is a valid task ID.
+/// @}
+void delete_task_with_logs(void);
+
+/// @defgroup TaskContextModule "TaskContextModule"
+/// @{
+/// @brief Provides execution context passed to plugins during task execution.
+/// @invariant Each TaskContext is bound to a single task execution.
+/// @post Plugins receive context instances with stable logger and parameter accessors.
+/// @pre Task execution pipeline provides valid task identifiers, logging callbacks, and parameter dictionaries.
+/// @}
+void TaskContextModule(void);
+
+/// @defgroup TaskContext "TaskContext"
+/// @{
+/// @brief A container passed to plugin.execute() providing the logger and other task-specific utilities.
+/// @invariant logger is always a valid TaskLogger instance.
+/// @post Instance exposes immutable task identity with logger, params, and optional background task access.
+/// @pre Constructor receives non-empty task_id, callable add_log_fn, and params mapping.
+/// @}
+void TaskContext(void);
+
+/// @defgroup task_id "task_id"
+/// @{
+/// @brief Get the task ID.
+/// @post Returns the task ID string.
+/// @pre TaskContext must be initialized.
+/// @return str - The task ID.
+/// @}
+void task_id(void);
+
+/// @defgroup logger "logger"
+/// @{
+/// @brief Get the TaskLogger instance for this context.
+/// @post Returns the TaskLogger instance.
+/// @pre TaskContext must be initialized.
+/// @return TaskLogger - The logger instance.
+/// @}
+void logger(void);
+
+/// @defgroup params "params"
+/// @{
+/// @brief Get the task parameters.
+/// @post Returns the parameters dictionary.
+/// @pre TaskContext must be initialized.
+/// @return Dict[str, Any] - The task parameters.
+/// @}
+void params(void);
+
+/// @defgroup background_tasks "background_tasks"
+/// @{
+/// @brief Expose optional background task scheduler for plugins that dispatch deferred side effects.
+/// @post Returns BackgroundTasks-like object or None.
+/// @pre TaskContext must be initialized.
+/// @}
+void background_tasks(void);
+
+/// @defgroup get_param "get_param"
+/// @{
+/// @brief Get a specific parameter value with optional default.
+/// @param default (Any) - Default value if key not found.
+/// @post Returns parameter value or default.
+/// @pre TaskContext must be initialized.
+/// @return Any - Parameter value or default.
+/// @}
+void get_param(void);
+
+/// @defgroup create_sub_context "create_sub_context"
+/// @{
+/// @brief Create a sub-context with a different default source.
+/// @param source (str) - New default source for logging.
+/// @post Returns new TaskContext with different logger source.
+/// @pre source is a non-empty string.
+/// @return TaskContext - New context with different source.
+/// @}
+void create_sub_context(void);
+
+/// @defgroup EventBusModule "EventBusModule"
+/// @{
+/// @brief Task-scoped log buffering, persistence flushes, and subscriber fan-out for real-time
+/// @}
+void EventBusModule(void);
+
+/// @defgroup EventBus "EventBus"
+/// @{
+/// @brief Coordinates task-scoped log buffering, persistence flushes, and subscriber fan-out
+/// @}
+void EventBus(void);
+
+/// @defgroup flush_task_logs "flush_task_logs"
+/// @{
+/// @brief Flush logs for a specific task immediately.
+/// @post Task's buffered logs are written to database.
+/// @pre task_id exists.
+/// @}
+void flush_task_logs(void);
+
+/// @defgroup add_log "add_log"
+/// @{
+/// @brief Adds a log entry to a task buffer and notifies subscribers.
+/// @post Log added to buffer and pushed to queues (if level meets task_log_level filter).
+/// @pre Task exists.
+/// @}
+void add_log(void);
+
+/// @defgroup TaskGraphModule "TaskGraphModule"
+/// @{
+/// @brief In-memory task registry with persistence-backed hydration, pagination, and
+/// @}
+void TaskGraphModule(void);
+
+/// @defgroup TaskGraph "TaskGraph"
+/// @{
+/// @brief In-memory task dependency graph spanning task registry nodes, pause futures,
+/// @}
+void TaskGraph(void);
+
+/// @defgroup add_task "add_task"
+/// @{
+/// @brief Register a task in the in-memory registry.
+/// @}
+void add_task(void);
+
+/// @defgroup remove_tasks "remove_tasks"
+/// @{
+/// @brief Remove tasks from registry and persistence, cancel futures for waiting tasks.
+/// @}
+void remove_tasks(void);
+
+/// @defgroup create_future "create_future"
+/// @{
+/// @brief Create and store a future for a paused task.
+/// @}
+void create_future(void);
+
+/// @defgroup resolve_future "resolve_future"
+/// @{
+/// @brief Resolve a paused task's future and remove it from the map.
+/// @}
+void resolve_future(void);
+
+/// @defgroup remove_future "remove_future"
+/// @{
+/// @brief Remove a future without resolving it.
+/// @}
+void remove_future(void);
+
+/// @defgroup JobLifecycleModule "JobLifecycleModule"
+/// @{
+/// @brief Task creation, execution, pause/resume, and completion transitions for plugin-backed
+/// @}
+void JobLifecycleModule(void);
+
+/// @defgroup JobLifecycle "JobLifecycle"
+/// @{
+/// @brief Encodes task creation, execution, pause/resume, and completion transitions for
+/// @}
+void JobLifecycle(void);
+
+/// @defgroup _broadcast_dataset_updated "_broadcast_dataset_updated"
+/// @{
+/// @brief Broadcast dataset.updated event to all subscribers for a given environment.
+/// @}
+void _broadcast_dataset_updated(void);
+
+/// @defgroup TaskManagerModule "TaskManagerModule"
+/// @{
+/// @brief Thin facade composing TaskGraph (registry), EventBus (log/pub-sub), and JobLifecycle
+/// @}
+void TaskManagerModule(void);
+
+/// @defgroup TaskManager "TaskManager"
+/// @{
+/// @brief Facade composing TaskGraph, EventBus, and JobLifecycle into a single interface.
+/// @post In-memory task graph, lifecycle scheduler, and log event bus stay consistent with
+/// @pre Plugin loader resolves plugin ids and persistence services are available.
+/// @}
+void TaskManager(void);
+
+/// @defgroup _make_add_log_callback "_make_add_log_callback"
+/// @{
+/// @brief Create a closure for adding logs that looks up the task and delegates to EventBus.
+/// @}
+void _make_add_log_callback(void);
+
+/// @defgroup _flusher_loop "_flusher_loop"
+/// @{
+/// @brief Legacy alias delegating to EventBus._flusher_loop.
+/// @}
+void _flusher_loop(void);
+
+/// @defgroup _flush_logs "_flush_logs"
+/// @{
+/// @brief Legacy alias delegating to EventBus._flush_logs.
+/// @}
+void _flush_logs(void);
+
+/// @defgroup _flush_task_logs "_flush_task_logs"
+/// @{
+/// @brief Legacy alias delegating to EventBus.flush_task_logs.
+/// @}
+void _flush_task_logs(void);
+
+/// @defgroup get_task "get_task"
+/// @{
+/// @brief Retrieves a task by its ID.
+/// @}
+void get_task(void);
+
+/// @defgroup get_all_tasks "get_all_tasks"
+/// @{
+/// @brief Retrieves all registered tasks.
+/// @}
+void get_all_tasks(void);
+
+/// @defgroup get_tasks "get_tasks"
+/// @{
+/// @brief Retrieves tasks with pagination and optional status filter.
+/// @}
+void get_tasks(void);
+
+/// @defgroup load_persisted_tasks "load_persisted_tasks"
+/// @{
+/// @brief Load persisted tasks using persistence service.
+/// @}
+void load_persisted_tasks(void);
+
+/// @defgroup clear_tasks "clear_tasks"
+/// @{
+/// @brief Clears tasks based on status filter (also deletes associated logs).
+/// @}
+void clear_tasks(void);
+
+/// @defgroup get_task_logs "get_task_logs"
+/// @{
+/// @brief Retrieves logs for a specific task (from memory or persistence).
+/// @}
+void get_task_logs(void);
+
+/// @defgroup get_task_log_stats "get_task_log_stats"
+/// @{
+/// @brief Get statistics about logs for a task.
+/// @}
+void get_task_log_stats(void);
+
+/// @defgroup get_task_log_sources "get_task_log_sources"
+/// @{
+/// @brief Get unique sources for a task's logs.
+/// @}
+void get_task_log_sources(void);
+
+/// @defgroup subscribe_logs "subscribe_logs"
+/// @{
+/// @brief Subscribes to real-time logs for a task.
+/// @}
+void subscribe_logs(void);
+
+/// @defgroup unsubscribe_logs "unsubscribe_logs"
+/// @{
+/// @brief Unsubscribes from real-time logs for a task.
+/// @}
+void unsubscribe_logs(void);
+
+/// @defgroup create_task "create_task"
+/// @{
+/// @brief Creates and queues a new task for execution.
+/// @}
+void create_task(void);
+
+/// @defgroup _run_task "_run_task"
+/// @{
+/// @brief Internal method to execute a task with TaskContext support (delegates to lifecycle).
+/// @}
+void _run_task(void);
+
+/// @defgroup resolve_task "resolve_task"
+/// @{
+/// @brief Resumes a task that is awaiting mapping.
+/// @}
+void resolve_task(void);
+
+/// @defgroup wait_for_resolution "wait_for_resolution"
+/// @{
+/// @brief Pauses execution and waits for a resolution signal.
+/// @}
+void wait_for_resolution(void);
+
+/// @defgroup wait_for_input "wait_for_input"
+/// @{
+/// @brief Pauses execution and waits for user input.
+/// @}
+void wait_for_input(void);
+
+/// @defgroup await_input "await_input"
+/// @{
+/// @brief Transition a task to AWAITING_INPUT state with input request.
+/// @}
+void await_input(void);
+
+/// @defgroup resume_task_with_password "resume_task_with_password"
+/// @{
+/// @brief Resume a task that is awaiting input with provided passwords.
+/// @}
+void resume_task_with_password(void);
+
+/// @defgroup subscribe_dataset_events "subscribe_dataset_events"
+/// @{
+/// @brief Subscribe to dataset.updated events for an environment.
+/// @}
+void subscribe_dataset_events(void);
+
+/// @defgroup unsubscribe_dataset_events "unsubscribe_dataset_events"
+/// @{
+/// @brief Unsubscribe from dataset.updated events.
+/// @}
+void unsubscribe_dataset_events(void);
+
+/// @defgroup TaskManagerModels "TaskManagerModels"
+/// @{
+/// @brief Defines the data models and enumerations used by the Task Manager.
+/// @invariant Must use Pydantic for data validation.
+/// @post Task models exported with immutable IDs
+/// @pre Task manager initialized
+/// @}
+void TaskManagerModels(void);
+
+/// @defgroup TaskStatus "TaskStatus"
+/// @{
+/// @}
+void TaskStatus(void);
+
+/// @defgroup LogLevel "LogLevel"
+/// @{
+/// @}
+void LogLevel(void);
+
+/// @defgroup TaskLog "TaskLog"
+/// @{
+/// @brief A Pydantic model representing a persisted log entry from the database.
+/// @}
+void TaskLog(void);
+
+/// @defgroup LogFilter "LogFilter"
+/// @{
+/// @}
+void LogFilter(void);
+
+/// @defgroup LogStats "LogStats"
+/// @{
+/// @brief Statistics about log entries for a task.
+/// @}
+void LogStats(void);
+
+/// @defgroup Task "Task"
+/// @{
+/// @brief A Pydantic model representing a single execution instance of a plugin, including its status, parameters, and logs.
+/// @}
+void Task(void);
+
+/// @defgroup TaskPersistenceModule "TaskPersistenceModule"
+/// @{
+/// @brief Handles the persistence of tasks using SQLAlchemy and the tasks.db database.
+/// @invariant Database schema must match the TaskRecord model structure.
+/// @post Provides reliable storage and retrieval for task metadata and logs.
+/// @pre Tasks database must be initialized with TaskRecord and TaskLogRecord schemas.
+/// @}
+void TaskPersistenceModule(void);
+
+/// @defgroup TaskPersistenceService "TaskPersistenceService"
+/// @{
+/// @brief Provides methods to save, load, and delete task records in tasks.db using SQLAlchemy models.
+/// @invariant Persistence must handle potentially missing task fields natively.
+/// @post Persist operations leave matching TaskRecord rows committed or rolled back without leaking sessions, load operations return reconstructed Task objects from stored TaskRecord rows, and delete operations remove only the addressed task rows.
+/// @pre TasksSessionLocal must provide an active SQLAlchemy session, Task inputs must expose id/plugin_id/status/params/result/logs fields, and TaskRecord plus Environment schemas must be available.
+/// @}
+void TaskPersistenceService(void);
+
+/// @defgroup _json_load_if_needed "_json_load_if_needed"
+/// @{
+/// @brief Safely load JSON strings from DB if necessary
+/// @post Returns parsed JSON object, list, string, or primitive
+/// @pre value is an arbitrary database value
+/// @}
+void _json_load_if_needed(void);
+
+/// @defgroup _parse_datetime "_parse_datetime"
+/// @{
+/// @brief Safely parse a datetime string from the database
+/// @post Returns datetime object or None
+/// @pre value is an ISO string or datetime object
+/// @}
+void _parse_datetime(void);
+
+/// @defgroup _resolve_environment_id "_resolve_environment_id"
+/// @{
+/// @brief Resolve environment id into existing environments.id value to satisfy FK constraints.
+/// @post Returns existing environments.id or None when unresolved.
+/// @pre Session is active
+/// @}
+void _resolve_environment_id(void);
+
+/// @defgroup persist_task "persist_task"
+/// @{
+/// @brief Persists or updates a single task in the database.
+/// @param task (Task) - The task object to persist.
+/// @post Task record created or updated in database.
+/// @pre isinstance(task, Task)
+/// @}
+void persist_task(void);
+
+/// @defgroup persist_tasks "persist_tasks"
+/// @{
+/// @brief Persists multiple tasks.
+/// @param tasks (List[Task]) - The list of tasks to persist.
+/// @post All tasks in list are persisted.
+/// @pre isinstance(tasks, list)
+/// @}
+void persist_tasks(void);
+
+/// @defgroup load_tasks "load_tasks"
+/// @{
+/// @brief Loads tasks from the database.
+/// @param status (Optional[TaskStatus]) - Filter by status.
+/// @post Returns list of Task objects.
+/// @pre limit is an integer.
+/// @return List[Task] - The loaded tasks.
+/// @}
+void load_tasks(void);
+
+/// @defgroup delete_tasks "delete_tasks"
+/// @{
+/// @brief Deletes specific tasks from the database.
+/// @param task_ids (List[str]) - List of task IDs to delete.
+/// @post Specified task records deleted from database.
+/// @pre task_ids is a list of strings.
+/// @}
+void delete_tasks(void);
+
+/// @defgroup TaskLogPersistenceService "TaskLogPersistenceService"
+/// @{
+/// @brief Provides methods to store, query, summarize, and delete task log rows in the task_logs table.
+/// @invariant Log entries are batch-inserted for performance.
+/// @post add_logs commits all provided log entries or rolls back on failure, query methods return TaskLog or LogStats views reconstructed from TaskLogRecord rows, and delete methods remove only log rows matching the supplied task identifiers.
+/// @pre TasksSessionLocal must provide an active SQLAlchemy session, task_id inputs must identify task log rows, LogEntry batches must expose timestamp/level/source/message/metadata fields, and LogFilter inputs must provide pagination and filter attributes used by queries.
+/// @}
+void TaskLogPersistenceService(void);
+
+/// @defgroup add_logs "add_logs"
+/// @{
+/// @brief Batch insert log entries for a task.
+/// @param logs (List[LogEntry]) - Log entries to insert.
+/// @post All logs inserted into task_logs table.
+/// @pre logs is a list of LogEntry objects.
+/// @}
+void add_logs(void);
+
+/// @defgroup get_logs "get_logs"
+/// @{
+/// @brief Query logs for a task with filtering and pagination.
+/// @param log_filter (LogFilter) - Filter parameters.
+/// @post Returns list of TaskLog objects matching filters.
+/// @pre task_id is a valid task ID.
+/// @return List[TaskLog] - Filtered log entries.
+/// @}
+void get_logs(void);
+
+/// @defgroup get_log_stats "get_log_stats"
+/// @{
+/// @brief Get statistics about logs for a task.
+/// @param task_id (str) - The task ID.
+/// @post Returns LogStats with counts by level and source.
+/// @pre task_id is a valid task ID.
+/// @return LogStats - Statistics about task logs.
+/// @}
+void get_log_stats(void);
+
+/// @defgroup get_sources "get_sources"
+/// @{
+/// @brief Get unique sources for a task's logs.
+/// @param task_id (str) - The task ID.
+/// @post Returns list of unique source strings.
+/// @pre task_id is a valid task ID.
+/// @return List[str] - Unique source names.
+/// @}
+void get_sources(void);
+
+/// @defgroup delete_logs_for_task "delete_logs_for_task"
+/// @{
+/// @brief Delete all logs for a specific task.
+/// @param task_id (str) - The task ID.
+/// @post All logs for the task are deleted.
+/// @pre task_id is a valid task ID.
+/// @}
+void delete_logs_for_task(void);
+
+/// @defgroup delete_logs_for_tasks "delete_logs_for_tasks"
+/// @{
+/// @brief Delete all logs for multiple tasks.
+/// @param task_ids (List[str]) - List of task IDs.
+/// @post All logs for the tasks are deleted.
+/// @pre task_ids is a list of task IDs.
+/// @}
+void delete_logs_for_tasks(void);
+
+/// @defgroup TaskLoggerModule "TaskLoggerModule"
+/// @{
+/// @brief Provides a dedicated logger for tasks with automatic source attribution.
+/// @invariant Each TaskLogger instance is bound to a specific task_id and default source.
+/// @}
+void TaskLoggerModule(void);
+
+/// @defgroup TaskLogger "TaskLogger"
+/// @{
+/// @brief A wrapper around TaskManager._add_log that carries task_id and source context.
+/// @invariant All log calls include the task_id and source.
+/// @}
+void TaskLogger(void);
+
+/// @defgroup with_source "with_source"
+/// @{
+/// @brief Create a sub-logger with a different default source.
+/// @param source (str) - New default source.
+/// @post Returns new TaskLogger with the same task_id but different source.
+/// @pre source is a non-empty string.
+/// @return TaskLogger - New logger instance.
+/// @}
+void with_source(void);
+
+/// @defgroup _log "_log"
+/// @{
+/// @brief Internal method to log a message at a given level.
+/// @param metadata (Optional[Dict]) - Additional structured data.
+/// @post Log entry added via add_log_fn.
+/// @pre level is a valid log level string.
+/// @}
+void _log(void);
+
+/// @defgroup debug "debug"
+/// @{
+/// @brief Log a DEBUG level message.
+/// @param metadata (Optional[Dict]) - Additional data.
+/// @post Log entry added via internally with DEBUG level.
+/// @pre message is a string.
+/// @}
+void debug(void);
+
+/// @defgroup info "info"
+/// @{
+/// @brief Log an INFO level message.
+/// @param metadata (Optional[Dict]) - Additional data.
+/// @post Log entry added internally with INFO level.
+/// @pre message is a string.
+/// @}
+void info(void);
+
+/// @defgroup warning "warning"
+/// @{
+/// @brief Log a WARNING level message.
+/// @param metadata (Optional[Dict]) - Additional data.
+/// @post Log entry added internally with WARNING level.
+/// @pre message is a string.
+/// @}
+void warning(void);
+
+/// @defgroup error "error"
+/// @{
+/// @brief Log an ERROR level message.
+/// @param metadata (Optional[Dict]) - Additional data.
+/// @post Log entry added internally with ERROR level.
+/// @pre message is a string.
+/// @}
+void error(void);
+
+/// @defgroup progress "progress"
+/// @{
+/// @brief Log a progress update with percentage.
+/// @param source (Optional[str]) - Override source.
+/// @post Log entry with progress metadata added.
+/// @pre percent is between 0 and 100.
+/// @}
+void progress(void);
+
+/// @defgroup AppTimezone "AppTimezone"
+/// @{
+/// @brief Application-level timezone utilities. Reads APP_TIMEZONE from env (default Europe/Moscow)
+/// @}
+void AppTimezone(void);
+
+/// @defgroup _get_default_tz_name "_get_default_tz_name"
+/// @{
+/// @brief Read APP_TIMEZONE from env, fall back to Europe/Moscow.
+/// @post Returns a valid IANA timezone string.
+/// @pre Environment is loaded (dotenv or os.environ).
+/// @}
+void _get_default_tz_name(void);
+
+/// @defgroup get_app_timezone "get_app_timezone"
+/// @{
+/// @brief Return cached ZoneInfo for the configured application timezone.
+/// @post Returns a ZoneInfo instance matching APP_TIMEZONE env var.
+/// @}
+void get_app_timezone(void);
+
+/// @defgroup invalidate_timezone_cache "invalidate_timezone_cache"
+/// @{
+/// @brief Reset the cached ZoneInfo so the next get_app_timezone() call re-reads from env/DB.
+/// @post _APP_TZ_CACHE is set to None; subsequent get_app_timezone() will re-resolve.
+/// @}
+void invalidate_timezone_cache(void);
+
+/// @defgroup validate_timezone "validate_timezone"
+/// @{
+/// @brief Validate that a timezone string is a known IANA timezone.
+/// @post Returns True if ZoneInfo accepts the name, False otherwise.
+/// @pre tz_name is a string.
+/// @}
+void validate_timezone(void);
+
+/// @defgroup localize "localize"
+/// @{
+/// @brief Convert a timezone-aware or naive UTC datetime to the configured app timezone.
+/// @post Returns a datetime with the app timezone attached (astimezone).
+/// @pre If dt is timezone-naive, it is assumed to be UTC.
+/// @}
+void localize(void);
+
+/// @defgroup now "now"
+/// @{
+/// @brief Get current time in the configured application timezone.
+/// @post Returns timezone-aware datetime in the app timezone.
+/// @}
+void now(void);
+
+/// @defgroup format_timezone_offset "format_timezone_offset"
+/// @{
+/// @brief Return the UTC offset string for the configured timezone (e.g. "+03:00").
+/// @post Returns string like "+03:00" or "+00:00".
+/// @}
+void format_timezone_offset(void);
+
+/// @defgroup CoreUtils "CoreUtils"
+/// @{
+/// @brief Shared utility package root.
+/// @}
+void CoreUtils(void);
+
+/// @defgroup AsyncAPIClient___init__ "AsyncAPIClient.__init__"
+/// @{
+/// @brief Initialize async API client for one environment.
+/// @post Client is ready for async request/authentication flow.
+/// @pre config contains base_url and auth payload.
+/// @}
+void AsyncAPIClient___init__(void);
+
+/// @defgroup AsyncAPIClient__normalize_base_url "AsyncAPIClient._normalize_base_url"
+/// @{
+/// @brief Normalize base URL for Superset API root construction.
+/// @post Returns canonical base URL without trailing slash and duplicate /api/v1 suffix.
+/// @}
+void AsyncAPIClient__normalize_base_url(void);
+
+/// @defgroup AsyncAPIClient__build_api_url "AsyncAPIClient._build_api_url"
+/// @{
+/// @brief Build full API URL from relative Superset endpoint.
+/// @post Returns absolute URL for upstream request.
+/// @}
+void AsyncAPIClient__build_api_url(void);
+
+/// @defgroup AsyncAPIClient__get_auth_lock "AsyncAPIClient._get_auth_lock"
+/// @{
+/// @brief Return per-cache-key async lock to serialize fresh login attempts.
+/// @post Returns stable asyncio.Lock instance.
+/// @}
+void AsyncAPIClient__get_auth_lock(void);
+
+/// @defgroup AsyncAPIClient_authenticate "AsyncAPIClient.authenticate"
+/// @{
+/// @brief Authenticate against Superset and cache access/csrf tokens.
+/// @post Client tokens are populated and reusable across requests.
+/// @}
+void AsyncAPIClient_authenticate(void);
+
+/// @defgroup AsyncAPIClient_get_headers "AsyncAPIClient.get_headers"
+/// @{
+/// @brief Return authenticated Superset headers for async requests.
+/// @post Headers include Authorization and CSRF tokens.
+/// @}
+void AsyncAPIClient_get_headers(void);
+
+/// @defgroup AsyncAPIClient__is_dashboard_endpoint "AsyncAPIClient._is_dashboard_endpoint"
+/// @{
+/// @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+/// @post Returns true only for dashboard-specific endpoints.
+/// @}
+void AsyncAPIClient__is_dashboard_endpoint(void);
+
+/// @defgroup AsyncAPIClient__handle_network_error "AsyncAPIClient._handle_network_error"
+/// @{
+/// @brief Translate generic httpx errors into NetworkError.
+/// @post Raises NetworkError with URL context.
+/// @}
+void AsyncAPIClient__handle_network_error(void);
+
+/// @defgroup AsyncAPIClient_aclose "AsyncAPIClient.aclose"
+/// @{
+/// @brief Close underlying httpx client.
+/// @post Client resources are released.
+/// @}
+void AsyncAPIClient_aclose(void);
+
+/// @defgroup DatasetMapperModule "DatasetMapperModule"
+/// @{
+/// @brief Этот модуль отвечает за обновление метаданных (verbose_name) в датасетах Superset,
+/// @}
+void DatasetMapperModule(void);
+
+/// @defgroup DatasetMapper "DatasetMapper"
+/// @{
+/// @brief Класс для маппинга и обновления verbose_name в датасетах Superset.
+/// @}
+void DatasetMapper(void);
+
+/// @defgroup get_sqllab_mappings "get_sqllab_mappings"
+/// @{
+/// @brief Извлекает маппинги column_name -> verbose_name через SQL Lab Superset.
+/// @post Возвращается словарь column_name -> verbose_name из результатов SQL-запроса.
+/// @pre dataset_id должен существовать в Superset.
+/// @}
+void get_sqllab_mappings(void);
+
+/// @defgroup load_excel_mappings "load_excel_mappings"
+/// @{
+/// @brief Загружает маппинги column_name -> verbose_name из XLSX файла.
+/// @param file_path (str) - Путь к XLSX файлу.
+/// @post Возвращается словарь с маппингами из файла.
+/// @pre file_path должен указывать на существующий XLSX файл.
+/// @return Dict[str, str] - Словарь с маппингами.
+/// @}
+void load_excel_mappings(void);
+
+/// @defgroup run_mapping "run_mapping"
+/// @{
+/// @brief Основная функция для выполнения маппинга и обновления verbose_name датасета в Superset.
+/// @param excel_path (Optional[str]) - Путь к XLSX файлу.
+/// @post Если найдены изменения, датасет в Superset обновлен через API.
+/// @pre dataset_id должен быть существующим ID в Superset.
+/// @}
+void run_mapping(void);
+
+/// @defgroup FileIO "FileIO"
+/// @{
+/// @brief Предоставляет набор утилит для управления файловыми операциями, включая работу с временными файлами, архивами ZIP, файлами YAML и очистку директорий.
+/// @}
+void FileIO(void);
+
+/// @defgroup InvalidZipFormatError "InvalidZipFormatError"
+/// @{
+/// @brief Exception raised when a file is not a valid ZIP archive.
+/// @}
+void InvalidZipFormatError(void);
+
+/// @defgroup create_temp_file "create_temp_file"
+/// @{
+/// @brief Контекстный менеджер для создания временного файла или директории с гарантированным удалением.
+/// @post Временный ресурс создан и путь к нему возвращен; ресурс удален после выхода из контекста.
+/// @pre suffix должен быть строкой, определяющей тип ресурса.
+/// @}
+void create_temp_file(void);
+
+/// @defgroup remove_empty_directories "remove_empty_directories"
+/// @{
+/// @brief Рекурсивно удаляет все пустые поддиректории, начиная с указанного пути.
+/// @post Все пустые поддиректории удалены, возвращено их количество.
+/// @pre root_dir должен быть путем к существующей директории.
+/// @}
+void remove_empty_directories(void);
+
+/// @defgroup read_dashboard_from_disk "read_dashboard_from_disk"
+/// @{
+/// @brief Читает бинарное содержимое файла с диска.
+/// @post Возвращает байты содержимого и имя файла.
+/// @pre file_path должен указывать на существующий файл.
+/// @}
+void read_dashboard_from_disk(void);
+
+/// @defgroup calculate_crc32 "calculate_crc32"
+/// @{
+/// @brief Вычисляет контрольную сумму CRC32 для файла.
+/// @post Возвращает 8-значную hex-строку CRC32.
+/// @pre file_path должен быть объектом Path к существующему файлу.
+/// @}
+void calculate_crc32(void);
+
+/// @defgroup RetentionPolicy "RetentionPolicy"
+/// @{
+/// @brief Определяет политику хранения для архивов (ежедневные, еженедельные, ежемесячные).
+/// @}
+void RetentionPolicy(void);
+
+/// @defgroup archive_exports "archive_exports"
+/// @{
+/// @brief Управляет архивом экспортированных файлов, применяя политику хранения и дедупликацию.
+/// @post Старые или дублирующиеся архивы удалены согласно политике.
+/// @pre output_dir должен быть путем к существующей директории.
+/// @}
+void archive_exports(void);
+
+/// @defgroup apply_retention_policy "apply_retention_policy"
+/// @{
+/// @brief (Helper) Применяет политику хранения к списку файлов, возвращая те, что нужно сохранить.
+/// @post Returns a set of files to keep.
+/// @pre files_with_dates is a list of (Path, date) tuples.
+/// @}
+void apply_retention_policy(void);
+
+/// @defgroup save_and_unpack_dashboard "save_and_unpack_dashboard"
+/// @{
+/// @brief Сохраняет бинарное содержимое ZIP-архива на диск и опционально распаковывает его.
+/// @post ZIP-файл сохранен, и если unpack=True, он распакован в output_dir.
+/// @pre zip_content должен быть байтами валидного ZIP-архива.
+/// @}
+void save_and_unpack_dashboard(void);
+
+/// @defgroup update_yamls "update_yamls"
+/// @{
+/// @brief Обновляет конфигурации в YAML-файлах, заменяя значения или применяя regex.
+/// @post Все YAML файлы в директории обновлены согласно переданным параметрам.
+/// @pre path должен быть существующей директорией.
+/// @}
+void update_yamls(void);
+
+/// @defgroup _update_yaml_file "_update_yaml_file"
+/// @{
+/// @brief (Helper) Обновляет один YAML файл.
+/// @post Файл обновлен согласно переданным конфигурациям или регулярному выражению.
+/// @pre file_path должен быть объектом Path к существующему YAML файлу.
+/// @}
+void _update_yaml_file(void);
+
+/// @defgroup replacer "replacer"
+/// @{
+/// @brief Функция замены, сохраняющая кавычки если они были.
+/// @post Возвращает строку с новым значением, сохраняя префикс и кавычки.
+/// @pre match должен быть объектом совпадения регулярного выражения.
+/// @}
+void replacer(void);
+
+/// @defgroup create_dashboard_export "create_dashboard_export"
+/// @{
+/// @brief Создает ZIP-архив из указанных исходных путей.
+/// @post ZIP-архив создан по пути zip_path.
+/// @pre source_paths должен содержать существующие пути.
+/// @}
+void create_dashboard_export(void);
+
+/// @defgroup sanitize_filename "sanitize_filename"
+/// @{
+/// @brief Очищает строку от символов, недопустимых в именах файлов.
+/// @post Возвращает строку без спецсимволов.
+/// @pre filename должен быть строкой.
+/// @}
+void sanitize_filename(void);
+
+/// @defgroup get_filename_from_headers "get_filename_from_headers"
+/// @{
+/// @brief Извлекает имя файла из HTTP заголовка 'Content-Disposition'.
+/// @post Возвращает имя файла или None, если заголовок отсутствует.
+/// @pre headers должен быть словарем заголовков.
+/// @}
+void get_filename_from_headers(void);
+
+/// @defgroup consolidate_archive_folders "consolidate_archive_folders"
+/// @{
+/// @brief Консолидирует директории архивов на основе общего слага в имени.
+/// @post Директории с одинаковым префиксом объединены в одну.
+/// @pre root_directory должен быть объектом Path к существующей директории.
+/// @}
+void consolidate_archive_folders(void);
+
+/// @defgroup FuzzyMatching "FuzzyMatching"
+/// @{
+/// @brief Provides utility functions for fuzzy matching database names.
+/// @invariant Confidence scores are returned as floats between 0.0 and 1.0.
+/// @}
+void FuzzyMatching(void);
+
+/// @defgroup suggest_mappings "suggest_mappings"
+/// @{
+/// @brief Suggests mappings between source and target databases using fuzzy matching.
+/// @post Returns a list of suggested mappings with confidence scores.
+/// @pre source_databases and target_databases are lists of dictionaries with 'uuid' and 'database_name'.
+/// @}
+void suggest_mappings(void);
+
+/// @defgroup NetworkModule "NetworkModule"
+/// @{
+/// @brief Инкапсулирует низкоуровневую HTTP-логику для взаимодействия с Superset API, включая аутентификацию, управление сессией, retry-логику и обработку ошибок.
+/// @}
+void NetworkModule(void);
+
+/// @defgroup SupersetAPIError "SupersetAPIError"
+/// @{
+/// @brief Base exception for all Superset API related errors.
+/// @}
+void SupersetAPIError(void);
+
+/// @defgroup AuthenticationError "AuthenticationError"
+/// @{
+/// @brief Exception raised when authentication fails.
+/// @}
+void AuthenticationError(void);
+
+/// @defgroup PermissionDeniedError "PermissionDeniedError"
+/// @{
+/// @brief Exception raised when access is denied.
+/// @}
+void PermissionDeniedError(void);
+
+/// @defgroup DashboardNotFoundError "DashboardNotFoundError"
+/// @{
+/// @brief Exception raised when a dashboard cannot be found.
+/// @}
+void DashboardNotFoundError(void);
+
+/// @defgroup NetworkError "NetworkError"
+/// @{
+/// @brief Exception raised when a network level error occurs.
+/// @}
+void NetworkError(void);
+
+/// @defgroup NetworkError___init__ "NetworkError.__init__"
+/// @{
+/// @brief Initializes the network error.
+/// @post NetworkError is initialized.
+/// @pre message is a string.
+/// @}
+void NetworkError___init__(void);
+
+/// @defgroup SupersetAuthCache "SupersetAuthCache"
+/// @{
+/// @brief Process-local cache for Superset access/csrf tokens keyed by environment credentials.
+/// @post Cached entries expire automatically by TTL and can be reused across requests.
+/// @pre base_url and username are stable strings.
+/// @}
+void SupersetAuthCache(void);
+
+/// @defgroup SupersetAuthCache_get "SupersetAuthCache.get"
+/// @{
+/// @}
+void SupersetAuthCache_get(void);
+
+/// @defgroup SupersetAuthCache_set "SupersetAuthCache.set"
+/// @{
+/// @}
+void SupersetAuthCache_set(void);
+
+/// @defgroup APIClient "APIClient"
+/// @{
+/// @brief Synchronous Superset API client with process-local auth token caching.
+/// @}
+void APIClient(void);
+
+/// @defgroup APIClient___init__ "APIClient.__init__"
+/// @{
+/// @brief Инициализирует API клиент с конфигурацией, сессией и логгером.
+/// @param timeout (int) - Таймаут запросов.
+/// @post APIClient instance is initialized with a session.
+/// @pre config must contain 'base_url' and 'auth'.
+/// @}
+void APIClient___init__(void);
+
+/// @defgroup _init_session "_init_session"
+/// @{
+/// @brief Создает и настраивает `requests.Session` с retry-логикой.
+/// @post Returns a configured requests.Session instance.
+/// @pre self.request_settings must be initialized.
+/// @return requests.Session - Настроенная сессия.
+/// @}
+void _init_session(void);
+
+/// @defgroup _normalize_base_url "_normalize_base_url"
+/// @{
+/// @brief Normalize Superset environment URL to base host/path without trailing slash and /api/v1 suffix.
+/// @}
+void _normalize_base_url(void);
+
+/// @defgroup _build_api_url "_build_api_url"
+/// @{
+/// @brief Build absolute Superset API URL for endpoint using canonical /api/v1 base.
+/// @post Returns full URL without accidental duplicate slashes.
+/// @pre endpoint is relative path or absolute URL.
+/// @return str
+/// @}
+void _build_api_url(void);
+
+/// @defgroup APIClient_authenticate "APIClient.authenticate"
+/// @{
+/// @brief Выполняет аутентификацию в Superset API и получает access и CSRF токены.
+/// @post `self._tokens` заполнен, `self._authenticated` установлен в `True`.
+/// @pre self.auth and self.base_url must be valid.
+/// @return Dict[str, str] - Словарь с токенами.
+/// @}
+void APIClient_authenticate(void);
+
+/// @defgroup headers "headers"
+/// @{
+/// @brief Возвращает HTTP-заголовки для аутентифицированных запросов.
+/// @post Returns headers including auth tokens.
+/// @pre APIClient is initialized and authenticated or can be authenticated.
+/// @}
+void headers(void);
+
+/// @defgroup request "request"
+/// @{
+/// @brief Выполняет универсальный HTTP-запрос к API.
+/// @param raw_response (bool) - Возвращать ли сырой ответ.
+/// @post Returns response content or raw Response object.
+/// @pre method and endpoint must be strings.
+/// @return `requests.Response` если `raw_response=True`, иначе `dict`.
+/// @}
+void request(void);
+
+/// @defgroup _handle_http_error "_handle_http_error"
+/// @{
+/// @brief (Helper) Преобразует HTTP ошибки в кастомные исключения.
+/// @param endpoint (str) - Эндпоинт.
+/// @post Raises a specific SupersetAPIError or subclass.
+/// @pre e must be a valid HTTPError with a response.
+/// @}
+void _handle_http_error(void);
+
+/// @defgroup _is_dashboard_endpoint "_is_dashboard_endpoint"
+/// @{
+/// @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+/// @post Returns true only for dashboard-specific endpoints.
+/// @pre endpoint may be relative or absolute.
+/// @}
+void _is_dashboard_endpoint(void);
+
+/// @defgroup _handle_network_error "_handle_network_error"
+/// @{
+/// @brief (Helper) Преобразует сетевые ошибки в `NetworkError`.
+/// @param url (str) - URL.
+/// @post Raises a NetworkError.
+/// @pre e must be a RequestException.
+/// @}
+void _handle_network_error(void);
+
+/// @defgroup upload_file "upload_file"
+/// @{
+/// @brief Загружает файл на сервер через multipart/form-data.
+/// @param timeout (Optional[int]) - Таймаут.
+/// @post File is uploaded and response returned.
+/// @pre file_info must contain 'file_obj' and 'file_name'.
+/// @return Ответ API в виде словаря.
+/// @}
+void upload_file(void);
+
+/// @defgroup _perform_upload "_perform_upload"
+/// @{
+/// @brief (Helper) Выполняет POST запрос с файлом.
+/// @param timeout (Optional[int]) - Таймаут.
+/// @post POST request is performed and JSON response returned.
+/// @pre url, files, and headers must be provided.
+/// @return Dict - Ответ.
+/// @}
+void _perform_upload(void);
+
+/// @defgroup fetch_paginated_count "fetch_paginated_count"
+/// @{
+/// @brief Получает общее количество элементов для пагинации.
+/// @param count_field (str) - Поле с количеством.
+/// @post Returns total count of items.
+/// @pre query_params must be a dictionary.
+/// @return int - Количество.
+/// @}
+void fetch_paginated_count(void);
+
+/// @defgroup fetch_paginated_data "fetch_paginated_data"
+/// @{
+/// @brief Автоматически собирает данные со всех страниц пагинированного эндпоинта.
+/// @param pagination_options (Dict[str, Any]) - Опции пагинации.
+/// @post Returns all items across all pages.
+/// @pre pagination_options must contain 'base_query', 'results_field'. 'total_count' is optional.
+/// @return List[Any] - Список данных.
+/// @}
+void fetch_paginated_data(void);
+
+/// @defgroup SupersetCompilationAdapter "SupersetCompilationAdapter"
+/// @{
+/// @brief Interact with Superset preview compilation and SQL Lab execution endpoints using the current approved execution context.
+/// @invariant The adapter never fabricates compiled SQL locally; preview truth is delegated to Superset only.
+/// @post preview and launch calls return Superset-originated artifacts or explicit errors.
+/// @pre effective template params and dataset execution reference are available.
+/// @}
+void SupersetCompilationAdapter(void);
+
+/// @defgroup SupersetCompilationAdapter_imports "SupersetCompilationAdapter.imports"
+/// @{
+/// @}
+void SupersetCompilationAdapter_imports(void);
+
+/// @defgroup PreviewCompilationPayload "PreviewCompilationPayload"
+/// @{
+/// @brief Typed preview payload for Superset-side compilation.
+/// @}
+void PreviewCompilationPayload(void);
+
+/// @defgroup SqlLabLaunchPayload "SqlLabLaunchPayload"
+/// @{
+/// @brief Typed SQL Lab payload for audited launch handoff.
+/// @}
+void SqlLabLaunchPayload(void);
+
+/// @defgroup SupersetCompilationAdapter___init__ "SupersetCompilationAdapter.__init__"
+/// @{
+/// @brief Bind adapter to one Superset environment and client instance.
+/// @}
+void SupersetCompilationAdapter___init__(void);
+
+/// @defgroup SupersetCompilationAdapter__supports_client_method "SupersetCompilationAdapter._supports_client_method"
+/// @{
+/// @brief Detect explicitly implemented client capabilities without treating loose mocks as real methods.
+/// @}
+void SupersetCompilationAdapter__supports_client_method(void);
+
+/// @defgroup SupersetCompilationAdapter_compile_preview "SupersetCompilationAdapter.compile_preview"
+/// @{
+/// @brief Request Superset-side compiled SQL preview for the current effective inputs.
+/// @post returns a ready or failed preview artifact backed only by Superset-originated SQL or diagnostics.
+/// @pre dataset_id and effective inputs are available for the current session.
+/// @}
+void SupersetCompilationAdapter_compile_preview(void);
+
+/// @defgroup SupersetCompilationAdapter_mark_preview_stale "SupersetCompilationAdapter.mark_preview_stale"
+/// @{
+/// @brief Invalidate previous preview after mapping or value changes.
+/// @post preview status becomes stale without fabricating a replacement artifact.
+/// @pre preview is a persisted preview artifact or current in-memory snapshot.
+/// @}
+void SupersetCompilationAdapter_mark_preview_stale(void);
+
+/// @defgroup SupersetCompilationAdapter_create_sql_lab_session "SupersetCompilationAdapter.create_sql_lab_session"
+/// @{
+/// @brief Create the canonical audited execution session after all launch gates pass.
+/// @post returns one canonical SQL Lab session reference from Superset.
+/// @pre compiled_sql is Superset-originated and launch gates are already satisfied.
+/// @}
+void SupersetCompilationAdapter_create_sql_lab_session(void);
+
+/// @defgroup SupersetCompilationAdapter__request_superset_preview "SupersetCompilationAdapter._request_superset_preview"
+/// @{
+/// @brief Request preview compilation through explicit client support backed by real Superset endpoints only.
+/// @post returns one normalized upstream compilation response including the chosen strategy metadata.
+/// @pre payload contains a valid dataset identifier and deterministic execution inputs for one preview attempt.
+/// @}
+void SupersetCompilationAdapter__request_superset_preview(void);
+
+/// @defgroup SupersetCompilationAdapter__request_sql_lab_session "SupersetCompilationAdapter._request_sql_lab_session"
+/// @{
+/// @brief Probe supported SQL Lab execution surfaces and return the first successful response.
+/// @post returns the first successful SQL Lab execution response from Superset.
+/// @pre payload carries non-empty Superset-originated SQL and a preview identifier for the current launch.
+/// @}
+void SupersetCompilationAdapter__request_sql_lab_session(void);
+
+/// @defgroup SupersetCompilationAdapter__normalize_preview_response "SupersetCompilationAdapter._normalize_preview_response"
+/// @{
+/// @brief Normalize candidate Superset preview responses into one compiled-sql structure.
+/// @}
+void SupersetCompilationAdapter__normalize_preview_response(void);
+
+/// @defgroup SupersetCompilationAdapter__dump_json "SupersetCompilationAdapter._dump_json"
+/// @{
+/// @brief Serialize Superset request payload deterministically for network transport.
+/// @}
+void SupersetCompilationAdapter__dump_json(void);
+
+/// @defgroup SupersetContextExtractorPackage "SupersetContextExtractorPackage"
+/// @{
+/// @brief Recover dataset and dashboard context from Superset links while preserving explicit partial-recovery markers.
+/// @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+/// @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+/// @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+/// @}
+void SupersetContextExtractorPackage(void);
+
+/// @defgroup SupersetContextExtractor "SupersetContextExtractor"
+/// @{
+/// @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+/// @post extractor instance is ready to parse links against one Superset environment.
+/// @pre constructor receives a configured environment with a usable Superset base URL.
+/// @}
+void SupersetContextExtractor(void);
+
+/// @defgroup SupersetContextExtractorBase "SupersetContextExtractorBase"
+/// @{
+/// @brief Base class and helpers for recovering dataset/dashboard context from Superset links with explicit partial-recovery markers.
+/// @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+/// @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+/// @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+/// @}
+void SupersetContextExtractorBase(void);
+
+/// @defgroup _base_imports "_base_imports"
+/// @{
+/// @}
+void _base_imports(void);
+
+/// @defgroup SupersetParsedContext "SupersetParsedContext"
+/// @{
+/// @brief Normalized output of Superset link parsing for session intake and recovery.
+/// @}
+void SupersetParsedContext(void);
+
+/// @defgroup SupersetContextExtractorBase___init__ "SupersetContextExtractorBase.__init__"
+/// @{
+/// @brief Bind extractor to one Superset environment and client instance.
+/// @}
+void SupersetContextExtractorBase___init__(void);
+
+/// @defgroup SupersetContextExtractorBase_build_recovery_summary "SupersetContextExtractorBase.build_recovery_summary"
+/// @{
+/// @brief Summarize recovered, partial, and unresolved context for session state and UX.
+/// @}
+void SupersetContextExtractorBase_build_recovery_summary(void);
+
+/// @defgroup SupersetContextExtractorBase__extract_numeric_identifier "SupersetContextExtractorBase._extract_numeric_identifier"
+/// @{
+/// @brief Extract a numeric identifier from a REST-like Superset URL path.
+/// @}
+void SupersetContextExtractorBase__extract_numeric_identifier(void);
+
+/// @defgroup SupersetContextExtractorBase__extract_dashboard_reference "SupersetContextExtractorBase._extract_dashboard_reference"
+/// @{
+/// @brief Extract a dashboard id-or-slug reference from a Superset URL path.
+/// @}
+void SupersetContextExtractorBase__extract_dashboard_reference(void);
+
+/// @defgroup SupersetContextExtractorBase__extract_dashboard_permalink_key "SupersetContextExtractorBase._extract_dashboard_permalink_key"
+/// @{
+/// @brief Extract a dashboard permalink key from a Superset URL path.
+/// @}
+void SupersetContextExtractorBase__extract_dashboard_permalink_key(void);
+
+/// @defgroup SupersetContextExtractorBase__extract_dashboard_id_from_state "SupersetContextExtractorBase._extract_dashboard_id_from_state"
+/// @{
+/// @brief Extract a dashboard identifier from returned permalink state when present.
+/// @}
+void SupersetContextExtractorBase__extract_dashboard_id_from_state(void);
+
+/// @defgroup SupersetContextExtractorBase__extract_chart_id_from_state "SupersetContextExtractorBase._extract_chart_id_from_state"
+/// @{
+/// @brief Extract a chart identifier from returned permalink state when dashboard id is absent.
+/// @}
+void SupersetContextExtractorBase__extract_chart_id_from_state(void);
+
+/// @defgroup SupersetContextExtractorBase__search_nested_numeric_key "SupersetContextExtractorBase._search_nested_numeric_key"
+/// @{
+/// @brief Recursively search nested dict/list payloads for the first numeric value under a candidate key set.
+/// @}
+void SupersetContextExtractorBase__search_nested_numeric_key(void);
+
+/// @defgroup SupersetContextExtractorBase__decode_query_state "SupersetContextExtractorBase._decode_query_state"
+/// @{
+/// @brief Decode query-string structures used by Superset URL state transport.
+/// @}
+void SupersetContextExtractorBase__decode_query_state(void);
+
+/// @defgroup SupersetContextFiltersExtractMixin "SupersetContextFiltersExtractMixin"
+/// @{
+/// @brief Extract normalized imported filters from decoded Superset query state (native_filters, dataMask, native_filter_state, form_data).
+/// @}
+void SupersetContextFiltersExtractMixin(void);
+
+/// @defgroup _filters_imports "_filters_imports"
+/// @{
+/// @}
+void _filters_imports(void);
+
+/// @defgroup SupersetContextFiltersExtractMixin__extract_imported_filters "SupersetContextFiltersExtractMixin._extract_imported_filters"
+/// @{
+/// @brief Normalize imported filters from decoded query state without fabricating missing values.
+/// @}
+void SupersetContextFiltersExtractMixin__extract_imported_filters(void);
+
+/// @defgroup SupersetContextParsingMixin "SupersetContextParsingMixin"
+/// @{
+/// @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+/// @}
+void SupersetContextParsingMixin(void);
+
+/// @defgroup _parsing_imports "_parsing_imports"
+/// @{
+/// @}
+void _parsing_imports(void);
+
+/// @defgroup SupersetContextParsingMixin_parse_superset_link "SupersetContextParsingMixin.parse_superset_link"
+/// @{
+/// @brief Extract candidate identifiers and query state from supported Superset URLs.
+/// @post returns resolved dataset/dashboard context, preserving explicit partial-recovery state if some identifiers cannot be confirmed.
+/// @pre link is a non-empty Superset URL compatible with the configured environment.
+/// @}
+void SupersetContextParsingMixin_parse_superset_link(void);
+
+/// @defgroup SupersetContextParsingMixin__recover_dataset_binding_from_dashboard "SupersetContextParsingMixin._recover_dataset_binding_from_dashboard"
+/// @{
+/// @brief Recover a dataset binding from resolved dashboard context while preserving explicit unresolved markers.
+/// @}
+void SupersetContextParsingMixin__recover_dataset_binding_from_dashboard(void);
+
+/// @defgroup SupersetContextExtractorPII "SupersetContextExtractorPII"
+/// @{
+/// @brief PII redaction helpers for assistant-facing dataset-review context — mask emails, UUIDs, long digit strings, and mixed identifiers.
+/// @}
+void SupersetContextExtractorPII(void);
+
+/// @defgroup _pii_imports "_pii_imports"
+/// @{
+/// @}
+void _pii_imports(void);
+
+/// @defgroup mask_pii_value "mask_pii_value"
+/// @{
+/// @brief Redact likely sensitive identifiers while preserving structural hints for assistant-facing dataset-review context.
+/// @}
+void mask_pii_value(void);
+
+/// @defgroup sanitize_imported_filter_for_assistant "sanitize_imported_filter_for_assistant"
+/// @{
+/// @brief Build assistant-safe imported-filter payload with raw-value redaction metadata when sensitive tokens are detected.
+/// @}
+void sanitize_imported_filter_for_assistant(void);
+
+/// @defgroup _mask_sensitive_text "_mask_sensitive_text"
+/// @{
+/// @brief Redact likely PII substrings from one string while preserving non-sensitive delimiters and token shape.
+/// @}
+void _mask_sensitive_text(void);
+
+/// @defgroup SupersetContextRecoveryMixin "SupersetContextRecoveryMixin"
+/// @{
+/// @brief Recover imported filters from Superset parsed context and dashboard metadata.
+/// @}
+void SupersetContextRecoveryMixin(void);
+
+/// @defgroup _recovery_imports "_recovery_imports"
+/// @{
+/// @}
+void _recovery_imports(void);
+
+/// @defgroup SupersetContextRecoveryMixin_recover_imported_filters "SupersetContextRecoveryMixin.recover_imported_filters"
+/// @{
+/// @brief Build imported filter entries from URL state and Superset-side saved context.
+/// @post returns explicit recovered and partial filter entries with preserved provenance and confirmation requirements.
+/// @pre parsed_context comes from a successful Superset link parse for one environment.
+/// @}
+void SupersetContextRecoveryMixin_recover_imported_filters(void);
+
+/// @defgroup SupersetContextRecoveryMixin__normalize_imported_filter_payload "SupersetContextRecoveryMixin._normalize_imported_filter_payload"
+/// @{
+/// @brief Normalize one imported-filter payload with explicit provenance and confirmation state.
+/// @}
+void SupersetContextRecoveryMixin__normalize_imported_filter_payload(void);
+
+/// @defgroup SupersetContextTemplatesMixin "SupersetContextTemplatesMixin"
+/// @{
+/// @brief Deterministically detect runtime variables and Jinja references from dataset query-bearing fields without execution.
+/// @}
+void SupersetContextTemplatesMixin(void);
+
+/// @defgroup _templates_imports "_templates_imports"
+/// @{
+/// @}
+void _templates_imports(void);
+
+/// @defgroup SupersetContextTemplatesMixin_discover_template_variables "SupersetContextTemplatesMixin.discover_template_variables"
+/// @{
+/// @brief Detect runtime variables and Jinja references from dataset query-bearing fields.
+/// @post returns deduplicated explicit variable records without executing Jinja or fabricating runtime values.
+/// @pre dataset_payload is a Superset dataset-detail style payload with query-bearing fields when available.
+/// @}
+void SupersetContextTemplatesMixin_discover_template_variables(void);
+
+/// @defgroup SupersetContextTemplatesMixin__collect_query_bearing_expressions "SupersetContextTemplatesMixin._collect_query_bearing_expressions"
+/// @{
+/// @brief Collect SQL and expression-bearing dataset fields for deterministic template-variable discovery.
+/// @}
+void SupersetContextTemplatesMixin__collect_query_bearing_expressions(void);
+
+/// @defgroup SupersetContextTemplatesMixin__append_template_variable "SupersetContextTemplatesMixin._append_template_variable"
+/// @{
+/// @brief Append one deduplicated template-variable descriptor.
+/// @}
+void SupersetContextTemplatesMixin__append_template_variable(void);
+
+/// @defgroup SupersetContextTemplatesMixin__extract_primary_jinja_identifier "SupersetContextTemplatesMixin._extract_primary_jinja_identifier"
+/// @{
+/// @brief Extract a deterministic primary identifier from a Jinja expression without executing it.
+/// @}
+void SupersetContextTemplatesMixin__extract_primary_jinja_identifier(void);
+
+/// @defgroup SupersetContextTemplatesMixin__normalize_default_literal "SupersetContextTemplatesMixin._normalize_default_literal"
+/// @{
+/// @brief Normalize literal default fragments from template helper calls into JSON-safe values.
+/// @}
+void SupersetContextTemplatesMixin__normalize_default_literal(void);
+
+/// @defgroup WsLogHandlerModule "WsLogHandlerModule"
+/// @{
+/// @brief WebSocket log handler module providing LogEntry DTO and WebSocketLogHandler for buffered log streaming.
+/// @}
+void WsLogHandlerModule(void);
+
+/// @defgroup WebSocketLogHandler "WebSocketLogHandler"
+/// @{
+/// @brief Custom logging handler that captures log records into a fixed-capacity buffer for WebSocket streaming.
+/// @}
+void WebSocketLogHandler(void);
+
+/// @defgroup WebSocketLogHandler___init__ "WebSocketLogHandler.__init__"
+/// @{
+/// @}
+void WebSocketLogHandler___init__(void);
+
+/// @defgroup WebSocketLogHandler_emit "WebSocketLogHandler.emit"
+/// @{
+/// @brief Captures a log record, formats it, and stores it in the buffer as a LogEntry.
+/// @}
+void WebSocketLogHandler_emit(void);
+
+/// @defgroup WebSocketLogHandler_get_recent_logs "WebSocketLogHandler.get_recent_logs"
+/// @{
+/// @brief Returns a list of recent log entries from the buffer.
+/// @}
+void WebSocketLogHandler_get_recent_logs(void);
+
+/// @defgroup AppDependencies "AppDependencies"
+/// @{
+/// @brief Provides shared instances to app and routers.
+/// @}
+void AppDependencies(void);
+
+/// @defgroup get_config_manager "get_config_manager"
+/// @{
+/// @brief Dependency injector for ConfigManager.
+/// @post Returns shared ConfigManager instance.
+/// @pre Global config_manager must be initialized.
+/// @}
+void get_config_manager(void);
+
+/// @defgroup get_plugin_loader "get_plugin_loader"
+/// @{
+/// @brief Dependency injector for PluginLoader.
+/// @post Returns shared PluginLoader instance.
+/// @pre Global plugin_loader must be initialized.
+/// @}
+void get_plugin_loader(void);
+
+/// @defgroup get_task_manager "get_task_manager"
+/// @{
+/// @brief Dependency injector for TaskManager.
+/// @post Returns shared TaskManager instance.
+/// @pre Global task_manager must be initialized.
+/// @}
+void get_task_manager(void);
+
+/// @defgroup get_scheduler_service "get_scheduler_service"
+/// @{
+/// @brief Dependency injector for SchedulerService.
+/// @post Returns shared SchedulerService instance.
+/// @pre Global scheduler_service must be initialized.
+/// @}
+void get_scheduler_service(void);
+
+/// @defgroup get_resource_service "get_resource_service"
+/// @{
+/// @brief Dependency injector for ResourceService.
+/// @post Returns shared ResourceService instance.
+/// @pre Global resource_service must be initialized.
+/// @}
+void get_resource_service(void);
+
+/// @defgroup get_mapping_service "get_mapping_service"
+/// @{
+/// @brief Dependency injector for MappingService.
+/// @post Returns new MappingService instance.
+/// @pre Global config_manager must be initialized.
+/// @}
+void get_mapping_service(void);
+
+/// @defgroup get_clean_release_repository "get_clean_release_repository"
+/// @{
+/// @brief Legacy compatibility shim for CleanReleaseRepository.
+/// @post Returns a shared CleanReleaseRepository instance.
+/// @}
+void get_clean_release_repository(void);
+
+/// @defgroup get_clean_release_facade "get_clean_release_facade"
+/// @{
+/// @brief Dependency injector for CleanReleaseFacade.
+/// @post Returns a facade instance with a fresh DB session.
+/// @}
+void get_clean_release_facade(void);
+
+/// @defgroup APIKeyPrincipal "APIKeyPrincipal"
+/// @{
+/// @brief Dataclass representing an authenticated API key principal for service-to-service auth.
+/// @}
+void APIKeyPrincipal(void);
+
+/// @defgroup require_api_key_or_jwt "require_api_key_or_jwt"
+/// @{
+/// @brief Factory: creates a dependency that accepts either a valid API key (with permission check)
+/// @}
+void require_api_key_or_jwt(void);
+
+/// @defgroup check_api_key_environment_scope "check_api_key_environment_scope"
+/// @{
+/// @brief Check the request's API key environment scope against a target env_id. Raises 400 if mismatch.
+/// @}
+void check_api_key_environment_scope(void);
+
+/// @defgroup get_api_key_principal "get_api_key_principal"
+/// @{
+/// @brief FastAPI dependency that reads X-API-Key header and returns APIKeyPrincipal or None.
+/// @post If valid key: returns APIKeyPrincipal; if no header: returns None; if invalid: raises 401.
+/// @pre X-API-Key header may be present in the request.
+/// @}
+void get_api_key_principal(void);
+
+/// @defgroup oauth2_scheme "oauth2_scheme"
+/// @{
+/// @brief OAuth2 password bearer scheme for token extraction (raises 401 on missing token).
+/// @}
+void oauth2_scheme(void);
+
+/// @defgroup oauth2_scheme_optional "oauth2_scheme_optional"
+/// @{
+/// @brief Optional OAuth2 scheme — returns None instead of raising 401 when no token.
+/// @}
+void oauth2_scheme_optional(void);
+
+/// @defgroup get_current_user "get_current_user"
+/// @{
+/// @brief Dependency for retrieving currently authenticated user from a JWT.
+/// @post Returns User object if token is valid.
+/// @pre JWT token provided in Authorization header.
+/// @}
+void get_current_user(void);
+
+/// @defgroup has_permission "has_permission"
+/// @{
+/// @brief Dependency for checking if the current user has a specific permission.
+/// @post Returns True if user has permission.
+/// @pre User is authenticated.
+/// @}
+void has_permission(void);
+
+/// @defgroup ModelsPackage "ModelsPackage"
+/// @{
+/// @brief Domain model package root.
+/// @}
+void ModelsPackage(void);
+
+/// @defgroup TestCleanReleaseModels "TestCleanReleaseModels"
+/// @{
+/// @brief Contract testing for Clean Release models
+/// @}
+void TestCleanReleaseModels(void);
+
+/// @defgroup test_release_candidate_valid "test_release_candidate_valid"
+/// @{
+/// @brief Verify that a valid release candidate can be instantiated.
+/// @}
+void test_release_candidate_valid(void);
+
+/// @defgroup test_release_candidate_empty_id "test_release_candidate_empty_id"
+/// @{
+/// @brief Verify that a release candidate with an empty ID is rejected.
+/// @}
+void test_release_candidate_empty_id(void);
+
+/// @defgroup test_enterprise_policy_valid "test_enterprise_policy_valid"
+/// @{
+/// @brief Verify that a valid enterprise policy is accepted.
+/// @}
+void test_enterprise_policy_valid(void);
+
+/// @defgroup test_enterprise_policy_missing_prohibited "test_enterprise_policy_missing_prohibited"
+/// @{
+/// @brief Verify that an enterprise policy without prohibited categories is rejected.
+/// @}
+void test_enterprise_policy_missing_prohibited(void);
+
+/// @defgroup test_enterprise_policy_external_allowed "test_enterprise_policy_external_allowed"
+/// @{
+/// @brief Verify that an enterprise policy allowing external sources is rejected.
+/// @}
+void test_enterprise_policy_external_allowed(void);
+
+/// @defgroup test_manifest_count_mismatch "test_manifest_count_mismatch"
+/// @{
+/// @brief Verify that a manifest with count mismatches is rejected.
+/// @}
+void test_manifest_count_mismatch(void);
+
+/// @defgroup test_compliant_run_validation "test_compliant_run_validation"
+/// @{
+/// @brief Verify compliant run validation logic and mandatory stage checks.
+/// @}
+void test_compliant_run_validation(void);
+
+/// @defgroup test_report_validation "test_report_validation"
+/// @{
+/// @brief Verify compliance report validation based on status and violation counts.
+/// @}
+void test_report_validation(void);
+
+/// @defgroup test_models "test_models"
+/// @{
+/// @brief Unit tests for data models
+/// @}
+void test_models(void);
+
+/// @defgroup test_environment_model "test_environment_model"
+/// @{
+/// @brief Tests that Environment model correctly stores values.
+/// @post Values are verified.
+/// @pre Environment class is available.
+/// @}
+void test_environment_model(void);
+
+/// @defgroup test_report_models "test_report_models"
+/// @{
+/// @brief Unit tests for report Pydantic models and their validators
+/// @}
+void test_report_models(void);
+
+/// @defgroup APIKeyModel "APIKeyModel"
+/// @{
+/// @brief SQLAlchemy model for API Key authentication — stores SHA-256 hash only, raw key shown once at creation.
+/// @invariant Raw key is NEVER stored — shown once at creation and discarded.
+/// @}
+void APIKeyModel(void);
+
+/// @defgroup APIKey "APIKey"
+/// @{
+/// @brief Stores API key metadata and SHA-256 hash for service-to-service authentication.
+/// @}
+void APIKey(void);
+
+/// @defgroup AssistantModels "AssistantModels"
+/// @{
+/// @brief SQLAlchemy models for assistant audit trail and confirmation tokens.
+/// @invariant Assistant records preserve immutable ids and creation timestamps.
+/// @}
+void AssistantModels(void);
+
+/// @defgroup AssistantAuditRecord "AssistantAuditRecord"
+/// @{
+/// @brief Store audit decisions and outcomes produced by assistant command handling.
+/// @post Audit payload remains available for compliance and debugging.
+/// @pre user_id must identify the actor for every record.
+/// @}
+void AssistantAuditRecord(void);
+
+/// @defgroup AssistantMessageRecord "AssistantMessageRecord"
+/// @{
+/// @brief Persist chat history entries for assistant conversations.
+/// @post Message row can be queried in chronological order.
+/// @pre user_id, conversation_id, role and text must be present.
+/// @}
+void AssistantMessageRecord(void);
+
+/// @defgroup AssistantConfirmationRecord "AssistantConfirmationRecord"
+/// @{
+/// @brief Persist risky operation confirmation tokens with lifecycle state.
+/// @post State transitions can be tracked and audited.
+/// @pre intent/dispatch and expiry timestamp must be provided.
+/// @}
+void AssistantConfirmationRecord(void);
+
+/// @defgroup AuthModels "AuthModels"
+/// @{
+/// @brief SQLAlchemy models for multi-user authentication and authorization.
+/// @invariant Usernames and emails must be unique.
+/// @post Auth ORM models registered with unique constraints
+/// @pre Database engine initialized
+/// @}
+void AuthModels(void);
+
+/// @defgroup generate_uuid "generate_uuid"
+/// @{
+/// @brief Generates a unique UUID string.
+/// @post Returns a string representation of a new UUID.
+/// @}
+void generate_uuid(void);
+
+/// @defgroup user_roles "user_roles"
+/// @{
+/// @brief Association table for many-to-many relationship between Users and Roles.
+/// @}
+void user_roles(void);
+
+/// @defgroup role_permissions "role_permissions"
+/// @{
+/// @brief Association table for many-to-many relationship between Roles and Permissions.
+/// @}
+void role_permissions(void);
+
+/// @defgroup Role "Role"
+/// @{
+/// @brief Represents a collection of permissions.
+/// @}
+void Role(void);
+
+/// @defgroup Permission "Permission"
+/// @{
+/// @brief Represents a specific capability within the system.
+/// @}
+void Permission(void);
+
+/// @defgroup ADGroupMapping "ADGroupMapping"
+/// @{
+/// @brief Maps an Active Directory group to a local System Role.
+/// @}
+void ADGroupMapping(void);
+
+/// @defgroup CleanReleaseModels "CleanReleaseModels"
+/// @{
+/// @brief Define canonical clean release domain entities and lifecycle guards.
+/// @invariant Immutable snapshots are never mutated; forbidden lifecycle transitions are rejected.
+/// @post Provides SQLAlchemy and dataclass definitions for governance domain.
+/// @pre Base mapping model and release enums are available.
+/// @}
+void CleanReleaseModels(void);
+
+/// @defgroup ExecutionMode "ExecutionMode"
+/// @{
+/// @brief Backward-compatible execution mode enum for legacy TUI/orchestrator tests.
+/// @}
+void ExecutionMode(void);
+
+/// @defgroup CheckFinalStatus "CheckFinalStatus"
+/// @{
+/// @brief Backward-compatible final status enum for legacy TUI/orchestrator tests.
+/// @}
+void CheckFinalStatus(void);
+
+/// @defgroup CheckStageName "CheckStageName"
+/// @{
+/// @brief Backward-compatible stage name enum for legacy TUI/orchestrator tests.
+/// @}
+void CheckStageName(void);
+
+/// @defgroup CheckStageStatus "CheckStageStatus"
+/// @{
+/// @brief Backward-compatible stage status enum for legacy TUI/orchestrator tests.
+/// @}
+void CheckStageStatus(void);
+
+/// @defgroup CheckStageResult "CheckStageResult"
+/// @{
+/// @brief Backward-compatible stage result container for legacy TUI/orchestrator tests.
+/// @}
+void CheckStageResult(void);
+
+/// @defgroup ProfileType "ProfileType"
+/// @{
+/// @brief Backward-compatible profile enum for legacy TUI bootstrap logic.
+/// @}
+void ProfileType(void);
+
+/// @defgroup RegistryStatus "RegistryStatus"
+/// @{
+/// @brief Backward-compatible registry status enum for legacy TUI bootstrap logic.
+/// @}
+void RegistryStatus(void);
+
+/// @defgroup ReleaseCandidateStatus "ReleaseCandidateStatus"
+/// @{
+/// @brief Backward-compatible release candidate status enum for legacy TUI.
+/// @}
+void ReleaseCandidateStatus(void);
+
+/// @defgroup ResourceSourceEntry "ResourceSourceEntry"
+/// @{
+/// @brief Backward-compatible source entry model for legacy TUI bootstrap logic.
+/// @}
+void ResourceSourceEntry(void);
+
+/// @defgroup ResourceSourceRegistry "ResourceSourceRegistry"
+/// @{
+/// @brief Backward-compatible source registry model for legacy TUI bootstrap logic.
+/// @}
+void ResourceSourceRegistry(void);
+
+/// @defgroup CleanProfilePolicy "CleanProfilePolicy"
+/// @{
+/// @brief Backward-compatible policy model for legacy TUI bootstrap logic.
+/// @}
+void CleanProfilePolicy(void);
+
+/// @defgroup ComplianceCheckRun "ComplianceCheckRun"
+/// @{
+/// @brief Backward-compatible run model for legacy TUI typing/import compatibility.
+/// @}
+void ComplianceCheckRun(void);
+
+/// @defgroup ReleaseCandidate "ReleaseCandidate"
+/// @{
+/// @brief Represents the release unit being prepared and governed.
+/// @post status advances only through legal transitions.
+/// @pre id, version, source_snapshot_ref are non-empty.
+/// @}
+void ReleaseCandidate(void);
+
+/// @defgroup CandidateArtifact "CandidateArtifact"
+/// @{
+/// @brief Represents one artifact associated with a release candidate.
+/// @}
+void CandidateArtifact(void);
+
+/// @defgroup ManifestItem "ManifestItem"
+/// @{
+/// @}
+void ManifestItem(void);
+
+/// @defgroup ManifestSummary "ManifestSummary"
+/// @{
+/// @}
+void ManifestSummary(void);
+
+/// @defgroup DistributionManifest "DistributionManifest"
+/// @{
+/// @brief Immutable snapshot of the candidate payload.
+/// @invariant Immutable after creation.
+/// @}
+void DistributionManifest(void);
+
+/// @defgroup SourceRegistrySnapshot "SourceRegistrySnapshot"
+/// @{
+/// @brief Immutable registry snapshot for allowed sources.
+/// @}
+void SourceRegistrySnapshot(void);
+
+/// @defgroup CleanPolicySnapshot "CleanPolicySnapshot"
+/// @{
+/// @brief Immutable policy snapshot used to evaluate a run.
+/// @}
+void CleanPolicySnapshot(void);
+
+/// @defgroup ComplianceRun "ComplianceRun"
+/// @{
+/// @brief Operational record for one compliance execution.
+/// @}
+void ComplianceRun(void);
+
+/// @defgroup ComplianceStageRun "ComplianceStageRun"
+/// @{
+/// @brief Stage-level execution record inside a run.
+/// @}
+void ComplianceStageRun(void);
+
+/// @defgroup ViolationSeverity "ViolationSeverity"
+/// @{
+/// @brief Backward-compatible violation severity enum for legacy clean-release tests.
+/// @}
+void ViolationSeverity(void);
+
+/// @defgroup ViolationCategory "ViolationCategory"
+/// @{
+/// @brief Backward-compatible violation category enum for legacy clean-release tests.
+/// @}
+void ViolationCategory(void);
+
+/// @defgroup ComplianceViolation "ComplianceViolation"
+/// @{
+/// @brief Violation produced by a stage.
+/// @}
+void ComplianceViolation(void);
+
+/// @defgroup ComplianceReport "ComplianceReport"
+/// @{
+/// @brief Immutable result derived from a completed run.
+/// @invariant Immutable after creation.
+/// @}
+void ComplianceReport(void);
+
+/// @defgroup ApprovalDecision "ApprovalDecision"
+/// @{
+/// @brief Approval or rejection bound to a candidate and report.
+/// @}
+void ApprovalDecision(void);
+
+/// @defgroup PublicationRecord "PublicationRecord"
+/// @{
+/// @brief Publication or revocation record.
+/// @}
+void PublicationRecord(void);
+
+/// @defgroup CleanReleaseAuditLog "CleanReleaseAuditLog"
+/// @{
+/// @brief Represents a persistent audit log entry for clean release actions.
+/// @}
+void CleanReleaseAuditLog(void);
+
+/// @defgroup AppConfigRecord "AppConfigRecord"
+/// @{
+/// @brief Stores persisted application configuration as a single authoritative record model.
+/// @post ORM table 'app_configurations' exposes id, payload, and updated_at fields with declared nullability/default semantics.
+/// @pre SQLAlchemy declarative Base is initialized and table metadata registration is active.
+/// @}
+void AppConfigRecord(void);
+
+/// @defgroup NotificationConfig "NotificationConfig"
+/// @{
+/// @brief Stores persisted provider-level notification configuration and encrypted credentials metadata.
+/// @post ORM table 'notification_configs' exposes id, type, name, credentials, is_active, created_at, updated_at fields with declared constraints/defaults.
+/// @pre SQLAlchemy declarative Base is initialized and uuid generation is available at instance creation time.
+/// @}
+void NotificationConfig(void);
+
+/// @defgroup DashboardModels "DashboardModels"
+/// @{
+/// @brief Defines data models for dashboard metadata and selection.
+/// @}
+void DashboardModels(void);
+
+/// @defgroup DashboardMetadata "DashboardMetadata"
+/// @{
+/// @brief Represents a dashboard available for migration.
+/// @}
+void DashboardMetadata(void);
+
+/// @defgroup DashboardSelection "DashboardSelection"
+/// @{
+/// @brief Represents the user's selection of dashboards to migrate.
+/// @}
+void DashboardSelection(void);
+
+/// @defgroup DatasetReviewModels "DatasetReviewModels"
+/// @{
+/// @brief Thin facade re-exporting all dataset review domain models from the decomposed sub-package.
+/// @invariant All public model classes and enums remain importable from `src.models.dataset_review` without changes.
+/// @}
+void DatasetReviewModels(void);
+
+/// @defgroup DatasetReviewClarificationModels "DatasetReviewClarificationModels"
+/// @{
+/// @brief Clarification session, question, option, and answer models for guided review flow.
+/// @invariant Only one active clarification question may exist at a time per session.
+/// @post Clarification ORM models registered
+/// @pre Database engine initialized
+/// @}
+void DatasetReviewClarificationModels(void);
+
+/// @defgroup ClarificationSession "ClarificationSession"
+/// @{
+/// @brief One clarification session aggregate owning questions and tracking resolution progress.
+/// @}
+void ClarificationSession(void);
+
+/// @defgroup ClarificationQuestion "ClarificationQuestion"
+/// @{
+/// @brief One clarification question with priority ordering, options, and state machine.
+/// @}
+void ClarificationQuestion(void);
+
+/// @defgroup ClarificationOption "ClarificationOption"
+/// @{
+/// @brief One selectable option for a clarification question with recommendation flag.
+/// @}
+void ClarificationOption(void);
+
+/// @defgroup ClarificationAnswer "ClarificationAnswer"
+/// @{
+/// @brief One persisted clarification answer with impact summary and feedback tracking.
+/// @}
+void ClarificationAnswer(void);
+
+/// @defgroup DatasetReviewEnums "DatasetReviewEnums"
+/// @{
+/// @brief All enumeration types for the dataset review domain, grouped for stable cross-module reuse.
+/// @invariant Enum values are string-based for JSON serialization compatibility.
+/// @}
+void DatasetReviewEnums(void);
+
+/// @defgroup SessionStatus "SessionStatus"
+/// @{
+/// @brief Lifecycle status of a dataset review session.
+/// @}
+void SessionStatus(void);
+
+/// @defgroup SessionPhase "SessionPhase"
+/// @{
+/// @brief Ordered phase progression for dataset review orchestration.
+/// @}
+void SessionPhase(void);
+
+/// @defgroup ReadinessState "ReadinessState"
+/// @{
+/// @brief Granular readiness indicator driving the recommended-action UX flow.
+/// @}
+void ReadinessState(void);
+
+/// @defgroup RecommendedAction "RecommendedAction"
+/// @{
+/// @brief Next-action guidance derived from the current readiness state.
+/// @}
+void RecommendedAction(void);
+
+/// @defgroup SessionCollaboratorRole "SessionCollaboratorRole"
+/// @{
+/// @brief RBAC role for session collaborators.
+/// @}
+void SessionCollaboratorRole(void);
+
+/// @defgroup BusinessSummarySource "BusinessSummarySource"
+/// @{
+/// @brief Provenance of the dataset business summary text.
+/// @}
+void BusinessSummarySource(void);
+
+/// @defgroup ConfidenceState "ConfidenceState"
+/// @{
+/// @brief Confidence level for dataset profile completeness.
+/// @}
+void ConfidenceState(void);
+
+/// @defgroup FindingArea "FindingArea"
+/// @{
+/// @brief Domain area classification for validation findings.
+/// @}
+void FindingArea(void);
+
+/// @defgroup FindingSeverity "FindingSeverity"
+/// @{
+/// @brief Severity classification for validation findings.
+/// @}
+void FindingSeverity(void);
+
+/// @defgroup ResolutionState "ResolutionState"
+/// @{
+/// @brief Resolution status for validation findings and clarification items.
+/// @}
+void ResolutionState(void);
+
+/// @defgroup SemanticSourceType "SemanticSourceType"
+/// @{
+/// @brief Classification of semantic enrichment source origins.
+/// @}
+void SemanticSourceType(void);
+
+/// @defgroup TrustLevel "TrustLevel"
+/// @{
+/// @brief Trust classification for semantic source reliability.
+/// @}
+void TrustLevel(void);
+
+/// @defgroup SemanticSourceStatus "SemanticSourceStatus"
+/// @{
+/// @brief Lifecycle status for semantic source application.
+/// @}
+void SemanticSourceStatus(void);
+
+/// @defgroup FieldKind "FieldKind"
+/// @{
+/// @brief Kind classification for semantic field entries.
+/// @}
+void FieldKind(void);
+
+/// @defgroup FieldProvenance "FieldProvenance"
+/// @{
+/// @brief Provenance tracking for semantic field value origin.
+/// @}
+void FieldProvenance(void);
+
+/// @defgroup CandidateMatchType "CandidateMatchType"
+/// @{
+/// @brief Match type classification for semantic candidates.
+/// @}
+void CandidateMatchType(void);
+
+/// @defgroup CandidateStatus "CandidateStatus"
+/// @{
+/// @brief Lifecycle status for semantic candidate proposals.
+/// @}
+void CandidateStatus(void);
+
+/// @defgroup FilterSource "FilterSource"
+/// @{
+/// @brief Origin classification for imported filters.
+/// @}
+void FilterSource(void);
+
+/// @defgroup FilterConfidenceState "FilterConfidenceState"
+/// @{
+/// @brief Confidence classification for imported filter values.
+/// @}
+void FilterConfidenceState(void);
+
+/// @defgroup FilterRecoveryStatus "FilterRecoveryStatus"
+/// @{
+/// @brief Recovery quality status for imported filters.
+/// @}
+void FilterRecoveryStatus(void);
+
+/// @defgroup VariableKind "VariableKind"
+/// @{
+/// @brief Kind classification for template variables.
+/// @}
+void VariableKind(void);
+
+/// @defgroup MappingStatus "MappingStatus"
+/// @{
+/// @brief Lifecycle status for template variable mapping.
+/// @}
+void MappingStatus(void);
+
+/// @defgroup MappingMethod "MappingMethod"
+/// @{
+/// @brief Method classification for execution mapping creation.
+/// @}
+void MappingMethod(void);
+
+/// @defgroup MappingWarningLevel "MappingWarningLevel"
+/// @{
+/// @brief Warning severity for execution mapping quality indicators.
+/// @}
+void MappingWarningLevel(void);
+
+/// @defgroup ApprovalState "ApprovalState"
+/// @{
+/// @brief Approval lifecycle for execution mapping gate checks.
+/// @}
+void ApprovalState(void);
+
+/// @defgroup ClarificationStatus "ClarificationStatus"
+/// @{
+/// @brief Lifecycle status for clarification sessions.
+/// @}
+void ClarificationStatus(void);
+
+/// @defgroup QuestionState "QuestionState"
+/// @{
+/// @brief State machine for individual clarification questions.
+/// @}
+void QuestionState(void);
+
+/// @defgroup AnswerKind "AnswerKind"
+/// @{
+/// @brief Classification of clarification answer types.
+/// @}
+void AnswerKind(void);
+
+/// @defgroup PreviewStatus "PreviewStatus"
+/// @{
+/// @brief Lifecycle status for compiled SQL previews.
+/// @}
+void PreviewStatus(void);
+
+/// @defgroup LaunchStatus "LaunchStatus"
+/// @{
+/// @brief Outcome status for dataset launch handoff.
+/// @}
+void LaunchStatus(void);
+
+/// @defgroup ArtifactType "ArtifactType"
+/// @{
+/// @brief Type classification for export artifacts.
+/// @}
+void ArtifactType(void);
+
+/// @defgroup ArtifactFormat "ArtifactFormat"
+/// @{
+/// @brief Format classification for export artifact output.
+/// @}
+void ArtifactFormat(void);
+
+/// @defgroup DatasetReviewExecutionModels "DatasetReviewExecutionModels"
+/// @{
+/// @brief Compiled preview, run context, session event, and export artifact models for execution and audit.
+/// @}
+void DatasetReviewExecutionModels(void);
+
+/// @defgroup CompiledPreview "CompiledPreview"
+/// @{
+/// @brief One compiled SQL preview snapshot with fingerprint for staleness detection.
+/// @}
+void CompiledPreview(void);
+
+/// @defgroup DatasetRunContext "DatasetRunContext"
+/// @{
+/// @brief Immutable launch audit snapshot capturing effective filters, template params, and approval state at launch time.
+/// @}
+void DatasetRunContext(void);
+
+/// @defgroup SessionEvent "SessionEvent"
+/// @{
+/// @brief One persisted audit event for dataset review session mutations.
+/// @}
+void SessionEvent(void);
+
+/// @defgroup ExportArtifact "ExportArtifact"
+/// @{
+/// @brief One persisted export artifact reference for documentation and validation outputs.
+/// @}
+void ExportArtifact(void);
+
+/// @defgroup DatasetReviewFilterModels "DatasetReviewFilterModels"
+/// @{
+/// @brief Imported filter and template variable models for Superset context recovery and execution mapping.
+/// @}
+void DatasetReviewFilterModels(void);
+
+/// @defgroup ImportedFilter "ImportedFilter"
+/// @{
+/// @brief Recovered Superset filter with confidence and recovery status tracking.
+/// @}
+void ImportedFilter(void);
+
+/// @defgroup TemplateVariable "TemplateVariable"
+/// @{
+/// @brief Discovered template variable from dataset SQL with mapping status tracking.
+/// @}
+void TemplateVariable(void);
+
+/// @defgroup DatasetReviewFindingModels "DatasetReviewFindingModels"
+/// @{
+/// @brief Validation finding model for tracking blocking, warning, and informational issues during review.
+/// @}
+void DatasetReviewFindingModels(void);
+
+/// @defgroup ValidationFinding "ValidationFinding"
+/// @{
+/// @brief Structured finding record for dataset review validation issues with resolution tracking.
+/// @}
+void ValidationFinding(void);
+
+/// @defgroup DatasetReviewMappingModels "DatasetReviewMappingModels"
+/// @{
+/// @brief Execution mapping model linking imported filters to template variables with approval gates.
+/// @}
+void DatasetReviewMappingModels(void);
+
+/// @defgroup ExecutionMapping "ExecutionMapping"
+/// @{
+/// @brief One filter-to-variable mapping with approval gate, effective value, and transformation metadata.
+/// @invariant Explicit approval is required before launch when requires_explicit_approval is true.
+/// @}
+void ExecutionMapping(void);
+
+/// @defgroup DatasetReviewProfileModels "DatasetReviewProfileModels"
+/// @{
+/// @brief Dataset profile model capturing business summary, confidence, and completeness metadata.
+/// @}
+void DatasetReviewProfileModels(void);
+
+/// @defgroup DatasetProfile "DatasetProfile"
+/// @{
+/// @brief One-to-one profile snapshot for a dataset review session, tracking business summary provenance and completeness.
+/// @}
+void DatasetProfile(void);
+
+/// @defgroup DatasetReviewSemanticModels "DatasetReviewSemanticModels"
+/// @{
+/// @brief Semantic source, field entry, and candidate models for dictionary-driven semantic enrichment.
+/// @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+/// @post Semantic ORM models registered with override protection
+/// @pre Database engine initialized
+/// @}
+void DatasetReviewSemanticModels(void);
+
+/// @defgroup SemanticSource "SemanticSource"
+/// @{
+/// @brief Registered semantic enrichment source with trust level and application status.
+/// @}
+void SemanticSource(void);
+
+/// @defgroup SemanticFieldEntry "SemanticFieldEntry"
+/// @{
+/// @brief Per-field semantic metadata entry with provenance tracking, lock state, and candidate set.
+/// @invariant Locked fields preserve their active value regardless of later candidate proposals.
+/// @}
+void SemanticFieldEntry(void);
+
+/// @defgroup SemanticCandidate "SemanticCandidate"
+/// @{
+/// @brief One proposed semantic value for a field entry, ranked by match type and confidence.
+/// @}
+void SemanticCandidate(void);
+
+/// @defgroup DatasetReviewSessionModels "DatasetReviewSessionModels"
+/// @{
+/// @brief Session aggregate root and collaborator models for dataset review orchestration.
+/// @invariant Session and profile entities are strictly scoped to an authenticated user.
+/// @post Session ORM models registered with optimistic locking
+/// @pre Database engine initialized
+/// @}
+void DatasetReviewSessionModels(void);
+
+/// @defgroup SessionCollaborator "SessionCollaborator"
+/// @{
+/// @brief RBAC collaborator record linking a user to a dataset review session with a specific role.
+/// @}
+void SessionCollaborator(void);
+
+/// @defgroup DatasetReviewSession "DatasetReviewSession"
+/// @{
+/// @brief Aggregate root for the dataset review lifecycle, owning all child entities and driving readiness transitions.
+/// @invariant Optimistic-lock version column prevents lost-update races on concurrent mutations.
+/// @}
+void DatasetReviewSession(void);
+
+/// @defgroup FilterStateModels "FilterStateModels"
+/// @{
+/// @brief Pydantic models for Superset native filter state extraction and restoration.
+/// @}
+void FilterStateModels(void);
+
+/// @defgroup FilterState "FilterState"
+/// @{
+/// @brief Represents the state of a single native filter.
+/// @}
+void FilterState(void);
+
+/// @defgroup NativeFilterDataMask "NativeFilterDataMask"
+/// @{
+/// @brief Represents the dataMask containing all native filter states.
+/// @}
+void NativeFilterDataMask(void);
+
+/// @defgroup ParsedNativeFilters "ParsedNativeFilters"
+/// @{
+/// @brief Result of parsing native filters from permalink or native_filters_key.
+/// @}
+void ParsedNativeFilters(void);
+
+/// @defgroup DashboardURLFilterExtraction "DashboardURLFilterExtraction"
+/// @{
+/// @brief Result of parsing a complete dashboard URL for filter information.
+/// @}
+void DashboardURLFilterExtraction(void);
+
+/// @defgroup ExtraFormDataMerge "ExtraFormDataMerge"
+/// @{
+/// @brief Configuration for merging extraFormData from different sources.
+/// @}
+void ExtraFormDataMerge(void);
+
+/// @defgroup GitModels "GitModels"
+/// @{
+/// @}
+void GitModels(void);
+
+/// @defgroup GitServerConfig "GitServerConfig"
+/// @{
+/// @brief Configuration for a Git server connection.
+/// @}
+void GitServerConfig(void);
+
+/// @defgroup GitRepository "GitRepository"
+/// @{
+/// @brief Tracking for a local Git repository linked to a dashboard.
+/// @}
+void GitRepository(void);
+
+/// @defgroup DeploymentEnvironment "DeploymentEnvironment"
+/// @{
+/// @brief Target Superset environments for dashboard deployment.
+/// @}
+void DeploymentEnvironment(void);
+
+/// @defgroup LlmModels "LlmModels"
+/// @{
+/// @brief SQLAlchemy models for LLM provider configuration and validation results.
+/// @}
+void LlmModels(void);
+
+/// @defgroup ValidationPolicy "ValidationPolicy"
+/// @{
+/// @brief Defines a scheduled rule for validating a group of dashboards within an execution window.
+/// @}
+void ValidationPolicy(void);
+
+/// @defgroup LLMProvider "LLMProvider"
+/// @{
+/// @brief SQLAlchemy model for LLM provider configuration.
+/// @}
+void LLMProvider(void);
+
+/// @defgroup ValidationRecord "ValidationRecord"
+/// @{
+/// @brief SQLAlchemy model for dashboard validation history.
+/// @}
+void ValidationRecord(void);
+
+/// @defgroup MaintenanceModels "MaintenanceModels"
+/// @{
+/// @brief SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.
+/// @invariant MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint
+/// @}
+void MaintenanceModels(void);
+
+/// @defgroup MaintenanceEventStatus "MaintenanceEventStatus"
+/// @{
+/// @}
+void MaintenanceEventStatus(void);
+
+/// @defgroup MaintenanceDashboardBannerStatus "MaintenanceDashboardBannerStatus"
+/// @{
+/// @}
+void MaintenanceDashboardBannerStatus(void);
+
+/// @defgroup MaintenanceDashboardStateStatus "MaintenanceDashboardStateStatus"
+/// @{
+/// @}
+void MaintenanceDashboardStateStatus(void);
+
+/// @defgroup DashboardScope "DashboardScope"
+/// @{
+/// @}
+void DashboardScope(void);
+
+/// @defgroup MaintenanceEvent "MaintenanceEvent"
+/// @{
+/// @brief A record of a maintenance event with table list, time window, status, and linked dashboard states.
+/// @}
+void MaintenanceEvent(void);
+
+/// @defgroup MaintenanceDashboardBanner "MaintenanceDashboardBanner"
+/// @{
+/// @brief The canonical "one chart per dashboard" entity. Unique partial index enforces single active banner per dashboard.
+/// @invariant Unique partial index (environment_id, dashboard_id) WHERE status='active'
+/// @}
+void MaintenanceDashboardBanner(void);
+
+/// @defgroup MaintenanceDashboardState "MaintenanceDashboardState"
+/// @{
+/// @brief Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.
+/// @}
+void MaintenanceDashboardState(void);
+
+/// @defgroup MaintenanceSettings "MaintenanceSettings"
+/// @{
+/// @brief Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').
+/// @invariant id must always be 'default' — enforced by CheckConstraint
+/// @}
+void MaintenanceSettings(void);
+
+/// @defgroup MappingModels "MappingModels"
+/// @{
+/// @brief Defines the database schema for environment metadata and database mappings using SQLAlchemy.
+/// @invariant All primary keys are UUID strings.
+/// @}
+void MappingModels(void);
+
+/// @defgroup Base "Base"
+/// @{
+/// @brief SQLAlchemy declarative base for all domain models.
+/// @}
+void Base(void);
+
+/// @defgroup ResourceType "ResourceType"
+/// @{
+/// @brief Enumeration of possible Superset resource types for ID mapping.
+/// @}
+void ResourceType(void);
+
+/// @defgroup MigrationStatus "MigrationStatus"
+/// @{
+/// @brief Enumeration of possible migration job statuses.
+/// @}
+void MigrationStatus(void);
+
+/// @defgroup MigrationJob "MigrationJob"
+/// @{
+/// @brief Represents a single migration execution job.
+/// @}
+void MigrationJob(void);
+
+/// @defgroup ResourceMapping "ResourceMapping"
+/// @{
+/// @brief Maps a universal UUID for a resource to its actual ID on a specific environment.
+/// @}
+void ResourceMapping(void);
+
+/// @defgroup ProfileModels "ProfileModels"
+/// @{
+/// @brief Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
+/// @invariant Sensitive Git token is stored encrypted and never returned in plaintext.
+/// @post Profile ORM models registered
+/// @pre Database engine initialized
+/// @}
+void ProfileModels(void);
+
+/// @defgroup UserDashboardPreference "UserDashboardPreference"
+/// @{
+/// @brief Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
+/// @}
+void UserDashboardPreference(void);
+
+/// @defgroup ReportModels "ReportModels"
+/// @{
+/// @brief Canonical report schemas for unified task reporting across heterogeneous task types.
+/// @invariant Canonical report fields are always present for every report item.
+/// @post Provides validated schemas for cross-plugin reporting and UI consumption.
+/// @pre Pydantic library and task manager models are available.
+/// @}
+void ReportModels(void);
+
+/// @defgroup TaskType "TaskType"
+/// @{
+/// @brief Supported normalized task report types.
+/// @invariant Must contain valid generic task type mappings.
+/// @}
+void TaskType(void);
+
+/// @defgroup ReportStatus "ReportStatus"
+/// @{
+/// @brief Supported normalized report status values.
+/// @invariant TaskStatus enum mapping logic holds.
+/// @}
+void ReportStatus(void);
+
+/// @defgroup ErrorContext "ErrorContext"
+/// @{
+/// @brief Error and recovery context for failed/partial reports.
+/// @invariant The properties accurately describe error state.
+/// @}
+void ErrorContext(void);
+
+/// @defgroup TaskReport "TaskReport"
+/// @{
+/// @brief Canonical normalized report envelope for one task execution.
+/// @invariant Must represent canonical task record attributes.
+/// @}
+void TaskReport(void);
+
+/// @defgroup ReportQuery "ReportQuery"
+/// @{
+/// @brief Query object for server-side report filtering, sorting, and pagination.
+/// @invariant Time and pagination queries are mutually consistent.
+/// @}
+void ReportQuery(void);
+
+/// @defgroup ReportCollection "ReportCollection"
+/// @{
+/// @brief Paginated collection of normalized task reports.
+/// @invariant Represents paginated data correctly.
+/// @}
+void ReportCollection(void);
+
+/// @defgroup ReportDetailView "ReportDetailView"
+/// @{
+/// @brief Detailed report representation including diagnostics and recovery actions.
+/// @invariant Incorporates a report and logs correctly.
+/// @}
+void ReportDetailView(void);
+
+/// @defgroup StorageModels "StorageModels"
+/// @{
+/// @}
+void StorageModels(void);
+
+/// @defgroup FileCategory "FileCategory"
+/// @{
+/// @brief Enumeration of supported file categories in the storage system.
+/// @}
+void FileCategory(void);
+
+/// @defgroup StorageConfig "StorageConfig"
+/// @{
+/// @brief Configuration model for the storage system, defining paths and naming patterns.
+/// @}
+void StorageConfig(void);
+
+/// @defgroup StoredFile "StoredFile"
+/// @{
+/// @brief Data model representing metadata for a file stored in the system.
+/// @}
+void StoredFile(void);
+
+/// @defgroup TaskModels "TaskModels"
+/// @{
+/// @brief Defines the database schema for task execution records.
+/// @invariant All primary keys are UUID strings.
+/// @}
+void TaskModels(void);
+
+/// @defgroup TaskRecord "TaskRecord"
+/// @{
+/// @brief Represents a persistent record of a task execution.
+/// @}
+void TaskRecord(void);
+
+/// @defgroup TaskLogRecord "TaskLogRecord"
+/// @{
+/// @brief Represents a single persistent log entry for a task.
+/// @invariant Each log entry belongs to exactly one task.
+/// @}
+void TaskLogRecord(void);
+
+/// @defgroup TranslateModels "TranslateModels"
+/// @{
+/// @brief SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects.
+/// @}
+void TranslateModels(void);
+
+/// @defgroup TranslationJob "TranslationJob"
+/// @{
+/// @brief A translation job representing a multi-dialect conversion task with column mappings, LLM config, and dictionary attachments.
+/// @}
+void TranslationJob(void);
+
+/// @defgroup TranslationRun "TranslationRun"
+/// @{
+/// @brief Represents a single execution of a translation job, capturing status, timing, and Superset execution metadata.
+/// @}
+void TranslationRun(void);
+
+/// @defgroup TranslationBatch "TranslationBatch"
+/// @{
+/// @brief Groups translation records within a run into manageable batches with timing and record counts.
+/// @}
+void TranslationBatch(void);
+
+/// @defgroup TranslationRecord "TranslationRecord"
+/// @{
+/// @brief Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.
+/// @}
+void TranslationRecord(void);
+
+/// @defgroup TranslationEvent "TranslationEvent"
+/// @{
+/// @brief Audit/event log for translation operations, with optional run_id for context.
+/// @}
+void TranslationEvent(void);
+
+/// @defgroup TranslationPreviewSession "TranslationPreviewSession"
+/// @{
+/// @brief A preview session allowing users to review proposed translations before applying them.
+/// @}
+void TranslationPreviewSession(void);
+
+/// @defgroup TranslationPreviewRecord "TranslationPreviewRecord"
+/// @{
+/// @brief Individual preview entry within a preview session, showing original and translated content side by side.
+/// @}
+void TranslationPreviewRecord(void);
+
+/// @defgroup TerminologyDictionary "TerminologyDictionary"
+/// @{
+/// @brief A named collection of terminology mappings used during translation to ensure consistent term translation.
+/// @}
+void TerminologyDictionary(void);
+
+/// @defgroup DictionaryEntry "DictionaryEntry"
+/// @{
+/// @brief A single term mapping entry with case-insensitive unique constraint on source_term_normalized and origin tracking.
+/// @}
+void DictionaryEntry(void);
+
+/// @defgroup TranslationSchedule "TranslationSchedule"
+/// @{
+/// @brief Defines a cron-based schedule for recurring translation jobs.
+/// @}
+void TranslationSchedule(void);
+
+/// @defgroup TranslationJobDictionary "TranslationJobDictionary"
+/// @{
+/// @brief Many-to-many association between translation jobs and terminology dictionaries.
+/// @}
+void TranslationJobDictionary(void);
+
+/// @defgroup MetricSnapshot "MetricSnapshot"
+/// @{
+/// @brief Captures translation performance metrics at a point in time with config/content/dictionary hash keys for aggregation.
+/// @}
+void MetricSnapshot(void);
+
+/// @defgroup TranslationLanguage "TranslationLanguage"
+/// @{
+/// @brief Per-language translation result for a single record, supporting multi-language output.
+/// @}
+void TranslationLanguage(void);
+
+/// @defgroup TranslationPreviewLanguage "TranslationPreviewLanguage"
+/// @{
+/// @brief Per-language preview entry within a preview session.
+/// @}
+void TranslationPreviewLanguage(void);
+
+/// @defgroup TranslationRunLanguageStats "TranslationRunLanguageStats"
+/// @{
+/// @brief Per-language statistics for a translation run (row counts, tokens, cost).
+/// @}
+void TranslationRunLanguageStats(void);
+
+/// @defgroup src_plugins "src.plugins"
+/// @{
+/// @brief Plugin package root for dynamic discovery and runtime imports.
+/// @}
+void src_plugins(void);
+
+/// @defgroup BackupPlugin "BackupPlugin"
+/// @{
+/// @brief A plugin that provides functionality to back up Superset dashboards.
+/// @}
+void BackupPlugin(void);
+
+/// @defgroup DebugPluginModule "DebugPluginModule"
+/// @{
+/// @brief Plugin for diagnostics. Inherits PluginBase.
+/// @}
+void DebugPluginModule(void);
+
+/// @defgroup DebugPlugin "DebugPlugin"
+/// @{
+/// @brief Plugin for system diagnostics and debugging.
+/// @}
+void DebugPlugin(void);
+
+/// @defgroup GitPluginExt "GitPluginExt"
+/// @{
+/// @brief Git plugin extension package root.
+/// @}
+void GitPluginExt(void);
+
+/// @defgroup GitLLMExtensionModule "GitLLMExtensionModule"
+/// @{
+/// @brief LLM-based extensions for the Git plugin, specifically for commit message generation.
+/// @}
+void GitLLMExtensionModule(void);
+
+/// @defgroup GitLLMExtension "GitLLMExtension"
+/// @{
+/// @brief Provides LLM capabilities to the Git plugin.
+/// @}
+void GitLLMExtension(void);
+
+/// @defgroup GitPluginModule "GitPluginModule"
+/// @{
+/// @brief Предоставляет плагин для версионирования и развертывания дашбордов Superset.
+/// @invariant _handle_sync сохраняет backup управляемых директорий перед удалением;
+/// @}
+void GitPluginModule(void);
+
+/// @defgroup GitPlugin "GitPlugin"
+/// @{
+/// @brief Реализация плагина Git Integration для управления версиями дашбордов.
+/// @}
+void GitPlugin(void);
+
+/// @defgroup LLMAnalysisPackage "LLMAnalysisPackage"
+/// @{
+/// @}
+void LLMAnalysisPackage(void);
+
+/// @defgroup LLMAnalysisModels "LLMAnalysisModels"
+/// @{
+/// @brief Define Pydantic models for LLM Analysis plugin.
+/// @}
+void LLMAnalysisModels(void);
+
+/// @defgroup LLMProviderType "LLMProviderType"
+/// @{
+/// @brief Enum for supported LLM providers.
+/// @}
+void LLMProviderType(void);
+
+/// @defgroup LLMProviderConfig "LLMProviderConfig"
+/// @{
+/// @brief Configuration for an LLM provider.
+/// @}
+void LLMProviderConfig(void);
+
+/// @defgroup ValidationStatus "ValidationStatus"
+/// @{
+/// @brief Enum for dashboard validation status.
+/// @}
+void ValidationStatus(void);
+
+/// @defgroup DetectedIssue "DetectedIssue"
+/// @{
+/// @brief Model for a single issue detected during validation.
+/// @}
+void DetectedIssue(void);
+
+/// @defgroup ValidationResult "ValidationResult"
+/// @{
+/// @brief Model for dashboard validation result.
+/// @}
+void ValidationResult(void);
+
+/// @defgroup LLMAnalysisPlugin "LLMAnalysisPlugin"
+/// @{
+/// @brief Implements DashboardValidationPlugin and DocumentationPlugin.
+/// @invariant All LLM interactions must be executed as asynchronous tasks.
+/// @}
+void LLMAnalysisPlugin(void);
+
+/// @defgroup _is_masked_or_invalid_api_key "_is_masked_or_invalid_api_key"
+/// @{
+/// @brief Guards against placeholder or malformed API keys in runtime.
+/// @post Returns True when value cannot be used for authenticated provider calls.
+/// @pre value may be None.
+/// @}
+void _is_masked_or_invalid_api_key(void);
+
+/// @defgroup _json_safe_value "_json_safe_value"
+/// @{
+/// @brief Recursively normalize payload values for JSON serialization.
+/// @post datetime values are converted to ISO strings.
+/// @pre value may be nested dict/list with datetime values.
+/// @}
+void _json_safe_value(void);
+
+/// @defgroup DashboardValidationPlugin "DashboardValidationPlugin"
+/// @{
+/// @brief Plugin for automated dashboard health analysis using LLMs.
+/// @}
+void DashboardValidationPlugin(void);
+
+/// @defgroup DocumentationPlugin "DocumentationPlugin"
+/// @{
+/// @brief Plugin for automated dataset documentation using LLMs.
+/// @}
+void DocumentationPlugin(void);
+
+/// @defgroup LLMAnalysisScheduler "LLMAnalysisScheduler"
+/// @{
+/// @brief Provides helper functions to schedule LLM-based validation tasks.
+/// @}
+void LLMAnalysisScheduler(void);
+
+/// @defgroup schedule_dashboard_validation "schedule_dashboard_validation"
+/// @{
+/// @brief Schedules a recurring dashboard validation task.
+/// @}
+void schedule_dashboard_validation(void);
+
+/// @defgroup _parse_cron "_parse_cron"
+/// @{
+/// @brief Basic cron parser placeholder.
+/// @}
+void _parse_cron(void);
+
+/// @defgroup LLMAnalysisService "LLMAnalysisService"
+/// @{
+/// @brief Services for LLM interaction and dashboard screenshots.
+/// @invariant Screenshots must be 1920px width and capture full page height.
+/// @}
+void LLMAnalysisService(void);
+
+/// @defgroup ScreenshotService "ScreenshotService"
+/// @{
+/// @brief Handles capturing screenshots of Superset dashboards.
+/// @}
+void ScreenshotService(void);
+
+/// @defgroup LLMClient "LLMClient"
+/// @{
+/// @brief Wrapper for LLM provider APIs.
+/// @}
+void LLMClient(void);
+
+/// @defgroup MaintenanceBannerPlugin "MaintenanceBannerPlugin"
+/// @{
+/// @brief TaskManager plugin for executing maintenance banner operations (start, end, end-all).
+/// @}
+void MaintenanceBannerPlugin(void);
+
+/// @defgroup MapperPluginModule "MapperPluginModule"
+/// @{
+/// @brief Plugin for dataset column mapping. Inherits PluginBase.
+/// @}
+void MapperPluginModule(void);
+
+/// @defgroup MapperPlugin "MapperPlugin"
+/// @{
+/// @brief Plugin for mapping dataset columns verbose names.
+/// @}
+void MapperPlugin(void);
+
+/// @defgroup MigrationPlugin "MigrationPlugin"
+/// @{
+/// @brief Orchestrates export, DB-mapping transformation, and import of Superset dashboards across environments.
+/// @invariant Dashboards must never be imported with unmapped/source DB connections to prevent data leaks or cross-environment pollution.
+/// @post Plugin metadata remains stable and migration execution preserves mapped-environment import guarantees.
+/// @pre Plugin loader can resolve infrastructure dependencies and execution requests provide validated migration context.
+/// @}
+void MigrationPlugin(void);
+
+/// @defgroup SearchPluginModule "SearchPluginModule"
+/// @{
+/// @brief Plugin for text search across datasets. Inherits PluginBase.
+/// @}
+void SearchPluginModule(void);
+
+/// @defgroup SearchPlugin "SearchPlugin"
+/// @{
+/// @brief Plugin for searching text patterns in Superset datasets.
+/// @}
+void SearchPlugin(void);
+
+/// @defgroup StoragePluginPackage "StoragePluginPackage"
+/// @{
+/// @}
+void StoragePluginPackage(void);
+
+/// @defgroup StoragePlugin "StoragePlugin"
+/// @{
+/// @brief Provides core filesystem operations for managing backups and repositories.
+/// @invariant All file operations must be restricted to the configured storage root.
+/// @}
+void StoragePlugin(void);
+
+/// @defgroup TranslatePluginPackage "TranslatePluginPackage"
+/// @{
+/// @}
+void TranslatePluginPackage(void);
+
+/// @defgroup TestClickHouseTimestampNormalization "TestClickHouseTimestampNormalization"
+/// @{
+/// @brief Verify Unix timestamp detection and conversion for ClickHouse Date columns.
+/// @}
+void TestClickHouseTimestampNormalization(void);
+
+/// @defgroup TestClickHouseInsertSqlGeneration "TestClickHouseInsertSqlGeneration"
+/// @{
+/// @brief Verify SQLGenerator produces valid ClickHouse INSERT SQL with normalized dates.
+/// @}
+void TestClickHouseInsertSqlGeneration(void);
+
+/// @defgroup TestClickHouseJoinVerification "TestClickHouseJoinVerification"
+/// @{
+/// @brief Verify the JOIN query SQL is syntactically correct for ClickHouse.
+/// @}
+void TestClickHouseJoinVerification(void);
+
+/// @defgroup TestOrchestratorInsertFlow "TestOrchestratorInsertFlow"
+/// @{
+/// @brief Verify the orchestrator's _generate_and_insert_sql produces correct SQL for ClickHouse.
+/// @}
+void TestOrchestratorInsertFlow(void);
+
+/// @defgroup TestClickHouseEndToEnd "TestClickHouseEndToEnd"
+/// @{
+/// @brief End-to-end test: generate SQL, verify structure, simulate execution.
+/// @}
+void TestClickHouseEndToEnd(void);
+
+/// @defgroup TestDictionaryLegacyHub "TestDictionaryLegacyHub"
+/// @{
+/// @brief Legacy test module — all tests migrated to domain-specific test files:
+/// @}
+void TestDictionaryLegacyHub(void);
+
+/// @defgroup TestDictionaryCorrection "TestDictionaryCorrection"
+/// @{
+/// @brief Validate InlineCorrectionService and dictionary correction flows.
+/// @}
+void TestDictionaryCorrection(void);
+
+/// @defgroup TestDictionaryCRUD "TestDictionaryCRUD"
+/// @{
+/// @brief Validate DictionaryCRUD and DictionaryEntryCRUD operations.
+/// @}
+void TestDictionaryCRUD(void);
+
+/// @defgroup TestDictionaryFilter "TestDictionaryFilter"
+/// @{
+/// @brief Validate DictionaryBatchFilter operations.
+/// @}
+void TestDictionaryFilter(void);
+
+/// @defgroup TestDictionaryImport "TestDictionaryImport"
+/// @{
+/// @brief Validate DictionaryImportExport operations.
+/// @}
+void TestDictionaryImport(void);
+
+/// @defgroup TestDictionaryPromptBuilder "TestDictionaryPromptBuilder"
+/// @{
+/// @brief Validate ContextAwarePromptBuilder operations: Jaccard similarity, context truncation, entry rendering.
+/// @}
+void TestDictionaryPromptBuilder(void);
+
+/// @defgroup TestDictionaryUtils "TestDictionaryUtils"
+/// @{
+/// @brief Validate utility functions: _normalize_term and _detect_delimiter.
+/// @}
+void TestDictionaryUtils(void);
+
+/// @defgroup LanguageDetectServiceTests "LanguageDetectServiceTests"
+/// @{
+/// @brief Unit tests for LanguageDetectService — local language detection via lingua.
+/// @}
+void LanguageDetectServiceTests(void);
+
+/// @defgroup test_detect_language_basic "test_detect_language_basic"
+/// @{
+/// @brief Verify core language detection for common languages.
+/// @}
+void test_detect_language_basic(void);
+
+/// @defgroup test_detect_language_edge_cases "test_detect_language_edge_cases"
+/// @{
+/// @}
+void test_detect_language_edge_cases(void);
+
+/// @defgroup test_batch_detect "test_batch_detect"
+/// @{
+/// @}
+void test_batch_detect(void);
+
+/// @defgroup test_build_detector "test_build_detector"
+/// @{
+/// @}
+void test_build_detector(void);
+
+/// @defgroup test_get_detector_cache "test_get_detector_cache"
+/// @{
+/// @}
+void test_get_detector_cache(void);
+
+/// @defgroup test_code_to_lang_mapping "test_code_to_lang_mapping"
+/// @{
+/// @}
+void test_code_to_lang_mapping(void);
+
+/// @defgroup fixtures "fixtures"
+/// @{
+/// @}
+void fixtures(void);
+
+/// @defgroup TestTextCleaner "TestTextCleaner"
+/// @{
+/// @brief Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.
+/// @}
+void TestTextCleaner(void);
+
+/// @defgroup TestTokenBudget "TestTokenBudget"
+/// @{
+/// @brief Verify estimate_token_budget contracts — safe batch sizing, auto-reduction, warning generation.
+/// @}
+void TestTokenBudget(void);
+
+/// @defgroup BatchInsertService "BatchInsertService"
+/// @{
+/// @brief Insert successful translation records into target table via Superset SQL Lab.
+/// @}
+void BatchInsertService(void);
+
+/// @defgroup insert_batch_to_target "insert_batch_to_target"
+/// @{
+/// @brief Insert successful records from a single batch into the target table.
+/// @}
+void insert_batch_to_target(void);
+
+/// @defgroup _fetch_batch_records "_fetch_batch_records"
+/// @{
+/// @}
+void _fetch_batch_records(void);
+
+/// @defgroup _build_target_columns "_build_target_columns"
+/// @{
+/// @}
+void _build_target_columns(void);
+
+/// @defgroup _build_context_keys "_build_context_keys"
+/// @{
+/// @}
+void _build_context_keys(void);
+
+/// @defgroup _build_insert_rows "_build_insert_rows"
+/// @{
+/// @}
+void _build_insert_rows(void);
+
+/// @defgroup _resolve_insert_backend "_resolve_insert_backend"
+/// @{
+/// @}
+void _resolve_insert_backend(void);
+
+/// @defgroup _generate_insert_sql "_generate_insert_sql"
+/// @{
+/// @}
+void _generate_insert_sql(void);
+
+/// @defgroup _execute_insert_sql "_execute_insert_sql"
+/// @{
+/// @}
+void _execute_insert_sql(void);
+
+/// @defgroup BatchProcessingService "BatchProcessingService"
+/// @{
+/// @brief Batch processing for translation: classify rows (same-language/cache/preview/LLM),
+/// @}
+void BatchProcessingService(void);
+
+/// @defgroup process_batch "process_batch"
+/// @{
+/// @brief Process a single batch: create record, classify rows, call LLM, persist.
+/// @post TranslationBatch and TranslationRecord rows are created.
+/// @pre job and batch_rows are valid.
+/// @}
+void process_batch(void);
+
+/// @defgroup AdaptiveBatchSizer "AdaptiveBatchSizer"
+/// @{
+/// @brief Adaptive batch sizing for LLM translation — splits source rows into variable-sized
+/// @}
+void AdaptiveBatchSizer(void);
+
+/// @defgroup resolve_provider_model "resolve_provider_model"
+/// @{
+/// @brief Resolve the LLM provider model name for token budget estimation.
+/// @post Returns model name string or None if resolution fails.
+/// @}
+void resolve_provider_model(void);
+
+/// @defgroup auto_size_batches "auto_size_batches"
+/// @{
+/// @brief Split source rows into variable-sized batches based on content length.
+/// @post Returns list of batches, each batch is a list of row dicts.
+/// @pre source_rows is non-empty. job has valid config.
+/// @}
+void auto_size_batches(void);
+
+/// @defgroup LanguageDetectService "LanguageDetectService"
+/// @{
+/// @brief Local language detection powered by lingua-language-detector (no LLM).
+/// @}
+void LanguageDetectService(void);
+
+/// @defgroup _detector_cache_key "_detector_cache_key"
+/// @{
+/// @brief Build a deterministic cache key from target languages list.
+/// @}
+void _detector_cache_key(void);
+
+/// @defgroup build_detector "build_detector"
+/// @{
+/// @brief Build a LanguageDetector restricted to target + common source languages.
+/// @}
+void build_detector(void);
+
+/// @defgroup get_detector "get_detector"
+/// @{
+/// @brief Get or create a cached detector for the given target languages.
+/// @}
+void get_detector(void);
+
+/// @defgroup detect_language "detect_language"
+/// @{
+/// @brief Detect the language of a single text string. Returns BCP-47 code or "und".
+/// @}
+void detect_language(void);
+
+/// @defgroup _character_block_fallback "_character_block_fallback"
+/// @{
+/// @brief When lingua returns "und", check if character-block dominance (e.g. Cyrillic)
+/// @}
+void _character_block_fallback(void);
+
+/// @defgroup batch_detect "batch_detect"
+/// @{
+/// @brief Detect language for multiple texts in batch. Builds detector if not provided.
+/// @}
+void batch_detect(void);
+
+/// @defgroup LLMTranslationService "LLMTranslationService"
+/// @{
+/// @brief LLM interaction for batch translation: call provider with retry, handle truncation
+/// @}
+void LLMTranslationService(void);
+
+/// @defgroup call_llm_for_batch "call_llm_for_batch"
+/// @{
+/// @brief Call LLM for a batch of rows requiring translation. Parse and persist results.
+/// @post Returns dict with successful/failed/skipped counts.
+/// @pre job has valid provider_id. batch_rows is non-empty.
+/// @}
+void call_llm_for_batch(void);
+
+/// @defgroup call_llm "call_llm"
+/// @{
+/// @brief Route to provider-specific LLM call implementation.
+/// @}
+void call_llm(void);
+
+/// @defgroup LLMHttpClient "LLMHttpClient"
+/// @{
+/// @brief HTTP client for OpenAI-compatible LLM API calls with rate-limit handling and
+/// @}
+void LLMHttpClient(void);
+
+/// @defgroup call_openai_compatible "call_openai_compatible"
+/// @{
+/// @brief Call OpenAI-compatible API with rate-limit handling and structured output fallback.
+/// @post Returns (response text, finish_reason).
+/// @pre Valid API endpoint, key, model, and prompt.
+/// @}
+void call_openai_compatible(void);
+
+/// @defgroup _do_http_request "_do_http_request"
+/// @{
+/// @}
+void _do_http_request(void);
+
+/// @defgroup _handle_response_format_fallback "_handle_response_format_fallback"
+/// @{
+/// @}
+void _handle_response_format_fallback(void);
+
+/// @defgroup LLMResponseParser "LLMResponseParser"
+/// @{
+/// @brief Parse LLM JSON response into per-row translations with support for markdown code
+/// @}
+void LLMResponseParser(void);
+
+/// @defgroup _recover_from_markdown "_recover_from_markdown"
+/// @{
+/// @}
+void _recover_from_markdown(void);
+
+/// @defgroup _recover_truncated_rows "_recover_truncated_rows"
+/// @{
+/// @}
+void _recover_truncated_rows(void);
+
+/// @defgroup RunExecutionService "RunExecutionService"
+/// @{
+/// @brief Full run lifecycle: prepare run, fetch source rows, filter new keys, orchestrate batches,
+/// @}
+void RunExecutionService(void);
+
+/// @defgroup RunSourceFetcher "RunSourceFetcher"
+/// @{
+/// @brief Fetch source rows for translation runs from Superset datasource or preview session.
+/// @}
+void RunSourceFetcher(void);
+
+/// @defgroup fetch_source_rows "fetch_source_rows"
+/// @{
+/// @brief Fetch source rows from Superset datasource or preview session fallback.
+/// @}
+void fetch_source_rows(void);
+
+/// @defgroup _extract_chart_data_rows "_extract_chart_data_rows"
+/// @{
+/// @}
+void _extract_chart_data_rows(void);
+
+/// @defgroup TextCleaner "TextCleaner"
+/// @{
+/// @brief Text cleaning utilities for the translation pipeline — whitespace normalization
+/// @}
+void TextCleaner(void);
+
+/// @defgroup normalize_whitespace "normalize_whitespace"
+/// @{
+/// @brief Collapse multiple spaces, tabs, and newlines into single spaces; trim leading/trailing
+/// @}
+void normalize_whitespace(void);
+
+/// @defgroup truncate_text "truncate_text"
+/// @{
+/// @brief Truncate text to max_length characters, appending "..." if truncation occurs.
+/// @post When len(text) <= max_length, returns text unchanged.
+/// @pre text is a string. max_length >= 0.
+/// @}
+void truncate_text(void);
+
+/// @defgroup clean_text "clean_text"
+/// @{
+/// @brief Combine whitespace normalization and truncation into one step.
+/// @}
+void clean_text(void);
+
+/// @defgroup estimate_token_budget "estimate_token_budget"
+/// @{
+/// @brief Calculate safe batch_size and max_tokens for LLM translation calls based on actual content length and model context window limits.
+/// @}
+void estimate_token_budget(void);
+
+/// @defgroup DEFAULT_CONTEXT_WINDOW "DEFAULT_CONTEXT_WINDOW"
+/// @{
+/// @}
+void DEFAULT_CONTEXT_WINDOW(void);
+
+/// @defgroup DEFAULT_MAX_OUTPUT_TOKENS "DEFAULT_MAX_OUTPUT_TOKENS"
+/// @{
+/// @}
+void DEFAULT_MAX_OUTPUT_TOKENS(void);
+
+/// @defgroup REASONING_OVERHEAD "REASONING_OVERHEAD"
+/// @{
+/// @}
+void REASONING_OVERHEAD(void);
+
+/// @defgroup PROVIDER_DEFAULTS "PROVIDER_DEFAULTS"
+/// @{
+/// @}
+void PROVIDER_DEFAULTS(void);
+
+/// @defgroup OUTPUT_PER_ROW_PER_LANG "OUTPUT_PER_ROW_PER_LANG"
+/// @{
+/// @}
+void OUTPUT_PER_ROW_PER_LANG(void);
+
+/// @defgroup JSON_OVERHEAD_PER_ROW "JSON_OVERHEAD_PER_ROW"
+/// @{
+/// @}
+void JSON_OVERHEAD_PER_ROW(void);
+
+/// @defgroup PROMPT_BASE_TOKENS "PROMPT_BASE_TOKENS"
+/// @{
+/// @}
+void PROMPT_BASE_TOKENS(void);
+
+/// @defgroup DICT_TOKENS_PER_ENTRY "DICT_TOKENS_PER_ENTRY"
+/// @{
+/// @}
+void DICT_TOKENS_PER_ENTRY(void);
+
+/// @defgroup DICT_TOKENS_MAX "DICT_TOKENS_MAX"
+/// @{
+/// @}
+void DICT_TOKENS_MAX(void);
+
+/// @defgroup CHARS_PER_TOKEN_MIXED "CHARS_PER_TOKEN_MIXED"
+/// @{
+/// @}
+void CHARS_PER_TOKEN_MIXED(void);
+
+/// @defgroup MIN_MAX_TOKENS "MIN_MAX_TOKENS"
+/// @{
+/// @}
+void MIN_MAX_TOKENS(void);
+
+/// @defgroup MAX_OUTPUT_HEADROOM "MAX_OUTPUT_HEADROOM"
+/// @{
+/// @}
+void MAX_OUTPUT_HEADROOM(void);
+
+/// @defgroup TranslationUtils "TranslationUtils"
+/// @{
+/// @brief Shared utility functions for the translation plugin — dictionary enforcement,
+/// @}
+void TranslationUtils(void);
+
+/// @defgroup _normalize_term "_normalize_term"
+/// @{
+/// @brief Normalize a term for case-insensitive unique constraint lookup.
+/// @}
+void _normalize_term(void);
+
+/// @defgroup _detect_delimiter "_detect_delimiter"
+/// @{
+/// @brief Detect the delimiter used in a CSV/TSV header line.
+/// @}
+void _detect_delimiter(void);
+
+/// @defgroup _enforce_dictionary "_enforce_dictionary"
+/// @{
+/// @brief Post-process LLM output: enforce dictionary term replacements.
+/// @post per_lang_values may be mutated to include forced dictionary replacements.
+/// @pre dict_matches is a list of dict entries with source_term/target_term.
+/// @}
+void _enforce_dictionary(void);
+
+/// @defgroup _compute_source_hash "_compute_source_hash"
+/// @{
+/// @brief Compute deterministic cache key for a source row.
+/// @}
+void _compute_source_hash(void);
+
+/// @defgroup _check_translation_cache "_check_translation_cache"
+/// @{
+/// @brief Look up a previously successful translation by source_hash.
+/// @}
+void _check_translation_cache(void);
+
+/// @defgroup _compute_key_hash "_compute_key_hash"
+/// @{
+/// @brief Compute a stable hash from source_data dict for matching preview edits.
+/// @}
+void _compute_key_hash(void);
+
+/// @defgroup estimate_row_tokens "estimate_row_tokens"
+/// @{
+/// @brief Estimate token count for a single source row including context fields.
+/// @post Returns estimated token count >= 1.
+/// @pre source_text is a string.
+/// @}
+void estimate_row_tokens(void);
+
+/// @defgroup DictionaryManagerModule "DictionaryManagerModule"
+/// @{
+/// @brief Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering.
+/// @post Dictionary and entry mutations are persisted with conflict detection.
+/// @pre Database session is open and valid.
+/// @}
+void DictionaryManagerModule(void);
+
+/// @defgroup DictionaryManager "DictionaryManager"
+/// @{
+/// @brief Facade for terminology dictionaries: delegates to DictionaryCRUD, DictionaryEntryCRUD, DictionaryImportExport, DictionaryBatchFilter, DictionaryCorrectionService.
+/// @post Dictionary and entry mutations are persisted with conflict detection.
+/// @pre Database session is open and valid.
+/// @}
+void DictionaryManager(void);
+
+/// @defgroup DictionaryCorrectionService "DictionaryCorrectionService"
+/// @{
+/// @brief Submit term corrections and bulk corrections to dictionaries with conflict detection.
+/// @}
+void DictionaryCorrectionService(void);
+
+/// @defgroup DictionaryCRUD "DictionaryCRUD"
+/// @{
+/// @brief CRUD operations for TerminologyDictionary records.
+/// @}
+void DictionaryCRUD(void);
+
+/// @defgroup DictionaryEntryCRUD "DictionaryEntryCRUD"
+/// @{
+/// @brief CRUD operations for DictionaryEntry records.
+/// @}
+void DictionaryEntryCRUD(void);
+
+/// @defgroup DictionaryBatchFilter "DictionaryBatchFilter"
+/// @{
+/// @brief Scan batch texts for case-insensitive, word-boundary-aware matches against dictionaries.
+/// @}
+void DictionaryBatchFilter(void);
+
+/// @defgroup DictionaryImportExport "DictionaryImportExport"
+/// @{
+/// @brief Import/export entries as CSV/TSV with conflict detection, and migration of old entries.
+/// @}
+void DictionaryImportExport(void);
+
+/// @defgroup _validate_bcp47 "_validate_bcp47"
+/// @{
+/// @brief Validate that a language tag is a non-empty BCP-47 string.
+/// @}
+void _validate_bcp47(void);
+
+/// @defgroup TranslationEventLog "TranslationEventLog"
+/// @{
+/// @brief Structured event logging for translation operations with terminal event invariant enforcement.
+/// @invariant Exactly one run_started + exactly one terminal event per non-null run_id.
+/// @post Events are persisted immutably; terminal events enforce exactly-one invariant per run.
+/// @pre Database session is open and valid.
+/// @}
+void TranslationEventLog(void);
+
+/// @defgroup TranslationExecutor "TranslationExecutor"
+/// @{
+/// @brief Process translation in batches: fetch source rows, call LLM, persist TranslationBatch
+/// @}
+void TranslationExecutor(void);
+
+/// @defgroup TranslationMetrics "TranslationMetrics"
+/// @{
+/// @brief Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting.
+/// @post Metrics are aggregated and returned; no side effects.
+/// @pre Database session is open.
+/// @}
+void TranslationMetrics(void);
+
+/// @defgroup TranslationOrchestrator "TranslationOrchestrator"
+/// @{
+/// @brief Run lifecycle coordination: validate preconditions, dispatch executor, generate SQL, submit to Superset, record events.
+/// @invariant State transitions: PENDING -> RUNNING -> COMPLETED|FAILED|CANCELLED. Exactly one terminal event per run.
+/// @post Translation run is executed, SQL generated and submitted, events recorded.
+/// @pre Valid job and accepted preview (for manual runs). Superset and LLM are reachable.
+/// @}
+void TranslationOrchestrator(void);
+
+/// @defgroup TranslationResultAggregator "TranslationResultAggregator"
+/// @{
+/// @brief Query translation run status, records, and history.
+/// @post Returns structured run data with pagination.
+/// @pre Database session is available.
+/// @}
+void TranslationResultAggregator(void);
+
+/// @defgroup orchestrator_cancel "orchestrator_cancel"
+/// @{
+/// @brief Cancel and retry-insert operations for translation runs.
+/// @}
+void orchestrator_cancel(void);
+
+/// @defgroup orchestrator_config "orchestrator_config"
+/// @{
+/// @brief Config hash and dictionary snapshot hash utilities for translation planning.
+/// @}
+void orchestrator_config(void);
+
+/// @defgroup TranslationExecutionEngine "TranslationExecutionEngine"
+/// @{
+/// @brief Execute translation runs: dispatch executor, manage completion and failure paths.
+/// @post Run is executed with SQL generated; events recorded.
+/// @pre Database session and config manager are available. Run is in valid state.
+/// @}
+void TranslationExecutionEngine(void);
+
+/// @defgroup update_language_stats "update_language_stats"
+/// @{
+/// @brief Aggregate TranslationLanguage entries by language_code and update TranslationRunLanguageStats.
+/// @}
+void update_language_stats(void);
+
+/// @defgroup TranslationPlanner "TranslationPlanner"
+/// @{
+/// @brief Handle translation run planning: validation, config hashing, dictionary snapshot.
+/// @post TranslationRun is planned with hashes and config snapshot; events recorded.
+/// @pre Database session and config manager are available.
+/// @}
+void TranslationPlanner(void);
+
+/// @defgroup orchestrator_query "orchestrator_query"
+/// @{
+/// @brief Query translation run records and history with pagination.
+/// @}
+void orchestrator_query(void);
+
+/// @defgroup TranslationRunRetryManager "TranslationRunRetryManager"
+/// @{
+/// @brief Manage retry of translation run batches.
+/// @post Retried batches are re-executed.
+/// @pre Database session and config manager are available.
+/// @}
+void TranslationRunRetryManager(void);
+
+/// @defgroup orchestrator_run_completion "orchestrator_run_completion"
+/// @{
+/// @brief Post-execution run completion handlers: cancelled, success-with-insert, and failure paths.
+/// @}
+void orchestrator_run_completion(void);
+
+/// @defgroup TranslationStageRunner "TranslationStageRunner"
+/// @{
+/// @brief Coordinate translation run execution, retry, and cancellation via delegated components.
+/// @post Run is executed; events recorded.
+/// @pre Database session and config manager are available. Run is in valid state.
+/// @}
+void TranslationStageRunner(void);
+
+/// @defgroup SQLInsertService "SQLInsertService"
+/// @{
+/// @brief Generate INSERT SQL from translation records and submit to Superset SQL Lab.
+/// @post SQL is generated and submitted to Superset; returns execution result.
+/// @pre Job has target table configured. Run has successful records.
+/// @}
+void SQLInsertService(void);
+
+/// @defgroup orchestrator_sql_rows "orchestrator_sql_rows"
+/// @{
+/// @brief Column and row building utilities for SQL insertion in translate plugin.
+/// @}
+void orchestrator_sql_rows(void);
+
+/// @defgroup build_columns "build_columns"
+/// @{
+/// @brief Build list of target columns for SQL INSERT from job configuration.
+/// @}
+void build_columns(void);
+
+/// @defgroup build_context_keys "build_context_keys"
+/// @{
+/// @brief Build list of context keys for SQL row data.
+/// @}
+void build_context_keys(void);
+
+/// @defgroup build_rows "build_rows"
+/// @{
+/// @brief Build row data for SQL INSERT with per-language expansion.
+/// @}
+void build_rows(void);
+
+/// @defgroup validate_job_preconditions "validate_job_preconditions"
+/// @{
+/// @brief Validate preconditions before starting a translation run.
+/// @post Raises ValueError if any precondition fails.
+/// @pre Job exists and db session is valid.
+/// @}
+void validate_job_preconditions(void);
+
+/// @defgroup TranslatePlugin "TranslatePlugin"
+/// @{
+/// @brief TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.
+/// @}
+void TranslatePlugin(void);
+
+/// @defgroup DEFAULT_EXECUTION_PROMPT_TEMPLATE "DEFAULT_EXECUTION_PROMPT_TEMPLATE"
+/// @{
+/// @brief Default LLM prompt template for full execution (batch translation).
+/// @}
+void DEFAULT_EXECUTION_PROMPT_TEMPLATE(void);
+
+/// @defgroup DEFAULT_PREVIEW_PROMPT_TEMPLATE "DEFAULT_PREVIEW_PROMPT_TEMPLATE"
+/// @{
+/// @brief Default LLM prompt template for preview (sample translation).
+/// @}
+void DEFAULT_PREVIEW_PROMPT_TEMPLATE(void);
+
+/// @defgroup PreviewExecutor "PreviewExecutor"
+/// @{
+/// @brief Fetch sample data from Superset and call LLM provider for preview.
+/// @post Sample rows fetched, LLM called.
+/// @pre Database session, config manager, and Superset client are available.
+/// @}
+void PreviewExecutor(void);
+
+/// @defgroup PreviewPromptBuilder "PreviewPromptBuilder"
+/// @{
+/// @brief Build LLM prompts for preview sessions including dictionary glossary and row context.
+/// @}
+void PreviewPromptBuilder(void);
+
+/// @defgroup preview_prompt_helpers "preview_prompt_helpers"
+/// @{
+/// @brief Token estimation metadata and budget helpers for preview prompt building.
+/// @}
+void preview_prompt_helpers(void);
+
+/// @defgroup estimate_token_budget_for_rows "estimate_token_budget_for_rows"
+/// @{
+/// @brief Check token budget and optionally truncate source rows for preview.
+/// @post Returns adjusted source_rows, actual_row_count, and token_budget dict.
+/// @}
+void estimate_token_budget_for_rows(void);
+
+/// @defgroup compute_build_token_metadata "compute_build_token_metadata"
+/// @{
+/// @brief Compute token estimation metadata for prompt builder return dict.
+/// @post Returns prompt, row_meta, target_languages, cost estimates, and cost_warning.
+/// @}
+void compute_build_token_metadata(void);
+
+/// @defgroup preview_response_parser "preview_response_parser"
+/// @{
+/// @brief Parse LLM JSON responses and Superset data; compute config/dict hashes for preview.
+/// @}
+void preview_response_parser(void);
+
+/// @defgroup parse_llm_response "parse_llm_response"
+/// @{
+/// @brief Parse LLM JSON response into structured translations dict with per-language support.
+/// @post Returns dict mapping row_id -> {detected_source_language, lang_code: translation, ...}.
+/// @pre response_text is a valid JSON string (possibly wrapped in markdown code block).
+/// @}
+void parse_llm_response(void);
+
+/// @defgroup extract_data_rows "extract_data_rows"
+/// @{
+/// @brief Extract data rows from Superset chart data API response.
+/// @}
+void extract_data_rows(void);
+
+/// @defgroup compute_config_hash "compute_config_hash"
+/// @{
+/// @brief Compute a deterministic hash of job configuration for snapshot comparison.
+/// @}
+void compute_config_hash(void);
+
+/// @defgroup compute_dict_snapshot_hash "compute_dict_snapshot_hash"
+/// @{
+/// @brief Compute a hash of dictionary state for snapshot comparison.
+/// @}
+void compute_dict_snapshot_hash(void);
+
+/// @defgroup PreviewSessionManager "PreviewSessionManager"
+/// @{
+/// @brief Manage preview session row-level actions: approve/edit/reject rows.
+/// @}
+void PreviewSessionManager(void);
+
+/// @defgroup preview_session_ops "preview_session_ops"
+/// @{
+/// @brief Preview session lifecycle operations: accept and query preview sessions.
+/// @}
+void preview_session_ops(void);
+
+/// @defgroup get_preview_session "get_preview_session"
+/// @{
+/// @brief Get the latest preview session for a job with its records.
+/// @}
+void get_preview_session(void);
+
+/// @defgroup preview_session_serializer "preview_session_serializer"
+/// @{
+/// @brief Serialization and action helpers for preview sessions: record serialization and per-row approve/reject/edit actions.
+/// @}
+void preview_session_serializer(void);
+
+/// @defgroup serialize_preview_record "serialize_preview_record"
+/// @{
+/// @brief Serialize a TranslationPreviewRecord to a response dict.
+/// @}
+void serialize_preview_record(void);
+
+/// @defgroup apply_language_action "apply_language_action"
+/// @{
+/// @brief Apply approve/reject/edit action to a TranslationPreviewLanguage entry.
+/// @}
+void apply_language_action(void);
+
+/// @defgroup apply_record_action "apply_record_action"
+/// @{
+/// @brief Apply approve/reject/edit action to a TranslationPreviewRecord and its language entries.
+/// @}
+void apply_record_action(void);
+
+/// @defgroup TokenEstimator "TokenEstimator"
+/// @{
+/// @brief Estimate token counts and costs for LLM translation operations.
+/// @}
+void TokenEstimator(void);
+
+/// @defgroup ContextAwarePromptBuilder "ContextAwarePromptBuilder"
+/// @{
+/// @brief Pure-function prompt builder that enhances dictionary entries with context annotations.
+/// @}
+void ContextAwarePromptBuilder(void);
+
+/// @defgroup TranslationScheduler "TranslationScheduler"
+/// @{
+/// @brief Manage TranslationSchedule rows and register them with core SchedulerService.
+/// @post TranslationSchedule CRUD persisted; APScheduler jobs registered/updated/removed.
+/// @pre Database session and SchedulerService are available.
+/// @}
+void TranslationScheduler(void);
+
+/// @defgroup execute_scheduled_translation "execute_scheduled_translation"
+/// @{
+/// @brief APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.
+/// @post Translation run created and executed if no concurrent run exists.
+/// @pre schedule_id is valid.
+/// @}
+void execute_scheduled_translation(void);
+
+/// @defgroup TranslateJobService "TranslateJobService"
+/// @{
+/// @brief Service layer for translation job CRUD with datasource column validation and database dialect detection.
+/// @post Translation jobs are created/updated/deleted with column validation and dialect caching.
+/// @pre Database session and config manager are available.
+/// @}
+void TranslateJobService(void);
+
+/// @defgroup BulkFindReplaceService "BulkFindReplaceService"
+/// @{
+/// @brief Service for bulk find-and-replace operations on translated values.
+/// @}
+void BulkFindReplaceService(void);
+
+/// @defgroup DatasourceMetadataService "DatasourceMetadataService"
+/// @{
+/// @brief Fetch datasource column metadata and database dialect from Superset.
+/// @post Datasource metadata is fetched with column details and normalized dialect.
+/// @pre Database session and config manager are available.
+/// @}
+void DatasourceMetadataService(void);
+
+/// @defgroup get_dialect_from_database "get_dialect_from_database"
+/// @{
+/// @brief Extract normalized dialect string from a Superset database record.
+/// @}
+void get_dialect_from_database(void);
+
+/// @defgroup fetch_datasource_metadata "fetch_datasource_metadata"
+/// @{
+/// @brief Fetch datasource columns and database dialect from Superset.
+/// @}
+void fetch_datasource_metadata(void);
+
+/// @defgroup detect_virtual_columns "detect_virtual_columns"
+/// @{
+/// @brief Identify virtual (calculated) columns from column metadata.
+/// @}
+void detect_virtual_columns(void);
+
+/// @defgroup InlineCorrectionService "InlineCorrectionService"
+/// @{
+/// @brief Service for inline editing translated values and submitting corrections to dictionaries.
+/// @post Inline edits applied with optional dictionary submission.
+/// @pre Database session is available.
+/// @}
+void InlineCorrectionService(void);
+
+/// @defgroup TargetSchemaValidation "TargetSchemaValidation"
+/// @{
+/// @brief Проверка схемы целевой таблицы: запрос колонок через Superset SQL Lab,
+/// @}
+void TargetSchemaValidation(void);
+
+/// @defgroup _build_expected_columns "_build_expected_columns"
+/// @{
+/// @brief Собирает список ожидаемых колонок по конфигурации column mapping.
+/// @}
+void _build_expected_columns(void);
+
+/// @defgroup _extract_columns_from_rows "_extract_columns_from_rows"
+/// @{
+/// @brief Извлекает список колонок таблицы из data-строк результата SQL Lab.
+/// @}
+void _extract_columns_from_rows(void);
+
+/// @defgroup _parse_sqllab_result "_parse_sqllab_result"
+/// @{
+/// @brief Извлекает data-строки из ответа Superset SQL Lab.
+/// @}
+void _parse_sqllab_result(void);
+
+/// @defgroup validate_target_table_schema "validate_target_table_schema"
+/// @{
+/// @brief Основная функция: проверяет схему целевой таблицы через Superset SQL Lab.
+/// @post Возвращает TargetSchemaValidationResponse с diff-анализом.
+/// @pre Superset окружение и target_database_id валидны.
+/// @}
+void validate_target_table_schema(void);
+
+/// @defgroup ServiceUtils "ServiceUtils"
+/// @{
+/// @brief Utility functions for the translate service layer.
+/// @}
+void ServiceUtils(void);
+
+/// @defgroup _extract_dialect "_extract_dialect"
+/// @{
+/// @brief Extract database dialect from Superset backend URI.
+/// @}
+void _extract_dialect(void);
+
+/// @defgroup job_to_response "job_to_response"
+/// @{
+/// @brief Convert a TranslationJob ORM model to a TranslateJobResponse schema with dictionary_ids.
+/// @}
+void job_to_response(void);
+
+/// @defgroup SQLGenerator "SQLGenerator"
+/// @{
+/// @brief Dialect-aware safe SQL generation for INSERT/UPSERT operations.
+/// @post Returns safe SQL strings for the target dialect.
+/// @pre Job has target_schema and target_table configured. Dialect is one of supported SUPPORTED_DIALECTS.
+/// @}
+void SQLGenerator(void);
+
+/// @defgroup _normalize_timestamp_value "_normalize_timestamp_value"
+/// @{
+/// @brief Detect Unix timestamp strings (seconds or millis) and convert to 'YYYY-MM-DD' for Date columns.
+/// @}
+void _normalize_timestamp_value(void);
+
+/// @defgroup _quote_identifier "_quote_identifier"
+/// @{
+/// @brief Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.
+/// @post Returns safely quoted identifier.
+/// @pre identifier is a non-empty string.
+/// @}
+void _quote_identifier(void);
+
+/// @defgroup _encode_sql_value "_encode_sql_value"
+/// @{
+/// @brief Encode a Python value into a SQL-safe literal for INSERT VALUES, with ClickHouse timestamp normalization.
+/// @}
+void _encode_sql_value(void);
+
+/// @defgroup _build_values_clause "_build_values_clause"
+/// @{
+/// @brief Build a VALUES clause for multiple rows with per-column value encoding and dialect-aware quoting.
+/// @}
+void _build_values_clause(void);
+
+/// @defgroup generate_insert_sql "generate_insert_sql"
+/// @{
+/// @brief Generate a dialect-aware plain INSERT SQL statement for the given table, columns, and rows.
+/// @}
+void generate_insert_sql(void);
+
+/// @defgroup generate_upsert_sql "generate_upsert_sql"
+/// @{
+/// @brief Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.
+/// @post Returns UPSERT SQL string or raises ValueError.
+/// @pre dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.
+/// @}
+void generate_upsert_sql(void);
+
+/// @defgroup SupersetSqlLabExecutor "SupersetSqlLabExecutor"
+/// @{
+/// @brief Submit SQL to Superset SQL Lab API and poll execution status.
+/// @post SQL is submitted to Superset SQL Lab; execution reference is returned.
+/// @pre Valid Superset environment configuration and authenticated client.
+/// @}
+void SupersetSqlLabExecutor(void);
+
+/// @defgroup SchemasPackage "SchemasPackage"
+/// @{
+/// @brief API schema package root.
+/// @}
+void SchemasPackage(void);
+
+/// @defgroup TestSettingsAndHealthSchemas "TestSettingsAndHealthSchemas"
+/// @{
+/// @brief Regression tests for settings and health schema contracts updated in 026 fix batch.
+/// @}
+void TestSettingsAndHealthSchemas(void);
+
+/// @defgroup test_validation_policy_create_accepts_structured_custom_channels "test_validation_policy_create_accepts_structured_custom_channels"
+/// @{
+/// @brief Ensure policy schema accepts structured custom channel objects with type/target fields.
+/// @}
+void test_validation_policy_create_accepts_structured_custom_channels(void);
+
+/// @defgroup test_validation_policy_create_rejects_legacy_string_custom_channels "test_validation_policy_create_rejects_legacy_string_custom_channels"
+/// @{
+/// @brief Ensure legacy list[str] custom channel payload is rejected by typed channel contract.
+/// @}
+void test_validation_policy_create_rejects_legacy_string_custom_channels(void);
+
+/// @defgroup test_dashboard_health_item_status_accepts_only_whitelisted_values "test_dashboard_health_item_status_accepts_only_whitelisted_values"
+/// @{
+/// @brief Verify strict grouped regex only accepts PASS/WARN/FAIL/UNKNOWN exact statuses.
+/// @}
+void test_dashboard_health_item_status_accepts_only_whitelisted_values(void);
+
+/// @defgroup AuthSchemas "AuthSchemas"
+/// @{
+/// @brief Pydantic schemas for authentication requests and responses.
+/// @invariant Sensitive fields like password must not be included in response schemas.
+/// @}
+void AuthSchemas(void);
+
+/// @defgroup Token "Token"
+/// @{
+/// @brief Represents a JWT access token response.
+/// @}
+void Token(void);
+
+/// @defgroup TokenData "TokenData"
+/// @{
+/// @brief Represents the data encoded in a JWT token.
+/// @}
+void TokenData(void);
+
+/// @defgroup PermissionSchema "PermissionSchema"
+/// @{
+/// @brief Represents a permission in API responses.
+/// @}
+void PermissionSchema(void);
+
+/// @defgroup RoleSchema "RoleSchema"
+/// @{
+/// @brief Represents a role in API responses.
+/// @}
+void RoleSchema(void);
+
+/// @defgroup RoleCreate "RoleCreate"
+/// @{
+/// @brief Schema for creating a new role.
+/// @}
+void RoleCreate(void);
+
+/// @defgroup RoleUpdate "RoleUpdate"
+/// @{
+/// @brief Schema for updating an existing role.
+/// @}
+void RoleUpdate(void);
+
+/// @defgroup ADGroupMappingSchema "ADGroupMappingSchema"
+/// @{
+/// @brief Represents an AD Group to Role mapping in API responses.
+/// @}
+void ADGroupMappingSchema(void);
+
+/// @defgroup ADGroupMappingCreate "ADGroupMappingCreate"
+/// @{
+/// @brief Schema for creating an AD Group mapping.
+/// @}
+void ADGroupMappingCreate(void);
+
+/// @defgroup UserBase "UserBase"
+/// @{
+/// @brief Base schema for user data.
+/// @}
+void UserBase(void);
+
+/// @defgroup UserCreate "UserCreate"
+/// @{
+/// @brief Schema for creating a new user.
+/// @}
+void UserCreate(void);
+
+/// @defgroup UserUpdate "UserUpdate"
+/// @{
+/// @brief Schema for updating an existing user.
+/// @}
+void UserUpdate(void);
+
+/// @defgroup User "User"
+/// @{
+/// @brief Schema for user data in API responses.
+/// @}
+void User(void);
+
+/// @defgroup DatasetReviewSchemas "DatasetReviewSchemas"
+/// @{
+/// @brief Thin facade re-exporting all dataset review API schemas from decomposed sub-modules.
+/// @}
+void DatasetReviewSchemas(void);
+
+/// @defgroup DatasetReviewSchemaComposites "DatasetReviewSchemaComposites"
+/// @{
+/// @brief Composite Pydantic DTOs for clarification, preview, run context, and session summary/detail responses.
+/// @}
+void DatasetReviewSchemaComposites(void);
+
+/// @defgroup ClarificationOptionDto "ClarificationOptionDto"
+/// @{
+/// @brief Clarification option DTO.
+/// @}
+void ClarificationOptionDto(void);
+
+/// @defgroup ClarificationAnswerDto "ClarificationAnswerDto"
+/// @{
+/// @brief Clarification answer DTO with feedback.
+/// @}
+void ClarificationAnswerDto(void);
+
+/// @defgroup ClarificationQuestionDto "ClarificationQuestionDto"
+/// @{
+/// @brief Clarification question DTO with nested options and answer.
+/// @}
+void ClarificationQuestionDto(void);
+
+/// @defgroup ClarificationSessionDto "ClarificationSessionDto"
+/// @{
+/// @brief Clarification session DTO with nested questions.
+/// @}
+void ClarificationSessionDto(void);
+
+/// @defgroup CompiledPreviewDto "CompiledPreviewDto"
+/// @{
+/// @brief Compiled preview DTO with fingerprint and session version.
+/// @}
+void CompiledPreviewDto(void);
+
+/// @defgroup DatasetRunContextDto "DatasetRunContextDto"
+/// @{
+/// @brief Run context DTO with launch audit data and session version.
+/// @}
+void DatasetRunContextDto(void);
+
+/// @defgroup SessionSummary "SessionSummary"
+/// @{
+/// @brief Lightweight session summary DTO for list responses.
+/// @}
+void SessionSummary(void);
+
+/// @defgroup SessionDetail "SessionDetail"
+/// @{
+/// @brief Full session detail DTO with all nested aggregates for detail views.
+/// @}
+void SessionDetail(void);
+
+/// @defgroup DatasetReviewSchemaDtos "DatasetReviewSchemaDtos"
+/// @{
+/// @brief Pydantic DTOs for session, profile, findings, collaborators, and semantic field API payloads.
+/// @}
+void DatasetReviewSchemaDtos(void);
+
+/// @defgroup SessionCollaboratorDto "SessionCollaboratorDto"
+/// @{
+/// @brief Collaborator DTO for session access control.
+/// @}
+void SessionCollaboratorDto(void);
+
+/// @defgroup DatasetProfileDto "DatasetProfileDto"
+/// @{
+/// @brief Dataset profile DTO with business summary and confidence metadata.
+/// @}
+void DatasetProfileDto(void);
+
+/// @defgroup ValidationFindingDto "ValidationFindingDto"
+/// @{
+/// @brief Validation finding DTO with resolution tracking.
+/// @}
+void ValidationFindingDto(void);
+
+/// @defgroup SemanticSourceDto "SemanticSourceDto"
+/// @{
+/// @brief Semantic source DTO with trust level and status.
+/// @}
+void SemanticSourceDto(void);
+
+/// @defgroup SemanticCandidateDto "SemanticCandidateDto"
+/// @{
+/// @brief Semantic candidate DTO with match type and confidence score.
+/// @}
+void SemanticCandidateDto(void);
+
+/// @defgroup SemanticFieldEntryDto "SemanticFieldEntryDto"
+/// @{
+/// @brief Semantic field entry DTO with nested candidates and session version.
+/// @}
+void SemanticFieldEntryDto(void);
+
+/// @defgroup ImportedFilterDto "ImportedFilterDto"
+/// @{
+/// @brief Imported filter DTO with confidence and recovery status.
+/// @}
+void ImportedFilterDto(void);
+
+/// @defgroup TemplateVariableDto "TemplateVariableDto"
+/// @{
+/// @brief Template variable DTO with mapping status.
+/// @}
+void TemplateVariableDto(void);
+
+/// @defgroup ExecutionMappingDto "ExecutionMappingDto"
+/// @{
+/// @brief Execution mapping DTO with approval state and session version.
+/// @}
+void ExecutionMappingDto(void);
+
+/// @defgroup HealthSchemas "HealthSchemas"
+/// @{
+/// @brief Pydantic schemas for dashboard health summary.
+/// @}
+void HealthSchemas(void);
+
+/// @defgroup DashboardHealthItem "DashboardHealthItem"
+/// @{
+/// @brief Represents the latest health status of a single dashboard.
+/// @}
+void DashboardHealthItem(void);
+
+/// @defgroup HealthSummaryResponse "HealthSummaryResponse"
+/// @{
+/// @brief Aggregated health summary for all dashboards.
+/// @}
+void HealthSummaryResponse(void);
+
+/// @defgroup ProfileSchemas "ProfileSchemas"
+/// @{
+/// @brief Defines API schemas for profile preference persistence, security read-only snapshot, and Superset account lookup.
+/// @invariant Schema shapes stay stable for profile UI states and backend preference contracts.
+/// @}
+void ProfileSchemas(void);
+
+/// @defgroup ProfilePermissionState "ProfilePermissionState"
+/// @{
+/// @brief Represents one permission badge state for profile read-only security view.
+/// @}
+void ProfilePermissionState(void);
+
+/// @defgroup ProfileSecuritySummary "ProfileSecuritySummary"
+/// @{
+/// @brief Read-only security and access snapshot for current user.
+/// @}
+void ProfileSecuritySummary(void);
+
+/// @defgroup ProfilePreference "ProfilePreference"
+/// @{
+/// @brief Represents persisted profile preference for a single authenticated user.
+/// @}
+void ProfilePreference(void);
+
+/// @defgroup ProfilePreferenceUpdateRequest "ProfilePreferenceUpdateRequest"
+/// @{
+/// @brief Request payload for updating current user's profile settings.
+/// @}
+void ProfilePreferenceUpdateRequest(void);
+
+/// @defgroup ProfilePreferenceResponse "ProfilePreferenceResponse"
+/// @{
+/// @brief Response envelope for profile preference read/update endpoints.
+/// @}
+void ProfilePreferenceResponse(void);
+
+/// @defgroup SupersetAccountLookupRequest "SupersetAccountLookupRequest"
+/// @{
+/// @brief Query contract for Superset account lookup by selected environment.
+/// @}
+void SupersetAccountLookupRequest(void);
+
+/// @defgroup SupersetAccountCandidate "SupersetAccountCandidate"
+/// @{
+/// @brief Canonical account candidate projected from Superset users payload.
+/// @}
+void SupersetAccountCandidate(void);
+
+/// @defgroup SupersetAccountLookupResponse "SupersetAccountLookupResponse"
+/// @{
+/// @brief Response envelope for Superset account lookup (success or degraded mode).
+/// @}
+void SupersetAccountLookupResponse(void);
+
+/// @defgroup SettingsSchemas "SettingsSchemas"
+/// @{
+/// @brief Pydantic schemas for application settings and automation policies.
+/// @}
+void SettingsSchemas(void);
+
+/// @defgroup NotificationChannel "NotificationChannel"
+/// @{
+/// @brief Structured notification channel definition for policy-level custom routing.
+/// @}
+void NotificationChannel(void);
+
+/// @defgroup ValidationPolicyBase "ValidationPolicyBase"
+/// @{
+/// @brief Base schema for validation policy data.
+/// @}
+void ValidationPolicyBase(void);
+
+/// @defgroup ValidationPolicyCreate "ValidationPolicyCreate"
+/// @{
+/// @brief Schema for creating a new validation policy.
+/// @}
+void ValidationPolicyCreate(void);
+
+/// @defgroup ValidationPolicyUpdate "ValidationPolicyUpdate"
+/// @{
+/// @brief Schema for updating an existing validation policy.
+/// @}
+void ValidationPolicyUpdate(void);
+
+/// @defgroup ValidationPolicyResponse "ValidationPolicyResponse"
+/// @{
+/// @brief Schema for validation policy response data.
+/// @}
+void ValidationPolicyResponse(void);
+
+/// @defgroup TranslationScheduleItem "TranslationScheduleItem"
+/// @{
+/// @brief Response schema for a translation schedule item with joined job name.
+/// @}
+void TranslationScheduleItem(void);
+
+/// @defgroup TranslateSchemas "TranslateSchemas"
+/// @{
+/// @brief Pydantic v2 schemas for translation API request/response serialization.
+/// @}
+void TranslateSchemas(void);
+
+/// @defgroup TranslateJobCreate "TranslateJobCreate"
+/// @{
+/// @brief Schema for creating a new translation job.
+/// @}
+void TranslateJobCreate(void);
+
+/// @defgroup TranslateJobUpdate "TranslateJobUpdate"
+/// @{
+/// @brief Schema for updating an existing translation job.
+/// @}
+void TranslateJobUpdate(void);
+
+/// @defgroup TranslateJobResponse "TranslateJobResponse"
+/// @{
+/// @brief Schema for translation job API responses.
+/// @}
+void TranslateJobResponse(void);
+
+/// @defgroup DatasourceColumnResponse "DatasourceColumnResponse"
+/// @{
+/// @brief Schema for datasource column metadata response.
+/// @}
+void DatasourceColumnResponse(void);
+
+/// @defgroup DatasourceColumnsResponse "DatasourceColumnsResponse"
+/// @{
+/// @brief Schema for datasource columns endpoint response.
+/// @}
+void DatasourceColumnsResponse(void);
+
+/// @defgroup DuplicateJobResponse "DuplicateJobResponse"
+/// @{
+/// @brief Schema for duplicate job response.
+/// @}
+void DuplicateJobResponse(void);
+
+/// @defgroup DictionaryCreate "DictionaryCreate"
+/// @{
+/// @brief Schema for creating a new terminology dictionary.
+/// @}
+void DictionaryCreate(void);
+
+/// @defgroup DictionaryImport "DictionaryImport"
+/// @{
+/// @brief Schema for importing entries into a terminology dictionary.
+/// @}
+void DictionaryImport(void);
+
+/// @defgroup DictionaryResponse "DictionaryResponse"
+/// @{
+/// @brief Schema for terminology dictionary API responses.
+/// @}
+void DictionaryResponse(void);
+
+/// @defgroup DictionaryEntryCreate "DictionaryEntryCreate"
+/// @{
+/// @brief Schema for adding/editing a dictionary entry with language pair support.
+/// @}
+void DictionaryEntryCreate(void);
+
+/// @defgroup DictionaryEntryResponse "DictionaryEntryResponse"
+/// @{
+/// @brief Schema for dictionary entry API responses.
+/// @}
+void DictionaryEntryResponse(void);
+
+/// @defgroup DictionaryImportResult "DictionaryImportResult"
+/// @{
+/// @brief Schema for dictionary import result.
+/// @}
+void DictionaryImportResult(void);
+
+/// @defgroup PreviewRequest "PreviewRequest"
+/// @{
+/// @brief Schema for triggering a translation preview.
+/// @}
+void PreviewRequest(void);
+
+/// @defgroup PreviewRowUpdate "PreviewRowUpdate"
+/// @{
+/// @brief Schema for approving/editing/rejecting a preview row.
+/// @}
+void PreviewRowUpdate(void);
+
+/// @defgroup PreviewAcceptResponse "PreviewAcceptResponse"
+/// @{
+/// @brief Schema for preview accept response.
+/// @}
+void PreviewAcceptResponse(void);
+
+/// @defgroup CostEstimate "CostEstimate"
+/// @{
+/// @brief Schema for cost estimation in preview response.
+/// @}
+void CostEstimate(void);
+
+/// @defgroup TermCorrectionSubmit "TermCorrectionSubmit"
+/// @{
+/// @brief Schema for submitting a term correction in a translation preview.
+/// @}
+void TermCorrectionSubmit(void);
+
+/// @defgroup TermCorrectionBulkSubmit "TermCorrectionBulkSubmit"
+/// @{
+/// @brief Schema for submitting multiple term corrections atomically.
+/// @}
+void TermCorrectionBulkSubmit(void);
+
+/// @defgroup CorrectionConflictResult "CorrectionConflictResult"
+/// @{
+/// @brief Schema for reporting conflicts in correction submission.
+/// @}
+void CorrectionConflictResult(void);
+
+/// @defgroup CorrectionSubmitResponse "CorrectionSubmitResponse"
+/// @{
+/// @brief Schema for correction submission response.
+/// @}
+void CorrectionSubmitResponse(void);
+
+/// @defgroup ScheduleResponse "ScheduleResponse"
+/// @{
+/// @brief Schema for schedule API responses.
+/// @}
+void ScheduleResponse(void);
+
+/// @defgroup NextExecutionResponse "NextExecutionResponse"
+/// @{
+/// @brief Schema for next execution preview.
+/// @}
+void NextExecutionResponse(void);
+
+/// @defgroup TranslationRunResponse "TranslationRunResponse"
+/// @{
+/// @brief Schema for translation run API responses.
+/// @}
+void TranslationRunResponse(void);
+
+/// @defgroup RunDetailResponse "RunDetailResponse"
+/// @{
+/// @brief Schema for detailed run response including records, events, and config snapshot.
+/// @}
+void RunDetailResponse(void);
+
+/// @defgroup RunHistoryFilter "RunHistoryFilter"
+/// @{
+/// @brief Schema for filtering run history.
+/// @}
+void RunHistoryFilter(void);
+
+/// @defgroup RunListResponse "RunListResponse"
+/// @{
+/// @brief Schema for paginated run list response.
+/// @}
+void RunListResponse(void);
+
+/// @defgroup AggregatedMetricsResponse "AggregatedMetricsResponse"
+/// @{
+/// @brief Schema for aggregated per-job metrics.
+/// @}
+void AggregatedMetricsResponse(void);
+
+/// @defgroup TranslationPreviewLanguageResponse "TranslationPreviewLanguageResponse"
+/// @{
+/// @brief Schema for per-language preview data in API responses.
+/// @}
+void TranslationPreviewLanguageResponse(void);
+
+/// @defgroup PreviewRow "PreviewRow"
+/// @{
+/// @brief A single row in a translation preview showing original and translated content side by side.
+/// @}
+void PreviewRow(void);
+
+/// @defgroup TranslationPreviewResponse "TranslationPreviewResponse"
+/// @{
+/// @brief Schema for translation preview session API responses.
+/// @}
+void TranslationPreviewResponse(void);
+
+/// @defgroup TranslationBatchResponse "TranslationBatchResponse"
+/// @{
+/// @brief Schema for translation batch API responses.
+/// @}
+void TranslationBatchResponse(void);
+
+/// @defgroup MetricsResponse "MetricsResponse"
+/// @{
+/// @brief Schema for translation metrics API responses.
+/// @}
+void MetricsResponse(void);
+
+/// @defgroup TranslationLanguageResponse "TranslationLanguageResponse"
+/// @{
+/// @brief Schema for per-language translation data in API responses.
+/// @}
+void TranslationLanguageResponse(void);
+
+/// @defgroup TranslationRunLanguageStatsResponse "TranslationRunLanguageStatsResponse"
+/// @{
+/// @brief Schema for per-language statistics in run API responses.
+/// @}
+void TranslationRunLanguageStatsResponse(void);
+
+/// @defgroup OverrideLanguageRequest "OverrideLanguageRequest"
+/// @{
+/// @brief Schema for manually overriding the detected source language of a translation.
+/// @}
+void OverrideLanguageRequest(void);
+
+/// @defgroup BulkFindReplaceRequest "BulkFindReplaceRequest"
+/// @{
+/// @brief Schema for bulk find-and-replace within translations for a target language.
+/// @}
+void BulkFindReplaceRequest(void);
+
+/// @defgroup InlineEditRequest "InlineEditRequest"
+/// @{
+/// @brief Schema for inline editing a translated value on a completed run result.
+/// @}
+void InlineEditRequest(void);
+
+/// @defgroup BulkReplacePreviewItem "BulkReplacePreviewItem"
+/// @{
+/// @brief A single item in a bulk replace preview list.
+/// @}
+void BulkReplacePreviewItem(void);
+
+/// @defgroup BulkReplaceResponse "BulkReplaceResponse"
+/// @{
+/// @brief Response for bulk find-and-replace operation.
+/// @}
+void BulkReplaceResponse(void);
+
+/// @defgroup InlineCorrectionSubmit "InlineCorrectionSubmit"
+/// @{
+/// @brief Schema for submitting an inline correction for a specific translated record.
+/// @}
+void InlineCorrectionSubmit(void);
+
+/// @defgroup TargetSchemaValidationRequest "TargetSchemaValidationRequest"
+/// @{
+/// @brief Schema for requesting target table schema validation.
+/// @}
+void TargetSchemaValidationRequest(void);
+
+/// @defgroup TargetSchemaColumnInfo "TargetSchemaColumnInfo"
+/// @{
+/// @brief Schema for a single column in the schema validation response.
+/// @}
+void TargetSchemaColumnInfo(void);
+
+/// @defgroup TargetSchemaValidationResponse "TargetSchemaValidationResponse"
+/// @{
+/// @brief Schema for target table schema validation response.
+/// @}
+void TargetSchemaValidationResponse(void);
+
+/// @defgroup ValidationSchemas "ValidationSchemas"
+/// @{
+/// @brief Pydantic v2 schemas for validation task management and run history API serialization.
+/// @}
+void ValidationSchemas(void);
+
+/// @defgroup ValidationTaskCreate "ValidationTaskCreate"
+/// @{
+/// @brief Schema for creating a new validation task (policy).
+/// @}
+void ValidationTaskCreate(void);
+
+/// @defgroup ValidationTaskUpdate "ValidationTaskUpdate"
+/// @{
+/// @brief Schema for updating an existing validation task (policy).
+/// @}
+void ValidationTaskUpdate(void);
+
+/// @defgroup ValidationTaskResponse "ValidationTaskResponse"
+/// @{
+/// @brief Schema for validation task API responses — includes last run status from join.
+/// @}
+void ValidationTaskResponse(void);
+
+/// @defgroup ValidationTaskListResponse "ValidationTaskListResponse"
+/// @{
+/// @brief Schema for paginated task list response.
+/// @}
+void ValidationTaskListResponse(void);
+
+/// @defgroup ValidationRunResponse "ValidationRunResponse"
+/// @{
+/// @brief Schema for validation run history listing.
+/// @}
+void ValidationRunResponse(void);
+
+/// @defgroup ValidationRunListResponse "ValidationRunListResponse"
+/// @{
+/// @brief Schema for paginated run list response.
+/// @}
+void ValidationRunListResponse(void);
+
+/// @defgroup ValidationRunDetailResponse "ValidationRunDetailResponse"
+/// @{
+/// @brief Schema for full run detail including parsed issues and raw response.
+/// @}
+void ValidationRunDetailResponse(void);
+
+/// @defgroup TriggerRunResponse "TriggerRunResponse"
+/// @{
+/// @brief Schema for trigger-run response — returns spawned task ID.
+/// @}
+void TriggerRunResponse(void);
+
+/// @defgroup ScriptsPackage "ScriptsPackage"
+/// @{
+/// @brief Script entrypoint package root.
+/// @}
+void ScriptsPackage(void);
+
+/// @defgroup CleanReleaseCliScript "CleanReleaseCliScript"
+/// @{
+/// @brief Provide headless CLI commands for candidate registration, artifact import and manifest build.
+/// @}
+void CleanReleaseCliScript(void);
+
+/// @defgroup build_parser "build_parser"
+/// @{
+/// @brief Build argparse parser for clean release CLI.
+/// @}
+void build_parser(void);
+
+/// @defgroup run_candidate_register "run_candidate_register"
+/// @{
+/// @brief Register candidate in repository via CLI command.
+/// @post Candidate is persisted in DRAFT status.
+/// @pre Candidate ID must be unique.
+/// @}
+void run_candidate_register(void);
+
+/// @defgroup run_artifact_import "run_artifact_import"
+/// @{
+/// @brief Import single artifact for existing candidate.
+/// @post Artifact is persisted for candidate.
+/// @pre Candidate must exist.
+/// @}
+void run_artifact_import(void);
+
+/// @defgroup run_manifest_build "run_manifest_build"
+/// @{
+/// @brief Build immutable manifest snapshot for candidate.
+/// @post New manifest version is persisted.
+/// @pre Candidate must exist.
+/// @}
+void run_manifest_build(void);
+
+/// @defgroup run_compliance_run "run_compliance_run"
+/// @{
+/// @brief Execute compliance run for candidate with optional manifest fallback.
+/// @post Returns run payload and exit code 0 on success.
+/// @pre Candidate exists and trusted snapshots are configured.
+/// @}
+void run_compliance_run(void);
+
+/// @defgroup run_compliance_status "run_compliance_status"
+/// @{
+/// @brief Read run status by run id.
+/// @post Returns run status payload.
+/// @pre Run exists.
+/// @}
+void run_compliance_status(void);
+
+/// @defgroup _to_payload "_to_payload"
+/// @{
+/// @brief Serialize domain models for CLI JSON output across SQLAlchemy/Pydantic variants.
+/// @post Returns dictionary payload without mutating value.
+/// @pre value is serializable model or primitive object.
+/// @}
+void _to_payload(void);
+
+/// @defgroup run_compliance_report "run_compliance_report"
+/// @{
+/// @brief Read immutable report by run id.
+/// @post Returns report payload.
+/// @pre Run and report exist.
+/// @}
+void run_compliance_report(void);
+
+/// @defgroup run_compliance_violations "run_compliance_violations"
+/// @{
+/// @brief Read run violations by run id.
+/// @post Returns violations payload.
+/// @pre Run exists.
+/// @}
+void run_compliance_violations(void);
+
+/// @defgroup run_approve "run_approve"
+/// @{
+/// @brief Approve candidate based on immutable PASSED report.
+/// @post Persists APPROVED decision and returns success payload.
+/// @pre Candidate and report exist; report is PASSED.
+/// @}
+void run_approve(void);
+
+/// @defgroup run_reject "run_reject"
+/// @{
+/// @brief Reject candidate without mutating compliance evidence.
+/// @post Persists REJECTED decision and returns success payload.
+/// @pre Candidate and report exist.
+/// @}
+void run_reject(void);
+
+/// @defgroup run_publish "run_publish"
+/// @{
+/// @brief Publish approved candidate to target channel.
+/// @post Appends ACTIVE publication record and returns payload.
+/// @pre Candidate is approved and report belongs to candidate.
+/// @}
+void run_publish(void);
+
+/// @defgroup run_revoke "run_revoke"
+/// @{
+/// @brief Revoke active publication record.
+/// @post Publication record status becomes REVOKED.
+/// @pre Publication id exists and is ACTIVE.
+/// @}
+void run_revoke(void);
+
+/// @defgroup CleanReleaseTuiScript "CleanReleaseTuiScript"
+/// @{
+/// @brief Interactive terminal interface for Enterprise Clean Release compliance validation.
+/// @invariant TUI refuses startup in non-TTY environments; headless flow is CLI/API only.
+/// @}
+void CleanReleaseTuiScript(void);
+
+/// @defgroup TuiFacadeAdapter "TuiFacadeAdapter"
+/// @{
+/// @brief Thin TUI adapter that routes business mutations through application services.
+/// @post Business actions return service results/errors without direct TUI-owned mutations.
+/// @pre repository contains candidate and trusted policy/registry snapshots for execution.
+/// @}
+void TuiFacadeAdapter(void);
+
+/// @defgroup CleanReleaseTUI "CleanReleaseTUI"
+/// @{
+/// @brief Curses-based application for compliance monitoring.
+/// @}
+void CleanReleaseTUI(void);
+
+/// @defgroup run_checks "run_checks"
+/// @{
+/// @brief Execute compliance run via facade adapter and update UI state.
+/// @post UI reflects final run/report/violation state from service result.
+/// @pre Candidate and policy snapshots are present in repository.
+/// @}
+void run_checks(void);
+
+/// @defgroup bundle_build_mode "bundle_build_mode"
+/// @{
+/// @brief Interactive bundle build screen — select type, enter tag, watch live build output.
+/// @post Subprocess completes (success/failure). Output displayed. User returns via Esc.
+/// @pre TTY is available. Bundle type selected (1 or 2). Tag is non-empty.
+/// @}
+void bundle_build_mode(void);
+
+/// @defgroup CreateAdminScript "CreateAdminScript"
+/// @{
+/// @brief CLI tool for creating the initial admin user.
+/// @invariant Admin user must have the "Admin" role.
+/// @}
+void CreateAdminScript(void);
+
+/// @defgroup create_admin "create_admin"
+/// @{
+/// @brief Creates an admin user and necessary roles/permissions.
+/// @post Admin user exists in auth.db.
+/// @pre username and password provided via CLI.
+/// @}
+void create_admin(void);
+
+/// @defgroup DeleteRunningTasksUtil "DeleteRunningTasksUtil"
+/// @{
+/// @brief Script to delete tasks with RUNNING status from the database.
+/// @}
+void DeleteRunningTasksUtil(void);
+
+/// @defgroup delete_running_tasks "delete_running_tasks"
+/// @{
+/// @brief Delete all tasks with RUNNING status from the database.
+/// @post All tasks with status 'RUNNING' are removed from the database.
+/// @pre Database is accessible and TaskRecord model is defined.
+/// @}
+void delete_running_tasks(void);
+
+/// @defgroup InitAuthDbScript "InitAuthDbScript"
+/// @{
+/// @brief Initializes the auth database and creates the necessary tables.
+/// @invariant Safe to run multiple times (idempotent).
+/// @}
+void InitAuthDbScript(void);
+
+/// @defgroup run_init "run_init"
+/// @{
+/// @brief Main entry point for the initialization script.
+/// @post auth.db is initialized with the correct schema and seeded permissions.
+/// @}
+void run_init(void);
+
+/// @defgroup SeedPermissionsScript "SeedPermissionsScript"
+/// @{
+/// @brief Populates the auth database with initial system permissions.
+/// @invariant Safe to run multiple times (idempotent).
+/// @}
+void SeedPermissionsScript(void);
+
+/// @defgroup INITIAL_PERMISSIONS "INITIAL_PERMISSIONS"
+/// @{
+/// @brief Canonical bootstrap permission tuples seeded into auth storage.
+/// @}
+void INITIAL_PERMISSIONS(void);
+
+/// @defgroup seed_permissions "seed_permissions"
+/// @{
+/// @brief Inserts missing permissions into the database.
+/// @post All INITIAL_PERMISSIONS exist in the DB.
+/// @}
+void seed_permissions(void);
+
+/// @defgroup SeedSupersetLoadTestScript "SeedSupersetLoadTestScript"
+/// @{
+/// @brief Creates randomized load-test data in Superset by cloning chart configurations and creating dashboards in target environments.
+/// @invariant Created chart and dashboard names are globally unique for one script run.
+/// @}
+void SeedSupersetLoadTestScript(void);
+
+/// @defgroup _parse_args "_parse_args"
+/// @{
+/// @brief Parses CLI arguments for load-test data generation.
+/// @post Returns validated argument namespace.
+/// @pre Script is called from CLI.
+/// @}
+void _parse_args(void);
+
+/// @defgroup _extract_result_payload "_extract_result_payload"
+/// @{
+/// @brief Normalizes Superset API payloads that may be wrapped in `result`.
+/// @post Returns the unwrapped object when present.
+/// @pre payload is a JSON-decoded API response.
+/// @}
+void _extract_result_payload(void);
+
+/// @defgroup _extract_created_id "_extract_created_id"
+/// @{
+/// @brief Extracts object ID from create/update API response.
+/// @post Returns integer object ID or None if missing.
+/// @pre payload is a JSON-decoded API response.
+/// @}
+void _extract_created_id(void);
+
+/// @defgroup _generate_unique_name "_generate_unique_name"
+/// @{
+/// @brief Generates globally unique random names for charts/dashboards.
+/// @post Returns a unique string and stores it in used_names.
+/// @pre used_names is mutable set for collision tracking.
+/// @}
+void _generate_unique_name(void);
+
+/// @defgroup _resolve_target_envs "_resolve_target_envs"
+/// @{
+/// @brief Resolves requested environment IDs from configuration.
+/// @post Returns mapping env_id -> configured environment object.
+/// @pre env_ids is non-empty.
+/// @}
+void _resolve_target_envs(void);
+
+/// @defgroup _build_chart_template_pool "_build_chart_template_pool"
+/// @{
+/// @brief Builds a pool of source chart templates to clone in one environment.
+/// @post Returns non-empty list of chart payload templates.
+/// @pre Client is authenticated.
+/// @}
+void _build_chart_template_pool(void);
+
+/// @defgroup seed_superset_load_data "seed_superset_load_data"
+/// @{
+/// @brief Creates dashboards and cloned charts for load testing across target environments.
+/// @post Returns execution statistics dictionary.
+/// @pre Target environments must be reachable and authenticated.
+/// @}
+void seed_superset_load_data(void);
+
+/// @defgroup main "main"
+/// @{
+/// @brief CLI entrypoint for Superset load-test data seeding.
+/// @post Prints summary and exits with non-zero status on failure.
+/// @pre Command line arguments are valid.
+/// @}
+void main(void);
+
+/// @defgroup test_dataset_dashboard_relations_script "test_dataset_dashboard_relations_script"
+/// @{
+/// @brief Tests and inspects dataset-to-dashboard relationship responses from Superset API.
+/// @}
+void test_dataset_dashboard_relations_script(void);
+
+/// @defgroup services "services"
+/// @{
+/// @brief Package initialization for services module
+/// @note GitService, AuthService, LLMProviderService have circular import issues - import directly when needed
+/// @}
+void services(void);
+
+/// @defgroup auth_service "auth_service"
+/// @{
+/// @brief Orchestrates credential authentication and ADFS JIT user provisioning.
+/// @invariant Authentication succeeds only for active users with valid credentials; issued sessions encode subject and scopes from assigned roles.
+/// @post User identity verified and session tokens issued according to role scopes.
+/// @pre Core auth models and security utilities available.
+/// @}
+void auth_service(void);
+
+/// @defgroup AuthService "AuthService"
+/// @{
+/// @brief Provides high-level authentication services.
+/// @}
+void AuthService(void);
+
+/// @defgroup CleanReleaseContracts "CleanReleaseContracts"
+/// @{
+/// @brief Publish the canonical semantic root for the clean-release backend service cluster.
+/// @}
+void CleanReleaseContracts(void);
+
+/// @defgroup ApprovalService "ApprovalService"
+/// @{
+/// @brief Enforce approval/rejection gates over immutable compliance reports.
+/// @invariant Approval is allowed only for PASSED report bound to candidate; decisions are append-only.
+/// @post Approval decision appended; candidate lifecycle advanced
+/// @pre Report with PASSED final_status exists for candidate
+/// @}
+void ApprovalService(void);
+
+/// @defgroup _get_or_init_decisions_store "_get_or_init_decisions_store"
+/// @{
+/// @brief Provide append-only in-memory storage for approval decisions.
+/// @post Returns mutable decision list attached to repository.
+/// @pre repository is initialized.
+/// @}
+void _get_or_init_decisions_store(void);
+
+/// @defgroup _latest_decision_for_candidate "_latest_decision_for_candidate"
+/// @{
+/// @brief Resolve latest approval decision for candidate from append-only store.
+/// @post Returns latest ApprovalDecision or None.
+/// @pre candidate_id is non-empty.
+/// @}
+void _latest_decision_for_candidate(void);
+
+/// @defgroup _resolve_candidate_and_report "_resolve_candidate_and_report"
+/// @{
+/// @brief Validate candidate/report existence and ownership prior to decision persistence.
+/// @post Returns tuple(candidate, report); raises ApprovalGateError on contract violation.
+/// @pre candidate_id and report_id are non-empty.
+/// @}
+void _resolve_candidate_and_report(void);
+
+/// @defgroup approve_candidate "approve_candidate"
+/// @{
+/// @brief Persist immutable APPROVED decision and advance candidate lifecycle to APPROVED.
+/// @post Approval decision is appended and candidate transitions to APPROVED.
+/// @pre Candidate exists, report belongs to candidate, report final_status is PASSED, candidate not already APPROVED.
+/// @}
+void approve_candidate(void);
+
+/// @defgroup reject_candidate "reject_candidate"
+/// @{
+/// @brief Persist immutable REJECTED decision without promoting candidate lifecycle.
+/// @post Rejected decision is appended; candidate lifecycle is unchanged.
+/// @pre Candidate exists and report belongs to candidate.
+/// @}
+void reject_candidate(void);
+
+/// @defgroup ArtifactCatalogLoader "ArtifactCatalogLoader"
+/// @{
+/// @brief Load bootstrap artifact catalogs for clean release real-mode flows.
+/// @invariant Artifact catalog must produce deterministic CandidateArtifact entries with required identity and checksum fields.
+/// @}
+void ArtifactCatalogLoader(void);
+
+/// @defgroup load_bootstrap_artifacts "load_bootstrap_artifacts"
+/// @{
+/// @brief Parse artifact catalog JSON into CandidateArtifact models for TUI/bootstrap flows.
+/// @post Returns non-mutated CandidateArtifact models with required fields populated.
+/// @pre path points to readable JSON file; payload is list[artifact] or {"artifacts": list[artifact]}.
+/// @}
+void load_bootstrap_artifacts(void);
+
+/// @defgroup AuditService "AuditService"
+/// @{
+/// @brief Provide lightweight audit hooks for clean release preparation/check/report lifecycle.
+/// @invariant Audit hooks are append-only log actions.
+/// @post Audit events appended to log
+/// @pre Logger configured
+/// @}
+void AuditService(void);
+
+/// @defgroup candidate_service "candidate_service"
+/// @{
+/// @brief Register release candidates with validated artifacts and advance lifecycle through legal transitions.
+/// @invariant Candidate lifecycle transitions are delegated to domain guard logic.
+/// @post candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.
+/// @pre candidate_id must be unique; artifacts input must be non-empty and valid.
+/// @}
+void candidate_service(void);
+
+/// @defgroup _validate_artifacts "_validate_artifacts"
+/// @{
+/// @brief Validate raw artifact payload list for required fields and shape.
+/// @post Returns normalized artifact list or raises ValueError.
+/// @pre artifacts payload is provided by caller.
+/// @}
+void _validate_artifacts(void);
+
+/// @defgroup ComplianceExecutionService "ComplianceExecutionService"
+/// @{
+/// @brief Create and execute compliance runs with trusted snapshots, deterministic stages, violations and immutable report persistence.
+/// @invariant A run binds to exactly one candidate/manifest/policy/registry snapshot set.
+/// @post Candidate-scoped compliance runs persist stage evidence, terminal status, and immutable report artifacts when execution succeeds.
+/// @pre Repository adapters, trusted policy resolution, and deterministic stage implementations are available for the run request.
+/// @}
+void ComplianceExecutionService(void);
+
+/// @defgroup ComplianceExecutionResult "ComplianceExecutionResult"
+/// @{
+/// @brief Return envelope for compliance execution with run/report and persisted stage artifacts.
+/// @}
+void ComplianceExecutionResult(void);
+
+/// @defgroup ComplianceOrchestrator "ComplianceOrchestrator"
+/// @{
+/// @brief Execute mandatory clean compliance stages and produce final COMPLIANT/BLOCKED/FAILED outcome.
+/// @invariant COMPLIANT is impossible when any mandatory stage fails.
+/// @post OrchestrationResult with compliance status
+/// @pre ManifestService and PolicyEngine are available
+/// @}
+void ComplianceOrchestrator(void);
+
+/// @defgroup CleanComplianceOrchestrator "CleanComplianceOrchestrator"
+/// @{
+/// @brief Coordinate clean-release compliance verification stages.
+/// @}
+void CleanComplianceOrchestrator(void);
+
+/// @defgroup run_check_legacy "run_check_legacy"
+/// @{
+/// @brief Legacy wrapper for compatibility with previous orchestrator call style.
+/// @post Returns finalized ComplianceRun produced by orchestrator start->execute->finalize sequence.
+/// @pre repository and identifiers are valid and resolvable by orchestrator dependencies.
+/// @}
+void run_check_legacy(void);
+
+/// @defgroup DemoDataService "DemoDataService"
+/// @{
+/// @brief Provide deterministic namespace helpers and isolated in-memory repository creation for demo and real modes.
+/// @invariant Demo and real namespaces must never collide for generated physical identifiers.
+/// @}
+void DemoDataService(void);
+
+/// @defgroup resolve_namespace "resolve_namespace"
+/// @{
+/// @brief Resolve canonical clean-release namespace for requested mode.
+/// @post Returns deterministic namespace key for demo/real separation.
+/// @pre mode is a non-empty string identifying runtime mode.
+/// @}
+void resolve_namespace(void);
+
+/// @defgroup build_namespaced_id "build_namespaced_id"
+/// @{
+/// @brief Build storage-safe physical identifier under mode namespace.
+/// @post Returns deterministic "{namespace}::{logical_id}" identifier.
+/// @pre namespace and logical_id are non-empty strings.
+/// @}
+void build_namespaced_id(void);
+
+/// @defgroup create_isolated_repository "create_isolated_repository"
+/// @{
+/// @brief Create isolated in-memory repository instance for selected mode namespace.
+/// @post Returns repository instance tagged with namespace metadata.
+/// @pre mode is a valid runtime mode marker.
+/// @}
+void create_isolated_repository(void);
+
+/// @defgroup clean_release_dto "clean_release_dto"
+/// @{
+/// @brief Data Transfer Objects for clean release compliance subsystem.
+/// @}
+void clean_release_dto(void);
+
+/// @defgroup clean_release_enums "clean_release_enums"
+/// @{
+/// @brief Canonical enums for clean release lifecycle and compliance.
+/// @}
+void clean_release_enums(void);
+
+/// @defgroup clean_release_exceptions "clean_release_exceptions"
+/// @{
+/// @brief Domain exceptions for clean release compliance subsystem.
+/// @}
+void clean_release_exceptions(void);
+
+/// @defgroup clean_release_facade "clean_release_facade"
+/// @{
+/// @brief Unified entry point for clean release operations.
+/// @}
+void clean_release_facade(void);
+
+/// @defgroup ManifestBuilder "ManifestBuilder"
+/// @{
+/// @brief Build deterministic distribution manifest from classified artifact input.
+/// @invariant Equal semantic artifact sets produce identical deterministic hash values.
+/// @}
+void ManifestBuilder(void);
+
+/// @defgroup build_distribution_manifest "build_distribution_manifest"
+/// @{
+/// @brief Build DistributionManifest with deterministic hash and validated counters.
+/// @post Returns DistributionManifest with summary counts matching items cardinality.
+/// @pre artifacts list contains normalized classification values.
+/// @}
+void build_distribution_manifest(void);
+
+/// @defgroup ManifestService "ManifestService"
+/// @{
+/// @brief Build immutable distribution manifests with deterministic digest and version increment.
+/// @invariant Existing manifests are never mutated.
+/// @post New immutable manifest is persisted with incremented version and deterministic digest.
+/// @pre Candidate exists and is PREPARED or MANIFEST_BUILT; artifacts are present.
+/// @}
+void ManifestService(void);
+
+/// @defgroup build_manifest_snapshot "build_manifest_snapshot"
+/// @{
+/// @brief Create a new immutable manifest version for a candidate.
+/// @post Returns persisted DistributionManifest with monotonically incremented version.
+/// @pre Candidate is prepared, artifacts are available, candidate_id is valid.
+/// @}
+void build_manifest_snapshot(void);
+
+/// @defgroup clean_release_mappers "clean_release_mappers"
+/// @{
+/// @brief Map between domain entities (SQLAlchemy models) and DTOs.
+/// @}
+void clean_release_mappers(void);
+
+/// @defgroup PolicyEngine "PolicyEngine"
+/// @{
+/// @brief Evaluate artifact/source policies for enterprise clean profile with deterministic outcomes.
+/// @invariant Enterprise-clean policy always treats non-registry sources as violations.
+/// @post PolicyDecision returned with approval status
+/// @pre PolicyRepository is accessible
+/// @}
+void PolicyEngine(void);
+
+/// @defgroup CleanPolicyEngine "CleanPolicyEngine"
+/// @{
+/// @post Deterministic classification and source validation are available.
+/// @pre Active policy exists and is internally consistent.
+/// @}
+void CleanPolicyEngine(void);
+
+/// @defgroup PolicyResolutionService "PolicyResolutionService"
+/// @{
+/// @brief Resolve trusted policy and registry snapshots from ConfigManager without runtime overrides.
+/// @invariant Trusted snapshot resolution is based only on ConfigManager active identifiers.
+/// @post ResolutionResult with matched policies
+/// @pre PolicyRepository and Manifest are available
+/// @}
+void PolicyResolutionService(void);
+
+/// @defgroup resolve_trusted_policy_snapshots "resolve_trusted_policy_snapshots"
+/// @{
+/// @brief Resolve immutable trusted policy and registry snapshots using active config IDs only.
+/// @post Returns immutable policy and registry snapshots; runtime override attempts are rejected.
+/// @pre ConfigManager provides active_policy_id and active_registry_id; repository contains referenced snapshots.
+/// @}
+void resolve_trusted_policy_snapshots(void);
+
+/// @defgroup PreparationService "PreparationService"
+/// @{
+/// @brief Prepare release candidate by policy evaluation and deterministic manifest creation.
+/// @invariant Candidate preparation always persists manifest and candidate status deterministically.
+/// @}
+void PreparationService(void);
+
+/// @defgroup prepare_candidate_legacy "prepare_candidate_legacy"
+/// @{
+/// @brief Legacy compatibility wrapper kept for migration period.
+/// @post Delegates to canonical prepare_candidate and preserves response shape.
+/// @pre Same as prepare_candidate.
+/// @}
+void prepare_candidate_legacy(void);
+
+/// @defgroup PublicationService "PublicationService"
+/// @{
+/// @brief Enforce publication and revocation gates with append-only publication records.
+/// @invariant Publication records are append-only snapshots; revoke mutates only publication status for targeted record.
+/// @}
+void PublicationService(void);
+
+/// @defgroup _get_or_init_publications_store "_get_or_init_publications_store"
+/// @{
+/// @brief Provide in-memory append-only publication storage.
+/// @post Returns publication list attached to repository.
+/// @pre repository is initialized.
+/// @}
+void _get_or_init_publications_store(void);
+
+/// @defgroup _latest_publication_for_candidate "_latest_publication_for_candidate"
+/// @{
+/// @brief Resolve latest publication record for candidate.
+/// @post Returns latest record or None.
+/// @pre candidate_id is non-empty.
+/// @}
+void _latest_publication_for_candidate(void);
+
+/// @defgroup _latest_approval_for_candidate "_latest_approval_for_candidate"
+/// @{
+/// @brief Resolve latest approval decision from repository decision store.
+/// @post Returns latest decision object or None.
+/// @pre candidate_id is non-empty.
+/// @}
+void _latest_approval_for_candidate(void);
+
+/// @defgroup publish_candidate "publish_candidate"
+/// @{
+/// @brief Create immutable publication record for approved candidate.
+/// @post New ACTIVE publication record is appended.
+/// @pre Candidate exists, report belongs to candidate, latest approval is APPROVED.
+/// @}
+void publish_candidate(void);
+
+/// @defgroup revoke_publication "revoke_publication"
+/// @{
+/// @brief Revoke existing publication record without deleting history.
+/// @post Target publication status becomes REVOKED and updated record is returned.
+/// @pre publication_id exists in repository publication store.
+/// @}
+void revoke_publication(void);
+
+/// @defgroup ReportBuilder "ReportBuilder"
+/// @{
+/// @brief Build and persist compliance reports with consistent counter invariants.
+/// @invariant blocking_violations_count never exceeds violations_count.
+/// @post Returns immutable report payloads with consistent violation counters and operator summary content.
+/// @pre Compliance run is terminal and repository persistence is available for report storage.
+/// @}
+void ReportBuilder(void);
+
+/// @defgroup clean_release_repositories "clean_release_repositories"
+/// @{
+/// @brief Export all clean release repositories.
+/// @}
+void clean_release_repositories(void);
+
+/// @defgroup approval_repository "approval_repository"
+/// @{
+/// @brief Persist and query approval decisions.
+/// @}
+void approval_repository(void);
+
+/// @defgroup artifact_repository "artifact_repository"
+/// @{
+/// @brief Persist and query candidate artifacts.
+/// @}
+void artifact_repository(void);
+
+/// @defgroup audit_repository "audit_repository"
+/// @{
+/// @brief Persist and query audit logs for clean release operations.
+/// @}
+void audit_repository(void);
+
+/// @defgroup candidate_repository "candidate_repository"
+/// @{
+/// @brief Persist and query release candidates.
+/// @}
+void candidate_repository(void);
+
+/// @defgroup compliance_repository "compliance_repository"
+/// @{
+/// @brief Persist and query compliance runs, stage runs, and violations.
+/// @}
+void compliance_repository(void);
+
+/// @defgroup ManifestRepositoryModule "ManifestRepositoryModule"
+/// @{
+/// @brief Persist and query distribution manifests.
+/// @}
+void ManifestRepositoryModule(void);
+
+/// @defgroup ManifestRepository "ManifestRepository"
+/// @{
+/// @brief Encapsulates database CRUD operations for DistributionManifest entities.
+/// @}
+void ManifestRepository(void);
+
+/// @defgroup policy_repository "policy_repository"
+/// @{
+/// @brief Persist and query policy and registry snapshots.
+/// @}
+void policy_repository(void);
+
+/// @defgroup publication_repository "publication_repository"
+/// @{
+/// @brief Persist and query publication records.
+/// @}
+void publication_repository(void);
+
+/// @defgroup report_repository "report_repository"
+/// @{
+/// @brief Persist and query compliance reports.
+/// @}
+void report_repository(void);
+
+/// @defgroup RepositoryRelations "RepositoryRelations"
+/// @{
+/// @brief Provide repository adapter for clean release entities with deterministic access methods.
+/// @invariant Repository operations are side-effect free outside explicit save/update calls.
+/// @post Repository operations exported
+/// @pre In-memory storage initialized
+/// @}
+void RepositoryRelations(void);
+
+/// @defgroup CleanReleaseRepository "CleanReleaseRepository"
+/// @{
+/// @brief Data access object for clean release lifecycle.
+/// @}
+void CleanReleaseRepository(void);
+
+/// @defgroup SourceIsolation "SourceIsolation"
+/// @{
+/// @brief Validate that all resource endpoints belong to the approved internal source registry.
+/// @invariant Any endpoint outside enabled registry entries is treated as external-source violation.
+/// @post Source isolation violations identified
+/// @pre Source registry configured
+/// @}
+void SourceIsolation(void);
+
+/// @defgroup ComplianceStages "ComplianceStages"
+/// @{
+/// @brief Define compliance stage order and helper functions for deterministic run-state evaluation.
+/// @invariant Stage order remains deterministic for all compliance runs.
+/// @}
+void ComplianceStages(void);
+
+/// @defgroup build_default_stages "build_default_stages"
+/// @{
+/// @brief Build default deterministic stage pipeline implementation order.
+/// @post Returns stage instances in mandatory execution order.
+/// @pre None.
+/// @}
+void build_default_stages(void);
+
+/// @defgroup stage_result_map "stage_result_map"
+/// @{
+/// @brief Convert stage result list to dictionary by stage name.
+/// @post Returns stage->status dictionary for downstream evaluation.
+/// @pre stage_results may be empty or contain unique stage names.
+/// @}
+void stage_result_map(void);
+
+/// @defgroup missing_mandatory_stages "missing_mandatory_stages"
+/// @{
+/// @brief Identify mandatory stages that are absent from run results.
+/// @post Returns ordered list of missing mandatory stages.
+/// @pre stage_status_map contains zero or more known stage statuses.
+/// @}
+void missing_mandatory_stages(void);
+
+/// @defgroup derive_final_status "derive_final_status"
+/// @{
+/// @brief Derive final run status from stage results with deterministic blocking behavior.
+/// @post Returns one of PASSED/BLOCKED/ERROR according to mandatory stage outcomes.
+/// @pre Stage statuses correspond to compliance checks.
+/// @}
+void derive_final_status(void);
+
+/// @defgroup ComplianceStageBase "ComplianceStageBase"
+/// @{
+/// @brief Define shared contracts and helpers for pluggable clean-release compliance stages.
+/// @invariant Stage execution is deterministic for equal input context.
+/// @}
+void ComplianceStageBase(void);
+
+/// @defgroup ComplianceStageContext "ComplianceStageContext"
+/// @{
+/// @brief Immutable input envelope passed to each compliance stage.
+/// @}
+void ComplianceStageContext(void);
+
+/// @defgroup StageExecutionResult "StageExecutionResult"
+/// @{
+/// @brief Structured stage output containing decision, details and violations.
+/// @}
+void StageExecutionResult(void);
+
+/// @defgroup ComplianceStage "ComplianceStage"
+/// @{
+/// @brief Protocol for pluggable stage implementations.
+/// @}
+void ComplianceStage(void);
+
+/// @defgroup build_stage_run_record "build_stage_run_record"
+/// @{
+/// @brief Build persisted stage run record from stage result.
+/// @post Returns ComplianceStageRun with deterministic identifiers and timestamps.
+/// @pre run_id and stage_name are non-empty.
+/// @}
+void build_stage_run_record(void);
+
+/// @defgroup build_violation "build_violation"
+/// @{
+/// @brief Construct a compliance violation with normalized defaults.
+/// @post Returns immutable-style violation payload ready for persistence.
+/// @pre run_id, stage_name, code and message are non-empty.
+/// @}
+void build_violation(void);
+
+/// @defgroup data_purity "data_purity"
+/// @{
+/// @brief Evaluate manifest purity counters and emit blocking violations for prohibited artifacts.
+/// @invariant prohibited_detected_count > 0 always yields BLOCKED stage decision.
+/// @}
+void data_purity(void);
+
+/// @defgroup DataPurityStage "DataPurityStage"
+/// @{
+/// @brief Validate manifest summary for prohibited artifacts.
+/// @post Returns PASSED when no prohibited artifacts are detected, otherwise BLOCKED with violations.
+/// @pre context.manifest.content_json contains summary block or defaults to safe counters.
+/// @}
+void DataPurityStage(void);
+
+/// @defgroup internal_sources_only "internal_sources_only"
+/// @{
+/// @brief Verify manifest-declared sources belong to trusted internal registry allowlist.
+/// @invariant Any source host outside allowed_hosts yields BLOCKED decision with at least one violation.
+/// @}
+void internal_sources_only(void);
+
+/// @defgroup InternalSourcesOnlyStage "InternalSourcesOnlyStage"
+/// @{
+/// @brief Enforce internal-source-only policy from trusted registry snapshot.
+/// @post Returns PASSED when all hosts are allowed; otherwise BLOCKED and violations captured.
+/// @pre context.registry.allowed_hosts is available.
+/// @}
+void InternalSourcesOnlyStage(void);
+
+/// @defgroup manifest_consistency "manifest_consistency"
+/// @{
+/// @brief Ensure run is bound to the exact manifest snapshot and digest used at run creation time.
+/// @invariant Digest mismatch between run and manifest yields ERROR with blocking violation evidence.
+/// @}
+void manifest_consistency(void);
+
+/// @defgroup ManifestConsistencyStage "ManifestConsistencyStage"
+/// @{
+/// @brief Validate run/manifest linkage consistency.
+/// @post Returns PASSED when digests match, otherwise ERROR with one violation.
+/// @pre context.run and context.manifest are loaded from repository for same run.
+/// @}
+void ManifestConsistencyStage(void);
+
+/// @defgroup no_external_endpoints "no_external_endpoints"
+/// @{
+/// @brief Block manifest payloads that expose external endpoints outside trusted schemes and hosts.
+/// @invariant Endpoint outside allowed scheme/host always yields BLOCKED stage decision.
+/// @}
+void no_external_endpoints(void);
+
+/// @defgroup NoExternalEndpointsStage "NoExternalEndpointsStage"
+/// @{
+/// @brief Validate endpoint references from manifest against trusted registry.
+/// @post Returns PASSED when all endpoints are trusted, otherwise BLOCKED with endpoint violations.
+/// @pre context.registry includes allowed hosts and schemes.
+/// @}
+void NoExternalEndpointsStage(void);
+
+/// @defgroup dataset_review "dataset_review"
+/// @{
+/// @brief Provides services for dataset-centered orchestration flow.
+/// @}
+void dataset_review(void);
+
+/// @defgroup ClarificationEngine "ClarificationEngine"
+/// @{
+/// @brief Manage one-question-at-a-time clarification state, deterministic answer persistence, and readiness/finding updates.
+/// @invariant Only one active clarification question may exist at a time; skipped and expert-review items remain unresolved and visible.
+/// @post Active clarification payload exposes one highest-priority unresolved question, and each recorded answer is persisted before pointer/readiness mutation.
+/// @pre Target session contains a persisted clarification aggregate in the current ownership scope.
+/// @}
+void ClarificationEngine(void);
+
+/// @defgroup ClarificationQuestionPayload "ClarificationQuestionPayload"
+/// @{
+/// @brief Typed active-question payload returned to the API layer.
+/// @}
+void ClarificationQuestionPayload(void);
+
+/// @defgroup ClarificationStateResult "ClarificationStateResult"
+/// @{
+/// @brief Clarification state result carrying the current session, active payload, and changed findings.
+/// @}
+void ClarificationStateResult(void);
+
+/// @defgroup ClarificationAnswerCommand "ClarificationAnswerCommand"
+/// @{
+/// @brief Typed answer command for clarification state mutation.
+/// @}
+void ClarificationAnswerCommand(void);
+
+/// @defgroup ClarificationHelpers "ClarificationHelpers"
+/// @{
+/// @brief Pure helper functions for clarification engine — question selection, counting, normalization, finding upsert, and readiness derivation.
+/// @}
+void ClarificationHelpers(void);
+
+/// @defgroup select_next_open_question "select_next_open_question"
+/// @{
+/// @brief Select the next unresolved question in deterministic priority order.
+/// @}
+void select_next_open_question(void);
+
+/// @defgroup count_resolved_questions "count_resolved_questions"
+/// @{
+/// @brief Count questions whose answers fully resolved the ambiguity.
+/// @}
+void count_resolved_questions(void);
+
+/// @defgroup count_remaining_questions "count_remaining_questions"
+/// @{
+/// @brief Count questions still unresolved or deferred after clarification interaction.
+/// @}
+void count_remaining_questions(void);
+
+/// @defgroup normalize_answer_value "normalize_answer_value"
+/// @{
+/// @brief Validate and normalize answer payload based on answer kind and active question options.
+/// @}
+void normalize_answer_value(void);
+
+/// @defgroup build_impact_summary "build_impact_summary"
+/// @{
+/// @brief Build a compact audit note describing how the clarification answer affects session state.
+/// @}
+void build_impact_summary(void);
+
+/// @defgroup upsert_clarification_finding "upsert_clarification_finding"
+/// @{
+/// @brief Keep one finding per clarification topic aligned with answer outcome and unresolved visibility rules.
+/// @}
+void upsert_clarification_finding(void);
+
+/// @defgroup derive_readiness_state "derive_readiness_state"
+/// @{
+/// @brief Recompute readiness after clarification mutation while preserving unresolved visibility semantics.
+/// @}
+void derive_readiness_state(void);
+
+/// @defgroup derive_recommended_action "derive_recommended_action"
+/// @{
+/// @brief Recompute next-action guidance after clarification mutations.
+/// @}
+void derive_recommended_action(void);
+
+/// @defgroup SessionEventLoggerModule "SessionEventLoggerModule"
+/// @{
+/// @brief Persist explicit session mutation events for dataset-review audit trails without weakening ownership or approval invariants.
+/// @post Every logged event is committed as an explicit, queryable audit record with deterministic event metadata.
+/// @pre Caller provides an owned session scope and an authenticated actor identifier for each persisted mutation event.
+/// @}
+void SessionEventLoggerModule(void);
+
+/// @defgroup SessionEventLoggerImports "SessionEventLoggerImports"
+/// @{
+/// @}
+void SessionEventLoggerImports(void);
+
+/// @defgroup SessionEventPayload "SessionEventPayload"
+/// @{
+/// @brief Typed input contract for one persisted dataset-review session audit event.
+/// @}
+void SessionEventPayload(void);
+
+/// @defgroup SessionEventLogger "SessionEventLogger"
+/// @{
+/// @brief Persist explicit dataset-review session audit events with meaningful runtime reasoning logs.
+/// @post Returns the committed session event row with a stable identifier and stored detail payload.
+/// @pre The database session is live and payload identifiers are non-empty.
+/// @}
+void SessionEventLogger(void);
+
+/// @defgroup DatasetReviewOrchestrator "DatasetReviewOrchestrator"
+/// @{
+/// @brief Coordinate dataset review session startup and lifecycle-safe intake recovery for one authenticated user.
+/// @invariant Launch is blocked unless a current session has no open blocking findings, all launch-sensitive mappings are approved, and a non-stale Superset-generated compiled preview matches the current input fingerprint.
+/// @post state transitions are persisted atomically and emit observable progress for long-running steps.
+/// @pre session mutations must execute inside a persisted session boundary scoped to one authenticated user.
+/// @}
+void DatasetReviewOrchestrator(void);
+
+/// @defgroup OrchestratorCommands "OrchestratorCommands"
+/// @{
+/// @brief Typed command and result dataclasses for dataset review orchestration boundary.
+/// @}
+void OrchestratorCommands(void);
+
+/// @defgroup StartSessionCommand "StartSessionCommand"
+/// @{
+/// @brief Typed input contract for starting a dataset review session.
+/// @}
+void StartSessionCommand(void);
+
+/// @defgroup StartSessionResult "StartSessionResult"
+/// @{
+/// @brief Session-start result carrying the persisted session and intake recovery metadata.
+/// @}
+void StartSessionResult(void);
+
+/// @defgroup PreparePreviewCommand "PreparePreviewCommand"
+/// @{
+/// @brief Typed input contract for compiling one Superset-backed session preview.
+/// @}
+void PreparePreviewCommand(void);
+
+/// @defgroup PreparePreviewResult "PreparePreviewResult"
+/// @{
+/// @brief Result contract for one persisted compiled preview attempt.
+/// @}
+void PreparePreviewResult(void);
+
+/// @defgroup LaunchDatasetCommand "LaunchDatasetCommand"
+/// @{
+/// @brief Typed input contract for launching one dataset-review session into SQL Lab.
+/// @}
+void LaunchDatasetCommand(void);
+
+/// @defgroup LaunchDatasetResult "LaunchDatasetResult"
+/// @{
+/// @brief Launch result carrying immutable run context and any gate blockers.
+/// @}
+void LaunchDatasetResult(void);
+
+/// @defgroup OrchestratorHelpers "OrchestratorHelpers"
+/// @{
+/// @brief Pure helper methods extracted from DatasetReviewOrchestrator for INV_7 compliance — snapshot, blockers, fingerprint, recovery bootstrap.
+/// @post Helper results are deterministic and do not mutate persistence directly.
+/// @pre Caller provides a loaded session aggregate with hydrated child collections.
+/// @}
+void OrchestratorHelpers(void);
+
+/// @defgroup parse_dataset_selection "parse_dataset_selection"
+/// @{
+/// @brief Normalize dataset-selection payload into canonical session references.
+/// @}
+void parse_dataset_selection(void);
+
+/// @defgroup build_initial_profile "build_initial_profile"
+/// @{
+/// @brief Create the first profile snapshot so exports and detail views remain usable immediately after intake.
+/// @}
+void build_initial_profile(void);
+
+/// @defgroup build_partial_recovery_findings "build_partial_recovery_findings"
+/// @{
+/// @brief Project partial Superset intake recovery into explicit findings without blocking session usability.
+/// @post Returns warning-level findings that preserve usable but incomplete state.
+/// @pre parsed_context.partial_recovery is true.
+/// @}
+void build_partial_recovery_findings(void);
+
+/// @defgroup extract_effective_filter_value "extract_effective_filter_value"
+/// @{
+/// @brief Separate normalized filter payload metadata from the user-facing effective filter value.
+/// @}
+void extract_effective_filter_value(void);
+
+/// @defgroup build_execution_snapshot "build_execution_snapshot"
+/// @{
+/// @brief Build effective filters, template params, approvals, and fingerprint for preview and launch gating.
+/// @post Returns deterministic execution snapshot for current session state without mutating persistence.
+/// @pre Session aggregate includes imported filters, template variables, and current execution mappings.
+/// @}
+void build_execution_snapshot(void);
+
+/// @defgroup build_launch_blockers "build_launch_blockers"
+/// @{
+/// @brief Enforce launch gates from findings, approvals, and current preview truth.
+/// @post Returns explicit blocker codes for every unmet launch invariant.
+/// @pre execution_snapshot was computed from current session state.
+/// @}
+void build_launch_blockers(void);
+
+/// @defgroup get_latest_preview "get_latest_preview"
+/// @{
+/// @brief Resolve the current latest preview snapshot for one session aggregate.
+/// @}
+void get_latest_preview(void);
+
+/// @defgroup compute_preview_fingerprint "compute_preview_fingerprint"
+/// @{
+/// @brief Produce deterministic execution fingerprint for preview truth and staleness checks.
+/// @}
+void compute_preview_fingerprint(void);
+
+/// @defgroup SessionRepositoryMutations "SessionRepositoryMutations"
+/// @{
+/// @brief Persistence mutation operations for dataset review session aggregates — profile/findings, recovery state, preview, run context.
+/// @post Session aggregate writes preserve ownership and version semantics.
+/// @pre All mutations execute within authenticated request or task scope.
+/// @}
+void SessionRepositoryMutations(void);
+
+/// @defgroup save_profile_and_findings "save_profile_and_findings"
+/// @{
+/// @brief Persist profile state and replace validation findings for an owned session in one transaction.
+/// @post stored profile matches the current session and findings are replaced by the supplied collection.
+/// @pre session_id belongs to user_id and the supplied profile/findings belong to the same aggregate scope.
+/// @}
+void save_profile_and_findings(void);
+
+/// @defgroup save_recovery_state "save_recovery_state"
+/// @{
+/// @brief Persist imported filters, template variables, and initial execution mappings for one owned session.
+/// @post Recovery state persisted to database.
+/// @pre session_id belongs to user_id.
+/// @}
+void save_recovery_state(void);
+
+/// @defgroup save_preview "save_preview"
+/// @{
+/// @brief Persist a preview snapshot and mark prior session previews stale.
+/// @post preview is persisted and the session points to the latest preview identifier.
+/// @pre session_id belongs to user_id and preview is prepared for the same session aggregate.
+/// @}
+void save_preview(void);
+
+/// @defgroup save_run_context "save_run_context"
+/// @{
+/// @brief Persist an immutable launch audit snapshot for an owned session.
+/// @post run context is persisted and linked as the latest launch snapshot for the session.
+/// @pre session_id belongs to user_id and run_context targets the same aggregate.
+/// @}
+void save_run_context(void);
+
+/// @defgroup DatasetReviewSessionRepository "DatasetReviewSessionRepository"
+/// @{
+/// @brief Persist and retrieve dataset review session aggregates, including readiness, findings, semantic decisions, clarification state, previews, and run contexts.
+/// @invariant answers, mapping approvals, preview artifacts, and launch snapshots are never attributed to the wrong user or session.
+/// @post session aggregate reads are structurally consistent and writes preserve ownership and version semantics.
+/// @pre repository operations execute within authenticated request or task scope.
+/// @}
+void DatasetReviewSessionRepository(void);
+
+/// @defgroup DatasetReviewSessionVersionConflictError "DatasetReviewSessionVersionConflictError"
+/// @{
+/// @brief Signal optimistic-lock conflicts for dataset review session mutations.
+/// @}
+void DatasetReviewSessionVersionConflictError(void);
+
+/// @defgroup SemanticSourceResolver "SemanticSourceResolver"
+/// @{
+/// @brief Resolve and rank semantic candidates from trusted dictionary-like sources before any inferred fallback.
+/// @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+/// @post candidate ranking follows the configured confidence hierarchy and unresolved fuzzy matches remain reviewable.
+/// @pre selected source and target field set must be known.
+/// @}
+void SemanticSourceResolver(void);
+
+/// @defgroup imports "imports"
+/// @{
+/// @}
+void imports(void);
+
+/// @defgroup DictionaryResolutionResult "DictionaryResolutionResult"
+/// @{
+/// @brief Carries field-level dictionary resolution output with explicit review and partial-recovery state.
+/// @}
+void DictionaryResolutionResult(void);
+
+/// @defgroup GitServiceModule "GitServiceModule"
+/// @{
+/// @brief Composed GitService via multiple inheritance from domain-specific mixins.
+/// @}
+void GitServiceModule(void);
+
+/// @defgroup GitService "GitService"
+/// @{
+/// @brief Composed GitService class providing all Git operations — init, clone, branches, commits, push, pull,
+/// @}
+void GitService(void);
+
+/// @defgroup GitServiceBase "GitServiceBase"
+/// @{
+/// @brief Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool.
+/// @}
+void GitServiceBase(void);
+
+/// @defgroup GitServiceBranchMixin "GitServiceBranchMixin"
+/// @{
+/// @brief Branch and commit operations for GitService — gitflow branches, list/create/checkout branches, commit changes (all concurrent-safe via per-dashboard locks).
+/// @}
+void GitServiceBranchMixin(void);
+
+/// @defgroup GitServiceGiteaMixin "GitServiceGiteaMixin"
+/// @{
+/// @brief Gitea API operations for GitService — connection testing, repository CRUD, and pull request creation. Uses shared self._http_client for connection pooling.
+/// @}
+void GitServiceGiteaMixin(void);
+
+/// @defgroup GitServiceMergeMixin "GitServiceMergeMixin"
+/// @{
+/// @brief Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks).
+/// @}
+void GitServiceMergeMixin(void);
+
+/// @defgroup GitServiceRemoteMixin "GitServiceRemoteMixin"
+/// @{
+/// @brief GitHub and GitLab provider operations for GitService — repository creation and PR/MR creation. Uses shared self._http_client for connection pooling.
+/// @}
+void GitServiceRemoteMixin(void);
+
+/// @defgroup GitServiceGithubMixin "GitServiceGithubMixin"
+/// @{
+/// @brief Mixin providing GitHub API operations for GitService.
+/// @}
+void GitServiceGithubMixin(void);
+
+/// @defgroup GitServiceGitlabMixin "GitServiceGitlabMixin"
+/// @{
+/// @brief Mixin providing GitLab API operations for GitService.
+/// @}
+void GitServiceGitlabMixin(void);
+
+/// @defgroup GitServiceStatusMixin "GitServiceStatusMixin"
+/// @{
+/// @brief Status, diff, and commit history operations for GitService (all concurrent-safe via per-dashboard locks).
+/// @}
+void GitServiceStatusMixin(void);
+
+/// @defgroup GitServiceSyncMixin "GitServiceSyncMixin"
+/// @{
+/// @brief Push and pull operations for GitService with origin host auto-alignment (concurrent-safe).
+/// @}
+void GitServiceSyncMixin(void);
+
+/// @defgroup GitServiceUrlMixin "GitServiceUrlMixin"
+/// @{
+/// @brief URL helper mixin for GitService — parse, normalize, align, and strip credentials from Git URLs.
+/// @}
+void GitServiceUrlMixin(void);
+
+/// @defgroup health_service "health_service"
+/// @{
+/// @brief Business logic for aggregating dashboard health status from validation records.
+/// @}
+void health_service(void);
+
+/// @defgroup HealthService "HealthService"
+/// @{
+/// @brief Aggregate latest dashboard validation state and manage persisted health report lifecycle.
+/// @post Exposes health summary aggregation and validation report deletion operations.
+/// @pre Service is constructed with a live SQLAlchemy session and optional config manager.
+/// @}
+void HealthService(void);
+
+/// @defgroup llm_prompt_templates "llm_prompt_templates"
+/// @{
+/// @brief Provide default LLM prompt templates and normalization helpers for runtime usage.
+/// @invariant All required prompt template keys are always present after normalization.
+/// @}
+void llm_prompt_templates(void);
+
+/// @defgroup DEFAULT_LLM_PROMPTS "DEFAULT_LLM_PROMPTS"
+/// @{
+/// @brief Default prompt templates used by documentation, dashboard validation, and git commit generation.
+/// @}
+void DEFAULT_LLM_PROMPTS(void);
+
+/// @defgroup DEFAULT_LLM_PROVIDER_BINDINGS "DEFAULT_LLM_PROVIDER_BINDINGS"
+/// @{
+/// @brief Default provider binding per task domain.
+/// @}
+void DEFAULT_LLM_PROVIDER_BINDINGS(void);
+
+/// @defgroup DEFAULT_LLM_ASSISTANT_SETTINGS "DEFAULT_LLM_ASSISTANT_SETTINGS"
+/// @{
+/// @brief Default planner settings for assistant chat intent model/provider resolution.
+/// @}
+void DEFAULT_LLM_ASSISTANT_SETTINGS(void);
+
+/// @defgroup normalize_llm_settings "normalize_llm_settings"
+/// @{
+/// @brief Ensure llm settings contain stable schema with prompts section and default templates.
+/// @post Returned dict contains prompts with all required template keys.
+/// @pre llm_settings is dictionary-like value or None.
+/// @}
+void normalize_llm_settings(void);
+
+/// @defgroup is_multimodal_model "is_multimodal_model"
+/// @{
+/// @brief Heuristically determine whether model supports image input required for dashboard validation.
+/// @deprecated Use the explicit `db_provider.is_multimodal` flag instead (see migration 9f8e7d6c5b4a).
+/// @}
+void is_multimodal_model(void);
+
+/// @defgroup resolve_bound_provider_id "resolve_bound_provider_id"
+/// @{
+/// @brief Resolve provider id configured for a task binding with fallback to default provider.
+/// @post Returns configured provider id or fallback id/empty string when not defined.
+/// @pre llm_settings is normalized or raw dict from config.
+/// @}
+void resolve_bound_provider_id(void);
+
+/// @defgroup render_prompt "render_prompt"
+/// @{
+/// @brief Render prompt template using deterministic placeholder replacement with graceful fallback.
+/// @post Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.
+/// @pre template is a string and variables values are already stringifiable.
+/// @}
+void render_prompt(void);
+
+/// @defgroup llm_provider "llm_provider"
+/// @{
+/// @brief Service for managing LLM provider configurations with encrypted API keys.
+/// @}
+void llm_provider(void);
+
+/// @defgroup mask_api_key "mask_api_key"
+/// @{
+/// @brief Mask an API key for safe display, showing first 4 and last 4 characters.
+/// @post Returns "****" for very short keys; "{first 2}...{last 2}" for <=8 chars;
+/// @pre api_key is a plaintext string or None.
+/// @}
+void mask_api_key(void);
+
+/// @defgroup is_masked_or_placeholder "is_masked_or_placeholder"
+/// @{
+/// @brief Predicate: True when api_key is None, empty, "********", or contains "...".
+/// @post Returns True only for non-real-key values.
+/// @pre api_key can be None.
+/// @}
+void is_masked_or_placeholder(void);
+
+/// @defgroup _require_fernet_key "_require_fernet_key"
+/// @{
+/// @brief Load and validate the Fernet key used for secret encryption.
+/// @invariant Encryption initialization never falls back to a hardcoded secret.
+/// @post Returns validated key bytes ready for Fernet initialization.
+/// @pre ENCRYPTION_KEY environment variable must be set to a valid Fernet key.
+/// @}
+void _require_fernet_key(void);
+
+/// @defgroup EncryptionManager "EncryptionManager"
+/// @{
+/// @brief Handles encryption and decryption of sensitive data like API keys.
+/// @invariant Uses only a validated secret key from environment.
+/// @post Manager exposes reversible encrypt/decrypt operations for persisted secrets.
+/// @pre ENCRYPTION_KEY is configured with a valid Fernet key before instantiation.
+/// @}
+void EncryptionManager(void);
+
+/// @defgroup LLMProviderService "LLMProviderService"
+/// @{
+/// @brief Service to manage LLM provider lifecycle.
+/// @}
+void LLMProviderService(void);
+
+/// @defgroup MaintenancePackage "MaintenancePackage"
+/// @{
+/// @brief Maintenance Banner service package. Re-exports all public orchestrators and helpers.
+/// @}
+void MaintenancePackage(void);
+
+/// @defgroup MaintenanceBannerRenderer "MaintenanceBannerRenderer"
+/// @{
+/// @brief Banner text rendering and rebuild helpers. Build aggregated markdown from
+/// @}
+void MaintenanceBannerRenderer(void);
+
+/// @defgroup build_banner_text "build_banner_text"
+/// @{
+/// @brief Build aggregated banner markdown text from events using settings template.
+/// @}
+void build_banner_text(void);
+
+/// @defgroup _build_banner_text_for_dashboard "_build_banner_text_for_dashboard"
+/// @{
+/// @brief Build aggregated banner text for a banner based on all active events linked to it.
+/// @}
+void _build_banner_text_for_dashboard(void);
+
+/// @defgroup rebuild_banner "rebuild_banner"
+/// @{
+/// @brief Rebuild aggregated banner text for a banner and update the Superset chart.
+/// @}
+void rebuild_banner(void);
+
+/// @defgroup MaintenanceChartManager "MaintenanceChartManager"
+/// @{
+/// @brief Chart operations for maintenance banners: create/get banner charts, process
+/// @}
+void MaintenanceChartManager(void);
+
+/// @defgroup ensure_banner_chart "ensure_banner_chart"
+/// @{
+/// @brief Get or create a MaintenanceDashboardBanner for a dashboard in the target environment.
+/// @}
+void ensure_banner_chart(void);
+
+/// @defgroup _process_dashboards_for_start "_process_dashboards_for_start"
+/// @{
+/// @brief Process each dashboard for a start maintenance event: ensure banner chart,
+/// @}
+void _process_dashboards_for_start(void);
+
+/// @defgroup _process_states_for_end "_process_states_for_end"
+/// @{
+/// @brief Process each dashboard state for an end maintenance event: if other events
+/// @}
+void _process_states_for_end(void);
+
+/// @defgroup MaintenanceDashboardScanner "MaintenanceDashboardScanner"
+/// @{
+/// @brief Dashboard discovery and filtering helpers for maintenance banner feature.
+/// @}
+void MaintenanceDashboardScanner(void);
+
+/// @defgroup find_affected_dashboards "find_affected_dashboards"
+/// @{
+/// @brief Find all dashboard IDs whose datasets reference any of the given tables.
+/// @}
+void find_affected_dashboards(void);
+
+/// @defgroup _get_linked_dashboards "_get_linked_dashboards"
+/// @{
+/// @brief Fetch linked dashboards for a dataset from Superset.
+/// @}
+void _get_linked_dashboards(void);
+
+/// @defgroup _apply_dashboard_filters "_apply_dashboard_filters"
+/// @{
+/// @brief Apply scope (published/draft/all), excluded, and forced filters from settings.
+/// @}
+void _apply_dashboard_filters(void);
+
+/// @defgroup _resolve_dashboard_title "_resolve_dashboard_title"
+/// @{
+/// @brief Resolve dashboard title from Superset by ID.
+/// @}
+void _resolve_dashboard_title(void);
+
+/// @defgroup MaintenanceOrchestrators "MaintenanceOrchestrators"
+/// @{
+/// @brief C4 orchestrators for maintenance event lifecycle: start, end, end-all.
+/// @}
+void MaintenanceOrchestrators(void);
+
+/// @defgroup build_idempotency_key "build_idempotency_key"
+/// @{
+/// @brief Build idempotency key from (tables, start_time, end_time). Sorted lowercased tables, ISO timestamps.
+/// @post Returns a tuple of (frozenset(str), str|None, str|None) for DB comparison.
+/// @pre tables is a list of strings. start_time is a datetime or None. end_time is a datetime or None.
+/// @}
+void build_idempotency_key(void);
+
+/// @defgroup mapping_service "mapping_service"
+/// @{
+/// @brief Orchestrates database fetching and fuzzy matching suggestions.
+/// @invariant Suggestions are based on database names.
+/// @post Exposes stateless mapping suggestion orchestration over configured environments.
+/// @pre source/target environment identifiers are provided by caller.
+/// @}
+void mapping_service(void);
+
+/// @defgroup MappingService "MappingService"
+/// @{
+/// @brief Service for handling database mapping logic.
+/// @post Provides client resolution and mapping suggestion methods.
+/// @pre config_manager exposes get_environments() with environment objects containing id.
+/// @}
+void MappingService(void);
+
+/// @defgroup notifications "notifications"
+/// @{
+/// @brief Notification service package root.
+/// @}
+void notifications(void);
+
+/// @defgroup providers "providers"
+/// @{
+/// @brief Defines abstract base and concrete implementations for external notification delivery.
+/// @invariant Sensitive credentials must be handled via encrypted config.
+/// @post Each provider exposes async send contract returning boolean delivery outcome.
+/// @pre Provider configuration dictionaries are supplied by trusted configuration sources.
+/// @}
+void providers(void);
+
+/// @defgroup NotificationProvider "NotificationProvider"
+/// @{
+/// @brief Abstract base class for all notification providers.
+/// @}
+void NotificationProvider(void);
+
+/// @defgroup SMTPProvider "SMTPProvider"
+/// @{
+/// @brief Delivers notifications via SMTP.
+/// @}
+void SMTPProvider(void);
+
+/// @defgroup TelegramProvider "TelegramProvider"
+/// @{
+/// @brief Delivers notifications via Telegram Bot API.
+/// @}
+void TelegramProvider(void);
+
+/// @defgroup SlackProvider "SlackProvider"
+/// @{
+/// @brief Delivers notifications via Slack Webhooks or API.
+/// @}
+void SlackProvider(void);
+
+/// @defgroup service "service"
+/// @{
+/// @brief Orchestrates notification routing based on user preferences and policy context.
+/// @invariant NotificationService maintains singleton pattern for per-channel notifications
+/// @post Notification dispatched via configured providers
+/// @pre channel_config is loaded
+/// @}
+void service(void);
+
+/// @defgroup NotificationService "NotificationService"
+/// @{
+/// @brief Routes validation reports to appropriate users and channels.
+/// @post Service can resolve targets and dispatch provider sends without mutating validation records.
+/// @pre Service receives a live DB session and configuration manager with notification payload settings.
+/// @}
+void NotificationService(void);
+
+/// @defgroup profile_preference_service "profile_preference_service"
+/// @{
+/// @brief Profile preference persistence — read, update, and normalize user dashboard filter preferences
+/// @}
+void profile_preference_service(void);
+
+/// @defgroup ProfilePreferenceService "ProfilePreferenceService"
+/// @{
+/// @brief Handles profile preference persistence, validation, and token encryption.
+/// @post Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.
+/// @pre db session is active.
+/// @}
+void ProfilePreferenceService(void);
+
+/// @defgroup get_my_preference "get_my_preference"
+/// @{
+/// @brief Return current user's persisted preference or default non-configured view.
+/// @post Returned payload belongs to current_user only.
+/// @pre current_user is authenticated.
+/// @}
+void get_my_preference(void);
+
+/// @defgroup get_dashboard_filter_binding "get_dashboard_filter_binding"
+/// @{
+/// @brief Return only dashboard-filter fields required by dashboards listing hot path.
+/// @post Returns normalized username and profile-default filter toggles without security summary expansion.
+/// @pre current_user is authenticated.
+/// @}
+void get_dashboard_filter_binding(void);
+
+/// @defgroup update_my_preference "update_my_preference"
+/// @{
+/// @brief Validate and persist current user's profile preference in self-scoped mode.
+/// @post Preference row for current_user is created/updated when validation passes.
+/// @pre current_user is authenticated and payload is provided.
+/// @}
+void update_my_preference(void);
+
+/// @defgroup _to_preference_payload "_to_preference_payload"
+/// @{
+/// @brief Map ORM preference row to API DTO with token metadata.
+/// @post Returns normalized ProfilePreference object.
+/// @pre preference row can contain nullable optional fields.
+/// @}
+void _to_preference_payload(void);
+
+/// @defgroup _build_default_preference "_build_default_preference"
+/// @{
+/// @brief Delegate to ProfileUtils.build_default_preference.
+/// @}
+void _build_default_preference(void);
+
+/// @defgroup _get_preference_row "_get_preference_row"
+/// @{
+/// @brief Return persisted preference row for user or None.
+/// @}
+void _get_preference_row(void);
+
+/// @defgroup _get_or_create_preference_row "_get_or_create_preference_row"
+/// @{
+/// @brief Return existing preference row or create new unsaved row.
+/// @}
+void _get_or_create_preference_row(void);
+
+/// @defgroup profile_service "profile_service"
+/// @{
+/// @brief Composite facade orchestrating profile preference persistence, Superset account lookup,
+/// @}
+void profile_service(void);
+
+/// @defgroup ProfileService "ProfileService"
+/// @{
+/// @brief Facade that composes ProfilePreferenceService, SupersetLookupService, and
+/// @}
+void ProfileService(void);
+
+/// @defgroup ProfileUtils "ProfileUtils"
+/// @{
+/// @brief Pure utility helpers for profile data sanitization, normalization, and secret masking.
+/// @}
+void ProfileUtils(void);
+
+/// @defgroup ProfileValidationError "ProfileValidationError"
+/// @{
+/// @brief Domain validation error for profile preference update requests.
+/// @}
+void ProfileValidationError(void);
+
+/// @defgroup EnvironmentNotFoundError "EnvironmentNotFoundError"
+/// @{
+/// @brief Raised when environment_id from lookup request is unknown in app configuration.
+/// @}
+void EnvironmentNotFoundError(void);
+
+/// @defgroup ProfileAuthorizationError "ProfileAuthorizationError"
+/// @{
+/// @brief Raised when caller attempts cross-user preference mutation.
+/// @}
+void ProfileAuthorizationError(void);
+
+/// @defgroup sanitize_text "sanitize_text"
+/// @{
+/// @brief Normalize optional text into trimmed form or None.
+/// @}
+void sanitize_text(void);
+
+/// @defgroup sanitize_secret "sanitize_secret"
+/// @{
+/// @brief Normalize secret input into trimmed form or None.
+/// @}
+void sanitize_secret(void);
+
+/// @defgroup sanitize_username "sanitize_username"
+/// @{
+/// @brief Normalize raw username into trimmed form or None for empty input.
+/// @}
+void sanitize_username(void);
+
+/// @defgroup normalize_username "normalize_username"
+/// @{
+/// @brief Apply deterministic trim+lower normalization for actor matching.
+/// @}
+void normalize_username(void);
+
+/// @defgroup normalize_start_page "normalize_start_page"
+/// @{
+/// @brief Normalize supported start page aliases to canonical values.
+/// @}
+void normalize_start_page(void);
+
+/// @defgroup normalize_density "normalize_density"
+/// @{
+/// @brief Normalize supported density aliases to canonical values.
+/// @}
+void normalize_density(void);
+
+/// @defgroup mask_secret_value "mask_secret_value"
+/// @{
+/// @brief Build a safe display value for sensitive secrets.
+/// @}
+void mask_secret_value(void);
+
+/// @defgroup validate_update_payload "validate_update_payload"
+/// @{
+/// @brief Validate username/toggle constraints for preference mutation.
+/// @post Returns validation errors list; empty list means valid.
+/// @}
+void validate_update_payload(void);
+
+/// @defgroup build_default_preference "build_default_preference"
+/// @{
+/// @brief Build non-persisted default preference DTO for unconfigured users.
+/// @}
+void build_default_preference(void);
+
+/// @defgroup normalize_owner_tokens "normalize_owner_tokens"
+/// @{
+/// @brief Normalize owners payload into deduplicated lower-cased tokens.
+/// @}
+void normalize_owner_tokens(void);
+
+/// @defgroup rbac_permission_catalog "rbac_permission_catalog"
+/// @{
+/// @brief Discovers declared RBAC permissions from API routes/plugins and synchronizes them into auth database.
+/// @}
+void rbac_permission_catalog(void);
+
+/// @defgroup HAS_PERMISSION_PATTERN "HAS_PERMISSION_PATTERN"
+/// @{
+/// @brief Regex pattern for extracting has_permission("resource", "ACTION") declarations.
+/// @}
+void HAS_PERMISSION_PATTERN(void);
+
+/// @defgroup ROUTES_DIR "ROUTES_DIR"
+/// @{
+/// @brief Absolute directory path where API route RBAC declarations are defined.
+/// @}
+void ROUTES_DIR(void);
+
+/// @defgroup _iter_route_files "_iter_route_files"
+/// @{
+/// @brief Iterates API route files that may contain RBAC declarations.
+/// @post Yields Python files excluding test and cache directories.
+/// @pre ROUTES_DIR points to backend/src/api/routes.
+/// @}
+void _iter_route_files(void);
+
+/// @defgroup _discover_route_permissions "_discover_route_permissions"
+/// @{
+/// @brief Extracts explicit has_permission declarations from API route source code.
+/// @post Returns unique set of (resource, action) pairs declared in route guards.
+/// @pre Route files are readable UTF-8 text files.
+/// @}
+void _discover_route_permissions(void);
+
+/// @defgroup _discover_route_permissions_cached "_discover_route_permissions_cached"
+/// @{
+/// @brief Cache route permission discovery because route source files are static during normal runtime.
+/// @post Returns stable discovered route permission pairs without repeated filesystem scans.
+/// @pre None.
+/// @}
+void _discover_route_permissions_cached(void);
+
+/// @defgroup _discover_plugin_execute_permissions "_discover_plugin_execute_permissions"
+/// @{
+/// @brief Derives dynamic task permissions of form plugin:{plugin_id}:EXECUTE from plugin registry.
+/// @post Returns unique plugin EXECUTE permissions if loader is available.
+/// @pre plugin_loader is optional and may expose get_all_plugin_configs.
+/// @}
+void _discover_plugin_execute_permissions(void);
+
+/// @defgroup _discover_plugin_execute_permissions_cached "_discover_plugin_execute_permissions_cached"
+/// @{
+/// @brief Cache dynamic plugin EXECUTE permission pairs by normalized plugin id tuple.
+/// @post Returns stable permission tuple without repeated plugin catalog expansion.
+/// @pre plugin_ids is a deterministic tuple of plugin ids.
+/// @}
+void _discover_plugin_execute_permissions_cached(void);
+
+/// @defgroup discover_declared_permissions "discover_declared_permissions"
+/// @{
+/// @brief Builds canonical RBAC permission catalog from routes and plugin registry.
+/// @post Returns union of route-declared and dynamic plugin EXECUTE permissions.
+/// @pre plugin_loader may be provided for dynamic task plugin permission discovery.
+/// @}
+void discover_declared_permissions(void);
+
+/// @defgroup sync_permission_catalog "sync_permission_catalog"
+/// @{
+/// @brief Persists missing RBAC permission pairs into auth database.
+/// @post Missing permissions are inserted; existing permissions remain untouched.
+/// @pre declared_permissions is an iterable of (resource, action) tuples.
+/// @}
+void sync_permission_catalog(void);
+
+/// @defgroup reports "reports"
+/// @{
+/// @brief Report service package root.
+/// @}
+void reports(void);
+
+/// @defgroup normalizer "normalizer"
+/// @{
+/// @brief Convert task manager task objects into canonical unified TaskReport entities with deterministic fallback behavior.
+/// @invariant Normalizer instance maintains consistent field order
+/// @post Returns Normalizer output with normalized fields
+/// @pre session is active and valid
+/// @}
+void normalizer(void);
+
+/// @defgroup status_to_report_status "status_to_report_status"
+/// @{
+/// @brief Normalize internal task status to canonical report status.
+/// @post Always returns one of canonical ReportStatus values.
+/// @pre status may be known or unknown string/enum value.
+/// @}
+void status_to_report_status(void);
+
+/// @defgroup build_summary "build_summary"
+/// @{
+/// @brief Build deterministic user-facing summary from task payload and status.
+/// @post Returns non-empty summary text.
+/// @pre report_status is canonical; plugin_id may be unknown.
+/// @}
+void build_summary(void);
+
+/// @defgroup extract_error_context "extract_error_context"
+/// @{
+/// @brief Extract normalized error context and next actions for failed/partial reports.
+/// @post Returns ErrorContext for failed/partial when context exists; otherwise None.
+/// @pre task is a valid Task object.
+/// @}
+void extract_error_context(void);
+
+/// @defgroup normalize_task_report "normalize_task_report"
+/// @{
+/// @brief Convert one Task to canonical TaskReport envelope.
+/// @post Returns TaskReport with required fields and deterministic fallback behavior.
+/// @pre task has valid id and plugin_id fields.
+/// @}
+void normalize_task_report(void);
+
+/// @defgroup report_service "report_service"
+/// @{
+/// @brief Aggregate, normalize, filter, and paginate task reports for unified list/detail API use cases.
+/// @invariant ReportService maintains consistent report structure
+/// @post Returns Report with generated summary
+/// @pre session is active and valid
+/// @}
+void report_service(void);
+
+/// @defgroup ReportsService "ReportsService"
+/// @{
+/// @brief Service layer for list/detail report retrieval and normalization.
+/// @invariant Service methods are read-only over task history source.
+/// @post Provides deterministic list/detail report responses.
+/// @pre TaskManager dependency is initialized.
+/// @}
+void ReportsService(void);
+
+/// @defgroup type_profiles "type_profiles"
+/// @{
+/// @brief Deterministic mapping of plugin/task identifiers to canonical report task types and fallback profile metadata.
+/// @}
+void type_profiles(void);
+
+/// @defgroup PLUGIN_TO_TASK_TYPE "PLUGIN_TO_TASK_TYPE"
+/// @{
+/// @brief Maps plugin identifiers to normalized report task types.
+/// @}
+void PLUGIN_TO_TASK_TYPE(void);
+
+/// @defgroup TASK_TYPE_PROFILES "TASK_TYPE_PROFILES"
+/// @{
+/// @brief Profile metadata registry for each normalized task type.
+/// @}
+void TASK_TYPE_PROFILES(void);
+
+/// @defgroup resolve_task_type "resolve_task_type"
+/// @{
+/// @brief Resolve canonical task type from plugin/task identifier with guaranteed fallback.
+/// @post Always returns one of TaskType enum values.
+/// @pre plugin_id may be None or unknown.
+/// @}
+void resolve_task_type(void);
+
+/// @defgroup get_type_profile "get_type_profile"
+/// @{
+/// @brief Return deterministic profile metadata for a task type.
+/// @post Returns a profile dict and never raises for unknown types.
+/// @pre task_type may be known or unknown.
+/// @}
+void get_type_profile(void);
+
+/// @defgroup ResourceServiceModule "ResourceServiceModule"
+/// @{
+/// @brief Shared service for fetching resource data with Git status and task status
+/// @invariant All resources include metadata about their current state
+/// @}
+void ResourceServiceModule(void);
+
+/// @defgroup ResourceService "ResourceService"
+/// @{
+/// @brief Provides centralized access to resource data with enhanced metadata
+/// @}
+void ResourceService(void);
+
+/// @defgroup security_badge_service "security_badge_service"
+/// @{
+/// @brief Builds security summary and permission badges for profile UI — role extraction,
+/// @}
+void security_badge_service(void);
+
+/// @defgroup SecurityBadgeService "SecurityBadgeService"
+/// @{
+/// @brief Builds security summary with role names and permission badges for profile UI display.
+/// @post build_security_summary returns ProfileSecuritySummary with deterministic sorted permissions.
+/// @pre plugin_loader may be None for degraded permission discovery.
+/// @}
+void SecurityBadgeService(void);
+
+/// @defgroup build_security_summary "build_security_summary"
+/// @{
+/// @brief Build read-only security snapshot with role and permission badges.
+/// @post Returns deterministic security projection for profile UI.
+/// @pre current_user is authenticated.
+/// @}
+void build_security_summary(void);
+
+/// @defgroup _collect_user_permission_pairs "_collect_user_permission_pairs"
+/// @{
+/// @brief Collect effective permission tuples from current user's roles.
+/// @post Returns unique normalized (resource, ACTION) tuples.
+/// @pre current_user can include role/permission graph.
+/// @}
+void _collect_user_permission_pairs(void);
+
+/// @defgroup _format_permission_key "_format_permission_key"
+/// @{
+/// @brief Convert normalized permission pair to compact UI key.
+/// @}
+void _format_permission_key(void);
+
+/// @defgroup SqlTableExtractorModule "SqlTableExtractorModule"
+/// @{
+/// @brief Three-phase SQL+Jinja table name extractor for virtual datasets as per FR-003.
+/// @}
+void SqlTableExtractorModule(void);
+
+/// @defgroup detect_jinja_spans "detect_jinja_spans"
+/// @{
+/// @brief Phase 1: Split raw SQL text into Jinja spans and SQL spans.
+/// @post Returns a list of (span_type: str, text: str) tuples.
+/// @pre raw_sql is a string (possibly empty).
+/// @}
+void detect_jinja_spans(void);
+
+/// @defgroup extract_tables_from_jinja "extract_tables_from_jinja"
+/// @{
+/// @brief Phase 2: Extract "schema.table" references from Jinja string values.
+/// @}
+void extract_tables_from_jinja(void);
+
+/// @defgroup is_string_literal "is_string_literal"
+/// @{
+/// @brief Check if a sqlparse Token is a string literal (not a schema.table identifier).
+/// @post Returns True if the token is a string/Single/Literal.String.
+/// @pre token is a sqlparse Token.
+/// @}
+void is_string_literal(void);
+
+/// @defgroup extract_tables_from_sql_span "extract_tables_from_sql_span"
+/// @{
+/// @brief Phase 3: Extract schema.table references from SQL text using regex + sqlparse filtering.
+/// @}
+void extract_tables_from_sql_span(void);
+
+/// @defgroup extract_tables_from_sql "extract_tables_from_sql"
+/// @{
+/// @brief Three-phase entry point: extract all schema.table references from raw SQL+Jinja text.
+/// @post Returns a set of lowercased fully-qualified table names (schema.table format).
+/// @pre raw_sql is a string (possibly empty).
+/// @}
+void extract_tables_from_sql(void);
+
+/// @defgroup superset_lookup_service "superset_lookup_service"
+/// @{
+/// @brief Environment-scoped Superset account lookup with degradation fallback for network failures.
+/// @}
+void superset_lookup_service(void);
+
+/// @defgroup SupersetLookupService "SupersetLookupService"
+/// @{
+/// @brief Resolves environments and queries Superset users in selected environment,
+/// @}
+void SupersetLookupService(void);
+
+/// @defgroup _resolve_environment "_resolve_environment"
+/// @{
+/// @brief Resolve environment model from configured environments by id.
+/// @post Returns environment object when found else None.
+/// @pre environment_id is provided.
+/// @}
+void _resolve_environment(void);
+
+/// @defgroup ValidationRunService "ValidationRunService"
+/// @{
+/// @brief Business logic for validation run queries: list, detail, delete.
+/// @}
+void ValidationRunService(void);
+
+/// @defgroup _resolve_task_name "_resolve_task_name"
+/// @{
+/// @}
+void _resolve_task_name(void);
+
+/// @defgroup ValidationService "ValidationService"
+/// @{
+/// @brief Business logic for validation task CRUD and trigger-run.
+/// @}
+void ValidationService(void);
+
+/// @defgroup ValidationTaskService "ValidationTaskService"
+/// @{
+/// @brief Validation task (policy) CRUD with provider validation and trigger-run.
+/// @}
+void ValidationTaskService(void);
+
+/// @defgroup _validate_provider "_validate_provider"
+/// @{
+/// @}
+void _validate_provider(void);
+
+/// @defgroup _validate_environment "_validate_environment"
+/// @{
+/// @}
+void _validate_environment(void);
+
+/// @defgroup _policy_to_response "_policy_to_response"
+/// @{
+/// @}
+void _policy_to_response(void);
+
+/// @defgroup TestSessionConfig "TestSessionConfig"
+/// @{
+/// @brief Shared pytest fixtures and session configuration for backend tests.
+/// @post Database tables exist before test session executes.
+/// @pre All test modules use sys.path patching to import from src/.
+/// @}
+void TestSessionConfig(void);
+
+/// @defgroup TestArchiveParser "TestArchiveParser"
+/// @{
+/// @brief Unit tests for MigrationArchiveParser ZIP extraction contract.
+/// @}
+void TestArchiveParser(void);
+
+/// @defgroup test_extract_objects_from_zip_collects_all_types "test_extract_objects_from_zip_collects_all_types"
+/// @{
+/// @brief Verify archive parser collects dashboard/chart/dataset YAML objects into typed buckets.
+/// @}
+void test_extract_objects_from_zip_collects_all_types(void);
+
+/// @defgroup TestDryRunOrchestrator "TestDryRunOrchestrator"
+/// @{
+/// @brief Unit tests for MigrationDryRunService diff and risk computation contracts.
+/// @}
+void TestDryRunOrchestrator(void);
+
+/// @defgroup _load_fixture "_load_fixture"
+/// @{
+/// @brief Load canonical migration dry-run fixture payload used by deterministic orchestration assertions.
+/// @}
+void _load_fixture(void);
+
+/// @defgroup test_migration_dry_run_service_builds_diff_and_risk "test_migration_dry_run_service_builds_diff_and_risk"
+/// @{
+/// @brief Verify dry-run orchestration returns stable diff summary and required risk codes.
+/// @}
+void test_migration_dry_run_service_builds_diff_and_risk(void);
+
+/// @defgroup test_git_service_get_repo_path_guard "test_git_service_get_repo_path_guard"
+/// @{
+/// @}
+void test_git_service_get_repo_path_guard(void);
+
+/// @defgroup test_git_service_get_repo_path_recreates_base_dir "test_git_service_get_repo_path_recreates_base_dir"
+/// @{
+/// @}
+void test_git_service_get_repo_path_recreates_base_dir(void);
+
+/// @defgroup test_superset_client_import_dashboard_guard "test_superset_client_import_dashboard_guard"
+/// @{
+/// @}
+void test_superset_client_import_dashboard_guard(void);
+
+/// @defgroup test_git_service_init_repo_reclones_when_path_is_not_a_git_repo "test_git_service_init_repo_reclones_when_path_is_not_a_git_repo"
+/// @{
+/// @}
+void test_git_service_init_repo_reclones_when_path_is_not_a_git_repo(void);
+
+/// @defgroup test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults "test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults"
+/// @{
+/// @}
+void test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults(void);
+
+/// @defgroup test_git_service_configure_identity_updates_repo_local_config "test_git_service_configure_identity_updates_repo_local_config"
+/// @{
+/// @}
+void test_git_service_configure_identity_updates_repo_local_config(void);
+
+/// @defgroup TestGitServiceGiteaPr "TestGitServiceGiteaPr"
+/// @{
+/// @brief Validate Gitea PR creation fallback behavior when configured server URL is stale.
+/// @invariant A 404 from primary Gitea URL retries once against remote-url host when different.
+/// @}
+void TestGitServiceGiteaPr(void);
+
+/// @defgroup test_derive_server_url_from_remote_strips_credentials "test_derive_server_url_from_remote_strips_credentials"
+/// @{
+/// @brief Ensure helper returns host base URL and removes embedded credentials.
+/// @post Result is scheme+host only.
+/// @pre remote_url is an https URL with username/token.
+/// @}
+void test_derive_server_url_from_remote_strips_credentials(void);
+
+/// @defgroup test_create_gitea_pull_request_retries_with_remote_host_on_404 "test_create_gitea_pull_request_retries_with_remote_host_on_404"
+/// @{
+/// @brief Verify create_gitea_pull_request retries with remote URL host after primary 404.
+/// @post Method returns success payload from fallback request.
+/// @pre primary server_url differs from remote_url host.
+/// @}
+void test_create_gitea_pull_request_retries_with_remote_host_on_404(void);
+
+/// @defgroup test_create_gitea_pull_request_returns_branch_error_when_target_missing "test_create_gitea_pull_request_returns_branch_error_when_target_missing"
+/// @{
+/// @brief Ensure Gitea 404 on PR creation is mapped to actionable target-branch validation error.
+/// @post Service raises HTTPException 400 with explicit missing target branch message.
+/// @pre PR create call returns 404 and target branch is absent.
+/// @}
+void test_create_gitea_pull_request_returns_branch_error_when_target_missing(void);
+
+/// @defgroup TestMappingService "TestMappingService"
+/// @{
+/// @brief Unit tests for the IdMappingService matching UUIDs to integer IDs.
+/// @}
+void TestMappingService(void);
+
+/// @defgroup test_sync_environment_upserts_correctly "test_sync_environment_upserts_correctly"
+/// @{
+/// @}
+void test_sync_environment_upserts_correctly(void);
+
+/// @defgroup test_get_remote_id_returns_integer "test_get_remote_id_returns_integer"
+/// @{
+/// @}
+void test_get_remote_id_returns_integer(void);
+
+/// @defgroup test_get_remote_ids_batch_returns_dict "test_get_remote_ids_batch_returns_dict"
+/// @{
+/// @}
+void test_get_remote_ids_batch_returns_dict(void);
+
+/// @defgroup test_sync_environment_updates_existing_mapping "test_sync_environment_updates_existing_mapping"
+/// @{
+/// @}
+void test_sync_environment_updates_existing_mapping(void);
+
+/// @defgroup test_sync_environment_skips_resources_without_uuid "test_sync_environment_skips_resources_without_uuid"
+/// @{
+/// @}
+void test_sync_environment_skips_resources_without_uuid(void);
+
+/// @defgroup test_sync_environment_handles_api_error_gracefully "test_sync_environment_handles_api_error_gracefully"
+/// @{
+/// @}
+void test_sync_environment_handles_api_error_gracefully(void);
+
+/// @defgroup test_get_remote_id_returns_none_for_missing "test_get_remote_id_returns_none_for_missing"
+/// @{
+/// @}
+void test_get_remote_id_returns_none_for_missing(void);
+
+/// @defgroup test_get_remote_ids_batch_returns_empty_for_empty_input "test_get_remote_ids_batch_returns_empty_for_empty_input"
+/// @{
+/// @}
+void test_get_remote_ids_batch_returns_empty_for_empty_input(void);
+
+/// @defgroup test_mapping_service_alignment_with_test_data "test_mapping_service_alignment_with_test_data"
+/// @{
+/// @}
+void test_mapping_service_alignment_with_test_data(void);
+
+/// @defgroup test_sync_environment_requires_existing_env "test_sync_environment_requires_existing_env"
+/// @{
+/// @}
+void test_sync_environment_requires_existing_env(void);
+
+/// @defgroup test_sync_environment_deletes_stale_mappings "test_sync_environment_deletes_stale_mappings"
+/// @{
+/// @}
+void test_sync_environment_deletes_stale_mappings(void);
+
+/// @defgroup TestMigrationEngine "TestMigrationEngine"
+/// @{
+/// @brief Unit tests for MigrationEngine's cross-filter patching algorithms.
+/// @}
+void TestMigrationEngine(void);
+
+/// @defgroup MockMappingService "MockMappingService"
+/// @{
+/// @brief Deterministic mapping service double for native filter ID remapping scenarios.
+/// @invariant Returns mappings only for requested UUID keys present in seeded map.
+/// @}
+void MockMappingService(void);
+
+/// @defgroup _write_dashboard_yaml "_write_dashboard_yaml"
+/// @{
+/// @brief Serialize dashboard metadata into YAML fixture with json_metadata payload for patch tests.
+/// @}
+void _write_dashboard_yaml(void);
+
+/// @defgroup test_patch_dashboard_metadata_replaces_chart_ids "test_patch_dashboard_metadata_replaces_chart_ids"
+/// @{
+/// @brief Verify native filter target chartId values are remapped via mapping service results.
+/// @}
+void test_patch_dashboard_metadata_replaces_chart_ids(void);
+
+/// @defgroup test_patch_dashboard_metadata_replaces_dataset_ids "test_patch_dashboard_metadata_replaces_dataset_ids"
+/// @{
+/// @brief Verify native filter target datasetId values are remapped via mapping service results.
+/// @}
+void test_patch_dashboard_metadata_replaces_dataset_ids(void);
+
+/// @defgroup test_patch_dashboard_metadata_skips_when_no_metadata "test_patch_dashboard_metadata_skips_when_no_metadata"
+/// @{
+/// @brief Ensure dashboard files without json_metadata are left unchanged by metadata patching.
+/// @}
+void test_patch_dashboard_metadata_skips_when_no_metadata(void);
+
+/// @defgroup test_patch_dashboard_metadata_handles_missing_targets "test_patch_dashboard_metadata_handles_missing_targets"
+/// @{
+/// @brief Verify patching updates mapped targets while preserving unmapped native filter IDs.
+/// @}
+void test_patch_dashboard_metadata_handles_missing_targets(void);
+
+/// @defgroup test_extract_chart_uuids_from_archive "test_extract_chart_uuids_from_archive"
+/// @{
+/// @brief Verify chart archive scan returns complete local chart id-to-uuid mapping.
+/// @}
+void test_extract_chart_uuids_from_archive(void);
+
+/// @defgroup test_transform_yaml_replaces_database_uuid "test_transform_yaml_replaces_database_uuid"
+/// @{
+/// @brief Ensure dataset YAML database_uuid fields are replaced when source UUID mapping exists.
+/// @}
+void test_transform_yaml_replaces_database_uuid(void);
+
+/// @defgroup test_transform_yaml_ignores_unmapped_uuid "test_transform_yaml_ignores_unmapped_uuid"
+/// @{
+/// @brief Ensure transform_yaml leaves dataset files untouched when database_uuid is not mapped.
+/// @}
+void test_transform_yaml_ignores_unmapped_uuid(void);
+
+/// @defgroup test_transform_zip_end_to_end "test_transform_zip_end_to_end"
+/// @{
+/// @brief Validate full ZIP transform pipeline remaps datasets and dashboard cross-filter chart IDs.
+/// @}
+void test_transform_zip_end_to_end(void);
+
+/// @defgroup test_transform_zip_invalid_path "test_transform_zip_invalid_path"
+/// @{
+/// @brief Verify transform_zip returns False when source archive path does not exist.
+/// @}
+void test_transform_zip_invalid_path(void);
+
+/// @defgroup test_transform_yaml_nonexistent_file "test_transform_yaml_nonexistent_file"
+/// @{
+/// @brief Verify transform_yaml raises FileNotFoundError for missing YAML source files.
+/// @}
+void test_transform_yaml_nonexistent_file(void);
+
+/// @defgroup test_clean_release_cli "test_clean_release_cli"
+/// @{
+/// @brief Smoke tests for the redesigned clean release CLI.
+/// @}
+void test_clean_release_cli(void);
+
+/// @defgroup test_cli_candidate_register_scaffold "test_cli_candidate_register_scaffold"
+/// @{
+/// @brief Verify candidate-register command exits successfully for valid required arguments.
+/// @}
+void test_cli_candidate_register_scaffold(void);
+
+/// @defgroup test_cli_manifest_build_scaffold "test_cli_manifest_build_scaffold"
+/// @{
+/// @brief Verify candidate-register/artifact-import/manifest-build smoke path succeeds end-to-end.
+/// @}
+void test_cli_manifest_build_scaffold(void);
+
+/// @defgroup test_cli_compliance_run_scaffold "test_cli_compliance_run_scaffold"
+/// @{
+/// @brief Verify compliance run/status/violations/report commands complete for prepared candidate.
+/// @invariant SimpleNamespace substitutes for GlobalSettings — any field rename in GlobalSettings will silently not propagate here; re-verify on GlobalSettings schema changes.
+/// @}
+void test_cli_compliance_run_scaffold(void);
+
+/// @defgroup test_cli_release_gate_commands_scaffold "test_cli_release_gate_commands_scaffold"
+/// @{
+/// @brief Verify approve/reject/publish/revoke release-gate commands execute with valid fixtures.
+/// @}
+void test_cli_release_gate_commands_scaffold(void);
+
+/// @defgroup TestCleanReleaseTui "TestCleanReleaseTui"
+/// @{
+/// @brief Unit tests for the interactive curses TUI of the clean release process.
+/// @invariant TUI initializes, handles hotkeys (F5, F10) and safely falls back without TTY.
+/// @}
+void TestCleanReleaseTui(void);
+
+/// @defgroup test_headless_fallback "test_headless_fallback"
+/// @{
+/// @}
+void test_headless_fallback(void);
+
+/// @defgroup test_tui_initial_render "test_tui_initial_render"
+/// @{
+/// @}
+void test_tui_initial_render(void);
+
+/// @defgroup test_tui_run_checks_f5 "test_tui_run_checks_f5"
+/// @{
+/// @}
+void test_tui_run_checks_f5(void);
+
+/// @defgroup test_tui_exit_f10 "test_tui_exit_f10"
+/// @{
+/// @}
+void test_tui_exit_f10(void);
+
+/// @defgroup test_tui_clear_history_f7 "test_tui_clear_history_f7"
+/// @{
+/// @}
+void test_tui_clear_history_f7(void);
+
+/// @defgroup test_tui_real_mode_bootstrap_imports_artifacts_catalog "test_tui_real_mode_bootstrap_imports_artifacts_catalog"
+/// @{
+/// @}
+void test_tui_real_mode_bootstrap_imports_artifacts_catalog(void);
+
+/// @defgroup test_clean_release_tui_v2 "test_clean_release_tui_v2"
+/// @{
+/// @brief Smoke tests for thin-client TUI action dispatch and blocked transition behavior.
+/// @}
+void test_clean_release_tui_v2(void);
+
+/// @defgroup _build_mock_stdscr "_build_mock_stdscr"
+/// @{
+/// @brief Build deterministic curses screen mock with default terminal geometry and exit key.
+/// @}
+void _build_mock_stdscr(void);
+
+/// @defgroup test_tui_f5_dispatches_run_action "test_tui_f5_dispatches_run_action"
+/// @{
+/// @brief Verify F5 key dispatch invokes run_checks exactly once before graceful exit.
+/// @}
+void test_tui_f5_dispatches_run_action(void);
+
+/// @defgroup test_tui_f5_run_smoke_reports_blocked_state "test_tui_f5_run_smoke_reports_blocked_state"
+/// @{
+/// @brief Verify blocked compliance state is surfaced after F5-triggered run action.
+/// @}
+void test_tui_f5_run_smoke_reports_blocked_state(void);
+
+/// @defgroup test_tui_non_tty_refuses_startup "test_tui_non_tty_refuses_startup"
+/// @{
+/// @brief Verify non-TTY execution returns exit code 2 with actionable stderr guidance.
+/// @}
+void test_tui_non_tty_refuses_startup(void);
+
+/// @defgroup test_tui_f8_blocked_without_facade_binding "test_tui_f8_blocked_without_facade_binding"
+/// @{
+/// @brief Verify F8 path reports disabled action instead of mutating hidden facade state.
+/// @}
+void test_tui_f8_blocked_without_facade_binding(void);
+
+/// @defgroup TestApprovalService "TestApprovalService"
+/// @{
+/// @brief Define approval gate contracts for approve/reject operations over immutable compliance evidence.
+/// @invariant Approval is allowed only for PASSED report bound to candidate; duplicate approve and foreign report must be rejected.
+/// @}
+void TestApprovalService(void);
+
+/// @defgroup _seed_candidate_with_report "_seed_candidate_with_report"
+/// @{
+/// @brief Seed candidate and report fixtures for approval gate tests.
+/// @post Repository contains candidate and report linked by candidate_id.
+/// @pre candidate_id and report_id are non-empty.
+/// @}
+void _seed_candidate_with_report(void);
+
+/// @defgroup test_approve_rejects_blocked_report "test_approve_rejects_blocked_report"
+/// @{
+/// @brief Ensure approve is rejected when latest report final status is not PASSED.
+/// @post approve_candidate raises ApprovalGateError.
+/// @pre Candidate has BLOCKED report.
+/// @}
+void test_approve_rejects_blocked_report(void);
+
+/// @defgroup test_approve_rejects_foreign_report "test_approve_rejects_foreign_report"
+/// @{
+/// @brief Ensure approve is rejected when report belongs to another candidate.
+/// @post approve_candidate raises ApprovalGateError.
+/// @pre Candidate exists, report candidate_id differs.
+/// @}
+void test_approve_rejects_foreign_report(void);
+
+/// @defgroup test_approve_rejects_duplicate_approve "test_approve_rejects_duplicate_approve"
+/// @{
+/// @brief Ensure repeated approve decision for same candidate is blocked.
+/// @post Second approve_candidate call raises ApprovalGateError.
+/// @pre Candidate has already been approved once.
+/// @}
+void test_approve_rejects_duplicate_approve(void);
+
+/// @defgroup test_reject_persists_decision_without_promoting_candidate_state "test_reject_persists_decision_without_promoting_candidate_state"
+/// @{
+/// @brief Ensure reject decision is immutable and does not promote candidate to APPROVED.
+/// @post reject_candidate persists REJECTED decision; candidate status remains unchanged.
+/// @pre Candidate has PASSED report and CHECK_PASSED lifecycle state.
+/// @}
+void test_reject_persists_decision_without_promoting_candidate_state(void);
+
+/// @defgroup test_reject_then_publish_is_blocked "test_reject_then_publish_is_blocked"
+/// @{
+/// @brief Ensure latest REJECTED decision blocks publication gate.
+/// @post publish_candidate raises PublicationGateError.
+/// @pre Candidate is rejected for passed report.
+/// @}
+void test_reject_then_publish_is_blocked(void);
+
+/// @defgroup test_candidate_manifest_services "test_candidate_manifest_services"
+/// @{
+/// @brief Test lifecycle and manifest versioning for release candidates.
+/// @}
+void test_candidate_manifest_services(void);
+
+/// @defgroup test_candidate_lifecycle_transitions "test_candidate_lifecycle_transitions"
+/// @{
+/// @brief Verify release candidate allows legal status transitions and rejects forbidden back-transitions.
+/// @}
+void test_candidate_lifecycle_transitions(void);
+
+/// @defgroup test_manifest_versioning_and_immutability "test_manifest_versioning_and_immutability"
+/// @{
+/// @brief Verify manifest versions increment monotonically and older snapshots remain queryable.
+/// @}
+void test_manifest_versioning_and_immutability(void);
+
+/// @defgroup _valid_artifacts "_valid_artifacts"
+/// @{
+/// @brief Provide canonical valid artifact payload used by candidate registration tests.
+/// @}
+void _valid_artifacts(void);
+
+/// @defgroup test_register_candidate_rejects_duplicate_candidate_id "test_register_candidate_rejects_duplicate_candidate_id"
+/// @{
+/// @brief Verify duplicate candidate_id registration is rejected by service invariants.
+/// @}
+void test_register_candidate_rejects_duplicate_candidate_id(void);
+
+/// @defgroup test_register_candidate_rejects_malformed_artifact_input "test_register_candidate_rejects_malformed_artifact_input"
+/// @{
+/// @brief Verify candidate registration rejects artifact payloads missing required fields.
+/// @}
+void test_register_candidate_rejects_malformed_artifact_input(void);
+
+/// @defgroup test_register_candidate_rejects_empty_artifact_set "test_register_candidate_rejects_empty_artifact_set"
+/// @{
+/// @brief Verify candidate registration rejects empty artifact collections.
+/// @}
+void test_register_candidate_rejects_empty_artifact_set(void);
+
+/// @defgroup test_manifest_service_rebuild_creates_new_version "test_manifest_service_rebuild_creates_new_version"
+/// @{
+/// @brief Verify repeated manifest build creates a new incremented immutable version.
+/// @}
+void test_manifest_service_rebuild_creates_new_version(void);
+
+/// @defgroup test_manifest_service_existing_manifest_cannot_be_mutated "test_manifest_service_existing_manifest_cannot_be_mutated"
+/// @{
+/// @brief Verify existing manifest snapshot remains immutable when rebuilding newer manifest version.
+/// @}
+void test_manifest_service_existing_manifest_cannot_be_mutated(void);
+
+/// @defgroup test_manifest_service_rejects_missing_candidate "test_manifest_service_rejects_missing_candidate"
+/// @{
+/// @brief Verify manifest build fails with missing candidate identifier.
+/// @}
+void test_manifest_service_rejects_missing_candidate(void);
+
+/// @defgroup TestComplianceExecutionService "TestComplianceExecutionService"
+/// @{
+/// @brief Validate stage pipeline and run finalization contracts for compliance execution.
+/// @invariant Missing manifest prevents run startup; failed execution cannot finalize as PASSED.
+/// @}
+void TestComplianceExecutionService(void);
+
+/// @defgroup _seed_with_candidate_policy_registry "_seed_with_candidate_policy_registry"
+/// @{
+/// @brief Build deterministic repository state for run startup tests.
+/// @post Returns repository with candidate, policy and registry; manifest is optional.
+/// @pre candidate_id and snapshot ids are non-empty.
+/// @}
+void _seed_with_candidate_policy_registry(void);
+
+/// @defgroup test_run_without_manifest_rejected "test_run_without_manifest_rejected"
+/// @{
+/// @brief Ensure compliance run cannot start when manifest is unresolved.
+/// @post start_check_run raises ValueError and no run is persisted.
+/// @pre Candidate/policy exist but manifest is missing.
+/// @}
+void test_run_without_manifest_rejected(void);
+
+/// @defgroup test_task_crash_mid_run_marks_failed "test_task_crash_mid_run_marks_failed"
+/// @{
+/// @brief Ensure execution crash conditions force FAILED run status.
+/// @post execute_stages persists run with FAILED status.
+/// @pre Run exists, then required dependency becomes unavailable before execute_stages.
+/// @}
+void test_task_crash_mid_run_marks_failed(void);
+
+/// @defgroup test_blocked_run_finalization_blocks_report_builder "test_blocked_run_finalization_blocks_report_builder"
+/// @{
+/// @brief Ensure blocked runs require blocking violations before report creation.
+/// @post finalize keeps BLOCKED and report_builder rejects zero blocking violations.
+/// @pre Manifest contains prohibited artifacts leading to BLOCKED decision.
+/// @}
+void test_blocked_run_finalization_blocks_report_builder(void);
+
+/// @defgroup TestComplianceTaskIntegration "TestComplianceTaskIntegration"
+/// @{
+/// @brief Verify clean release compliance runs execute through TaskManager lifecycle with observable success/failure outcomes.
+/// @invariant Compliance execution triggered as task produces terminal task status and persists run evidence.
+/// @}
+void TestComplianceTaskIntegration(void);
+
+/// @defgroup _seed_repository "_seed_repository"
+/// @{
+/// @brief Prepare deterministic candidate/policy/registry/manifest fixtures for task integration tests.
+/// @post Returns initialized repository and identifiers for compliance run startup.
+/// @pre with_manifest controls manifest availability.
+/// @}
+void _seed_repository(void);
+
+/// @defgroup CleanReleaseCompliancePlugin "CleanReleaseCompliancePlugin"
+/// @{
+/// @brief TaskManager plugin shim that executes clean release compliance orchestration.
+/// @}
+void CleanReleaseCompliancePlugin(void);
+
+/// @defgroup _PluginLoaderStub "_PluginLoaderStub"
+/// @{
+/// @brief Provide minimal plugin loader contract used by TaskManager in integration tests.
+/// @invariant has_plugin/get_plugin only acknowledge the seeded compliance plugin id.
+/// @}
+void _PluginLoaderStub(void);
+
+/// @defgroup _make_task_manager "_make_task_manager"
+/// @{
+/// @brief Build TaskManager with mocked persistence services for isolated integration tests.
+/// @post Returns TaskManager ready for async task execution.
+/// @}
+void _make_task_manager(void);
+
+/// @defgroup _wait_for_terminal_task "_wait_for_terminal_task"
+/// @{
+/// @brief Poll task registry until target task reaches terminal status.
+/// @post Returns task with SUCCESS or FAILED status, otherwise raises TimeoutError.
+/// @pre task_id exists in manager registry.
+/// @}
+void _wait_for_terminal_task(void);
+
+/// @defgroup test_compliance_run_executes_as_task_manager_task "test_compliance_run_executes_as_task_manager_task"
+/// @{
+/// @brief Verify successful compliance execution is observable as TaskManager SUCCESS task.
+/// @post Task ends with SUCCESS; run is persisted with SUCCEEDED status and task binding.
+/// @pre Candidate, policy and manifest are available in repository.
+/// @}
+void test_compliance_run_executes_as_task_manager_task(void);
+
+/// @defgroup test_compliance_run_missing_manifest_marks_task_failed "test_compliance_run_missing_manifest_marks_task_failed"
+/// @{
+/// @brief Verify missing manifest startup failure is surfaced as TaskManager FAILED task.
+/// @post Task ends with FAILED and run history remains empty.
+/// @pre Candidate/policy exist but manifest is absent.
+/// @}
+void test_compliance_run_missing_manifest_marks_task_failed(void);
+
+/// @defgroup TestDemoModeIsolation "TestDemoModeIsolation"
+/// @{
+/// @brief Verify demo and real mode namespace isolation contracts before TUI integration.
+/// @}
+void TestDemoModeIsolation(void);
+
+/// @defgroup test_resolve_namespace_separates_demo_and_real "test_resolve_namespace_separates_demo_and_real"
+/// @{
+/// @brief Ensure namespace resolver returns deterministic and distinct namespaces.
+/// @post Demo and real namespaces are different and stable.
+/// @pre Mode names are provided as user/runtime strings.
+/// @}
+void test_resolve_namespace_separates_demo_and_real(void);
+
+/// @defgroup test_build_namespaced_id_prevents_cross_mode_collisions "test_build_namespaced_id_prevents_cross_mode_collisions"
+/// @{
+/// @brief Ensure ID generation prevents demo/real collisions for identical logical IDs.
+/// @post Produced physical IDs differ by namespace prefix.
+/// @pre Same logical candidate id is used in two different namespaces.
+/// @}
+void test_build_namespaced_id_prevents_cross_mode_collisions(void);
+
+/// @defgroup test_create_isolated_repository_keeps_mode_data_separate "test_create_isolated_repository_keeps_mode_data_separate"
+/// @{
+/// @brief Verify demo and real repositories do not leak state across mode boundaries.
+/// @post Candidate mutations in one mode are not visible in the other mode.
+/// @pre Two repositories are created for distinct modes.
+/// @}
+void test_create_isolated_repository_keeps_mode_data_separate(void);
+
+/// @defgroup TestPolicyResolutionService "TestPolicyResolutionService"
+/// @{
+/// @brief Verify trusted policy snapshot resolution contract and error guards.
+/// @invariant Resolution uses only ConfigManager active IDs and rejects runtime override attempts.
+/// @}
+void TestPolicyResolutionService(void);
+
+/// @defgroup _config_manager "_config_manager"
+/// @{
+/// @brief Build deterministic ConfigManager-like stub for tests.
+/// @invariant Only settings.clean_release.active_policy_id and active_registry_id are populated; any other settings field access raises AttributeError.
+/// @post Returns object exposing get_config().settings.clean_release active IDs.
+/// @pre policy_id and registry_id may be None or non-empty strings.
+/// @}
+void _config_manager(void);
+
+/// @defgroup test_resolve_trusted_policy_snapshots_missing_profile "test_resolve_trusted_policy_snapshots_missing_profile"
+/// @{
+/// @brief Ensure resolution fails when trusted profile is not configured.
+/// @post Raises PolicyResolutionError with missing trusted profile reason.
+/// @pre active_policy_id is None.
+/// @}
+void test_resolve_trusted_policy_snapshots_missing_profile(void);
+
+/// @defgroup test_resolve_trusted_policy_snapshots_missing_registry "test_resolve_trusted_policy_snapshots_missing_registry"
+/// @{
+/// @brief Ensure resolution fails when trusted registry is not configured.
+/// @post Raises PolicyResolutionError with missing trusted registry reason.
+/// @pre active_registry_id is None and active_policy_id is set.
+/// @}
+void test_resolve_trusted_policy_snapshots_missing_registry(void);
+
+/// @defgroup test_resolve_trusted_policy_snapshots_rejects_override_attempt "test_resolve_trusted_policy_snapshots_rejects_override_attempt"
+/// @{
+/// @brief Ensure runtime override attempt is rejected even if snapshots exist.
+/// @post Raises PolicyResolutionError with override forbidden reason.
+/// @pre valid trusted snapshots exist in repository and override is provided.
+/// @}
+void test_resolve_trusted_policy_snapshots_rejects_override_attempt(void);
+
+/// @defgroup TestPublicationService "TestPublicationService"
+/// @{
+/// @brief Define publication gate contracts over approved candidates and immutable publication records.
+/// @invariant Publish requires approval; revoke requires existing publication; republish after revoke is allowed as a new record.
+/// @}
+void TestPublicationService(void);
+
+/// @defgroup _seed_candidate_with_passed_report "_seed_candidate_with_passed_report"
+/// @{
+/// @brief Seed candidate/report fixtures for publication gate scenarios.
+/// @post Repository contains candidate and PASSED report.
+/// @pre candidate_id and report_id are non-empty.
+/// @}
+void _seed_candidate_with_passed_report(void);
+
+/// @defgroup test_publish_without_approval_rejected "test_publish_without_approval_rejected"
+/// @{
+/// @brief Ensure publish action is blocked until candidate is approved.
+/// @post publish_candidate raises PublicationGateError.
+/// @pre Candidate has PASSED report but status is not APPROVED.
+/// @}
+void test_publish_without_approval_rejected(void);
+
+/// @defgroup test_revoke_unknown_publication_rejected "test_revoke_unknown_publication_rejected"
+/// @{
+/// @brief Ensure revocation is rejected for unknown publication id.
+/// @post revoke_publication raises PublicationGateError.
+/// @pre Repository has no matching publication record.
+/// @}
+void test_revoke_unknown_publication_rejected(void);
+
+/// @defgroup test_republish_after_revoke_creates_new_active_record "test_republish_after_revoke_creates_new_active_record"
+/// @{
+/// @brief Ensure republish after revoke is allowed and creates a new ACTIVE record.
+/// @post New publish call returns distinct publication id with ACTIVE status.
+/// @pre Candidate is APPROVED and first publication has been revoked.
+/// @}
+void test_republish_after_revoke_creates_new_active_record(void);
+
+/// @defgroup TestReportAuditImmutability "TestReportAuditImmutability"
+/// @{
+/// @brief Validate report snapshot immutability expectations and append-only audit hook behavior for US2.
+/// @invariant Built reports are immutable snapshots; audit hooks produce append-only event traces.
+/// @}
+void TestReportAuditImmutability(void);
+
+/// @defgroup _terminal_run "_terminal_run"
+/// @{
+/// @brief Build deterministic terminal run fixture for report snapshot tests.
+/// @post Returns a terminal ComplianceRun suitable for report generation.
+/// @pre final_status is a valid ComplianceDecision value.
+/// @}
+void _terminal_run(void);
+
+/// @defgroup test_report_builder_sets_immutable_snapshot_flag "test_report_builder_sets_immutable_snapshot_flag"
+/// @{
+/// @brief Ensure generated report payload is marked immutable and persisted as snapshot.
+/// @post Built report has immutable=True and repository stores same immutable object.
+/// @pre Terminal run exists.
+/// @}
+void test_report_builder_sets_immutable_snapshot_flag(void);
+
+/// @defgroup test_repository_rejects_report_overwrite_for_same_report_id "test_repository_rejects_report_overwrite_for_same_report_id"
+/// @{
+/// @brief Define immutability contract that report snapshots cannot be overwritten by same identifier.
+/// @post Second save for same report id is rejected with explicit immutability error.
+/// @pre Existing report with id is already persisted.
+/// @}
+void test_repository_rejects_report_overwrite_for_same_report_id(void);
+
+/// @defgroup test_audit_hooks_emit_append_only_event_stream "test_audit_hooks_emit_append_only_event_stream"
+/// @{
+/// @brief Verify audit hooks emit one event per action call and preserve call order.
+/// @post Three calls produce three ordered info entries with molecular prefixes.
+/// @pre Logger backend is patched.
+/// @}
+void test_audit_hooks_emit_append_only_event_stream(void);
+
+/// @defgroup SupersetCompatibilityMatrixTests "SupersetCompatibilityMatrixTests"
+/// @{
+/// @brief Verifies Superset preview and SQL Lab endpoint fallback strategy used by dataset-review orchestration.
+/// @}
+void SupersetCompatibilityMatrixTests(void);
+
+/// @defgroup make_adapter "make_adapter"
+/// @{
+/// @brief Build an adapter with a mock Superset client and deterministic environment for compatibility tests.
+/// @}
+void make_adapter(void);
+
+/// @defgroup test_preview_prefers_supported_client_method_before_network_fallback "test_preview_prefers_supported_client_method_before_network_fallback"
+/// @{
+/// @brief Confirms preview compilation uses a supported client method first when the capability exists.
+/// @}
+void test_preview_prefers_supported_client_method_before_network_fallback(void);
+
+/// @defgroup test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql "test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql"
+/// @{
+/// @brief Confirms preview fallback walks the compatibility matrix from preferred to legacy endpoints until one returns compiled SQL.
+/// @}
+void test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql(void);
+
+/// @defgroup test_sql_lab_launch_falls_back_to_legacy_execute_endpoint "test_sql_lab_launch_falls_back_to_legacy_execute_endpoint"
+/// @{
+/// @brief Confirms SQL Lab launch falls back from modern to legacy execute endpoint and preserves canonical session reference extraction.
+/// @}
+void test_sql_lab_launch_falls_back_to_legacy_execute_endpoint(void);
+
+/// @defgroup TestAPIKeyAuth "TestAPIKeyAuth"
+/// @{
+/// @brief Contract tests for API key authentication — valid key, invalid, revoked, expired, missing permission,
+/// @}
+void TestAPIKeyAuth(void);
+
+/// @defgroup test_no_header_returns_none "test_no_header_returns_none"
+/// @{
+/// @brief No X-API-Key header → returns None.
+/// @}
+void test_no_header_returns_none(void);
+
+/// @defgroup test_valid_key_returns_principal "test_valid_key_returns_principal"
+/// @{
+/// @brief Valid API key → returns APIKeyPrincipal with correct fields.
+/// @}
+void test_valid_key_returns_principal(void);
+
+/// @defgroup test_invalid_key_raises_401 "test_invalid_key_raises_401"
+/// @{
+/// @brief Invalid API key → 401.
+/// @}
+void test_invalid_key_raises_401(void);
+
+/// @defgroup test_revoked_key_raises_401 "test_revoked_key_raises_401"
+/// @{
+/// @brief Revoked (active=False) API key → 401.
+/// @}
+void test_revoked_key_raises_401(void);
+
+/// @defgroup test_expired_key_raises_401 "test_expired_key_raises_401"
+/// @{
+/// @brief Expired API key → 401.
+/// @}
+void test_expired_key_raises_401(void);
+
+/// @defgroup test_api_key_auth_valid "test_api_key_auth_valid"
+/// @{
+/// @brief Valid API key with matching permission → 202.
+/// @}
+void test_api_key_auth_valid(void);
+
+/// @defgroup test_api_key_auth_wrong_permission "test_api_key_auth_wrong_permission"
+/// @{
+/// @brief API key lacks required permission → 403.
+/// @}
+void test_api_key_auth_wrong_permission(void);
+
+/// @defgroup test_api_key_auth_revoked "test_api_key_auth_revoked"
+/// @{
+/// @brief Revoked API key → 401.
+/// @}
+void test_api_key_auth_revoked(void);
+
+/// @defgroup test_api_key_auth_expired "test_api_key_auth_expired"
+/// @{
+/// @brief Expired API key → 401.
+/// @}
+void test_api_key_auth_expired(void);
+
+/// @defgroup test_api_key_auth_invalid "test_api_key_auth_invalid"
+/// @{
+/// @brief Non-existent key → 401.
+/// @}
+void test_api_key_auth_invalid(void);
+
+/// @defgroup test_api_key_auth_environment_scope "test_api_key_auth_environment_scope"
+/// @{
+/// @brief Key scoped to ss-dev, request for ss-prod → 400.
+/// @}
+void test_api_key_auth_environment_scope(void);
+
+/// @defgroup test_api_key_auth_environment_scope_ok "test_api_key_auth_environment_scope_ok"
+/// @{
+/// @brief Key scoped to ss-dev, request for ss-dev → 202.
+/// @}
+void test_api_key_auth_environment_scope_ok(void);
+
+/// @defgroup test_jwt_precedence "test_jwt_precedence"
+/// @{
+/// @brief Both valid API key + valid JWT → JWT takes precedence.
+/// @}
+void test_jwt_precedence(void);
+
+/// @defgroup TestAPIKeyModel "TestAPIKeyModel"
+/// @{
+/// @brief Contract tests for the APIKey SQLAlchemy model — creation, hash storage, and field constraints.
+/// @}
+void TestAPIKeyModel(void);
+
+/// @defgroup clean_db "clean_db"
+/// @{
+/// @brief In-memory SQLite fixture for APIKey model tests.
+/// @}
+void clean_db(void);
+
+/// @defgroup test_create_api_key "test_create_api_key"
+/// @{
+/// @brief Create APIKey with required fields and verify defaults.
+/// @}
+void test_create_api_key(void);
+
+/// @defgroup test_key_hash_unique "test_key_hash_unique"
+/// @{
+/// @brief key_hash is unique — duplicate raises IntegrityError.
+/// @}
+void test_key_hash_unique(void);
+
+/// @defgroup test_prefix_length "test_prefix_length"
+/// @{
+/// @brief prefix is exactly 11 characters.
+/// @}
+void test_prefix_length(void);
+
+/// @defgroup test_active_default_true "test_active_default_true"
+/// @{
+/// @brief active column defaults to True.
+/// @}
+void test_active_default_true(void);
+
+/// @defgroup TestAPIKeyRoutes "TestAPIKeyRoutes"
+/// @{
+/// @brief Contract tests for admin API key CRUD endpoints — list, create (raw key present), revoke, idempotent revoke.
+/// @}
+void TestAPIKeyRoutes(void);
+
+/// @defgroup test_list_empty "test_list_empty"
+/// @{
+/// @brief No keys → returns empty list.
+/// @}
+void test_list_empty(void);
+
+/// @defgroup test_list_with_keys "test_list_with_keys"
+/// @{
+/// @brief Keys exist → returns list without raw_key or key_hash fields.
+/// @}
+void test_list_with_keys(void);
+
+/// @defgroup test_create_valid "test_create_valid"
+/// @{
+/// @brief Valid request → 201 with raw_key, prefix, id.
+/// @}
+void test_create_valid(void);
+
+/// @defgroup test_create_missing_name "test_create_missing_name"
+/// @{
+/// @brief Missing name → 400 or 422.
+/// @}
+void test_create_missing_name(void);
+
+/// @defgroup test_create_empty_permissions "test_create_empty_permissions"
+/// @{
+/// @brief Empty permissions → 400 or 422.
+/// @}
+void test_create_empty_permissions(void);
+
+/// @defgroup test_revoke_valid "test_revoke_valid"
+/// @{
+/// @brief Revoke existing active key → 200 with status=revoked.
+/// @}
+void test_revoke_valid(void);
+
+/// @defgroup test_revoke_already_revoked "test_revoke_already_revoked"
+/// @{
+/// @brief Revoke already revoked key → 404.
+/// @}
+void test_revoke_already_revoked(void);
+
+/// @defgroup test_revoke_not_found "test_revoke_not_found"
+/// @{
+/// @brief Revoke non-existent key → 404.
+/// @}
+void test_revoke_not_found(void);
+
+/// @defgroup TestAuth "TestAuth"
+/// @{
+/// @brief Covers authentication service/repository behavior and auth bootstrap helpers.
+/// @}
+void TestAuth(void);
+
+/// @defgroup test_create_admin_creates_user_with_optional_email "test_create_admin_creates_user_with_optional_email"
+/// @{
+/// @}
+void test_create_admin_creates_user_with_optional_email(void);
+
+/// @defgroup test_create_admin_is_idempotent_for_existing_user "test_create_admin_is_idempotent_for_existing_user"
+/// @{
+/// @}
+void test_create_admin_is_idempotent_for_existing_user(void);
+
+/// @defgroup test_ensure_encryption_key_generates_backend_env_file "test_ensure_encryption_key_generates_backend_env_file"
+/// @{
+/// @}
+void test_ensure_encryption_key_generates_backend_env_file(void);
+
+/// @defgroup test_ensure_encryption_key_reuses_existing_env_file_value "test_ensure_encryption_key_reuses_existing_env_file_value"
+/// @{
+/// @}
+void test_ensure_encryption_key_reuses_existing_env_file_value(void);
+
+/// @defgroup test_ensure_encryption_key_prefers_process_environment "test_ensure_encryption_key_prefers_process_environment"
+/// @{
+/// @}
+void test_ensure_encryption_key_prefers_process_environment(void);
+
+/// @defgroup TestConstantsAuditFixes "TestConstantsAuditFixes"
+/// @{
+/// @brief Verify Class 5 fix — hardcoded values extracted to named module-level constants.
+/// @}
+void TestConstantsAuditFixes(void);
+
+/// @defgroup test_page_size_constant_exists "test_page_size_constant_exists"
+/// @{
+/// @brief DEFAULT_PAGE_SIZE contract: importable, int > 0 (not yet defined in source).
+/// @}
+void test_page_size_constant_exists(void);
+
+/// @defgroup test_llm_analysis_timeout_constants "test_llm_analysis_timeout_constants"
+/// @{
+/// @brief Named timeout constants should exist per RATIONALE comment (not yet defined).
+/// @}
+void test_llm_analysis_timeout_constants(void);
+
+/// @defgroup test_base_dir_constant_replaces_parents "test_base_dir_constant_replaces_parents"
+/// @{
+/// @brief BASE_DIR resolves to backend/ root, not __file__-dependent relative path.
+/// @}
+void test_base_dir_constant_replaces_parents(void);
+
+/// @defgroup test_git_service_repositorys_typo_regression "test_git_service_repositorys_typo_regression"
+/// @{
+/// @brief services/git/_base.py still has "repositorys" (old typo) at line 148 — known bug.
+/// @}
+void test_git_service_repositorys_typo_regression(void);
+
+/// @defgroup test_git_default_repos_path_constant "test_git_default_repos_path_constant"
+/// @{
+/// @brief DEFAULT_GIT_REPOS_PATH should be defined per RATIONALE (not yet defined).
+/// @}
+void test_git_default_repos_path_constant(void);
+
+/// @defgroup test_superset_client_module_loads "test_superset_client_module_loads"
+/// @{
+/// @brief superset_client._base is importable (no dependency on crashing modules).
+/// @}
+void test_superset_client_module_loads(void);
+
+/// @defgroup test_constants_are_immutable "test_constants_are_immutable"
+/// @{
+/// @brief Module-level constants use int/str types (immutable by convention).
+/// @}
+void test_constants_are_immutable(void);
+
+/// @defgroup TestCoreScheduler "TestCoreScheduler"
+/// @{
+/// @brief Verify SchedulerService load_schedules and translation job add/remove contracts.
+/// @}
+void TestCoreScheduler(void);
+
+/// @defgroup test_load_schedules_reloads_translation_schedules "test_load_schedules_reloads_translation_schedules"
+/// @{
+/// @}
+void test_load_schedules_reloads_translation_schedules(void);
+
+/// @defgroup test_add_and_remove_translation_job "test_add_and_remove_translation_job"
+/// @{
+/// @}
+void test_add_and_remove_translation_job(void);
+
+/// @defgroup test_remove_nonexistent_translation_job_no_error "test_remove_nonexistent_translation_job_no_error"
+/// @{
+/// @}
+void test_remove_nonexistent_translation_job_no_error(void);
+
+/// @defgroup test_add_validation_job "test_add_validation_job"
+/// @{
+/// @}
+void test_add_validation_job(void);
+
+/// @defgroup test_load_schedules_loads_validation_policies "test_load_schedules_loads_validation_policies"
+/// @{
+/// @}
+void test_load_schedules_loads_validation_policies(void);
+
+/// @defgroup test_trigger_validation_creates_tasks "test_trigger_validation_creates_tasks"
+/// @{
+/// @}
+void test_trigger_validation_creates_tasks(void);
+
+/// @defgroup test_trigger_validation_skips_missing_policy "test_trigger_validation_skips_missing_policy"
+/// @{
+/// @}
+void test_trigger_validation_skips_missing_policy(void);
+
+/// @defgroup test_trigger_validation_skips_inactive_policy "test_trigger_validation_skips_inactive_policy"
+/// @{
+/// @}
+void test_trigger_validation_skips_inactive_policy(void);
+
+/// @defgroup test_trigger_validation_skips_no_dashboards "test_trigger_validation_skips_no_dashboards"
+/// @{
+/// @}
+void test_trigger_validation_skips_no_dashboards(void);
+
+/// @defgroup test_remove_validation_job "test_remove_validation_job"
+/// @{
+/// @}
+void test_remove_validation_job(void);
+
+/// @defgroup test_remove_nonexistent_validation_job "test_remove_nonexistent_validation_job"
+/// @{
+/// @}
+void test_remove_nonexistent_validation_job(void);
+
+/// @defgroup test_reload_validation_policy_adds_job "test_reload_validation_policy_adds_job"
+/// @{
+/// @}
+void test_reload_validation_policy_adds_job(void);
+
+/// @defgroup test_reload_validation_policy_removes_job_when_policy_gone "test_reload_validation_policy_removes_job_when_policy_gone"
+/// @{
+/// @}
+void test_reload_validation_policy_removes_job_when_policy_gone(void);
+
+/// @defgroup TestDashboardsApi "TestDashboardsApi"
+/// @{
+/// @brief Comprehensive contract-driven tests for Dashboard Hub API
+/// @}
+void TestDashboardsApi(void);
+
+/// @defgroup test_get_dashboard_tasks_history_success "test_get_dashboard_tasks_history_success"
+/// @{
+/// @}
+void test_get_dashboard_tasks_history_success(void);
+
+/// @defgroup test_get_dashboard_tasks_history_sorting "test_get_dashboard_tasks_history_sorting"
+/// @{
+/// @}
+void test_get_dashboard_tasks_history_sorting(void);
+
+/// @defgroup test_get_dashboard_thumbnail_env_not_found "test_get_dashboard_thumbnail_env_not_found"
+/// @{
+/// @}
+void test_get_dashboard_thumbnail_env_not_found(void);
+
+/// @defgroup test_get_dashboard_thumbnail_202 "test_get_dashboard_thumbnail_202"
+/// @{
+/// @}
+void test_get_dashboard_thumbnail_202(void);
+
+/// @defgroup test_migrate_dashboards_pre_checks "test_migrate_dashboards_pre_checks"
+/// @{
+/// @}
+void test_migrate_dashboards_pre_checks(void);
+
+/// @defgroup test_backup_dashboards_pre_checks "test_backup_dashboards_pre_checks"
+/// @{
+/// @}
+void test_backup_dashboards_pre_checks(void);
+
+/// @defgroup test_backup_dashboards_with_schedule "test_backup_dashboards_with_schedule"
+/// @{
+/// @}
+void test_backup_dashboards_with_schedule(void);
+
+/// @defgroup test_task_matches_dashboard_logic "test_task_matches_dashboard_logic"
+/// @{
+/// @}
+void test_task_matches_dashboard_logic(void);
+
+/// @defgroup TestDeprecationAuditFixes "TestDeprecationAuditFixes"
+/// @{
+/// @brief Verify Class 7 fix — is_multimodal_model should emit DeprecationWarning.
+/// @}
+void TestDeprecationAuditFixes(void);
+
+/// @defgroup test_is_multimodal_model_emits_warning "test_is_multimodal_model_emits_warning"
+/// @{
+/// @brief is_multimodal_model should emit DeprecationWarning (shim not yet implemented).
+/// @}
+void test_is_multimodal_model_emits_warning(void);
+
+/// @defgroup test_multimodal_model_returns_true "test_multimodal_model_returns_true"
+/// @{
+/// @brief Known multimodal models (gpt-4o, claude-3, gemini) return True.
+/// @}
+void test_multimodal_model_returns_true(void);
+
+/// @defgroup test_text_only_model_returns_false "test_text_only_model_returns_false"
+/// @{
+/// @brief Text-only models (embedding, whisper, rerank) return False.
+/// @}
+void test_text_only_model_returns_false(void);
+
+/// @defgroup test_empty_model_returns_false "test_empty_model_returns_false"
+/// @{
+/// @brief Empty or None model name returns False without error.
+/// @}
+void test_empty_model_returns_false(void);
+
+/// @defgroup test_case_insensitive_matching "test_case_insensitive_matching"
+/// @{
+/// @brief Model name matching is case-insensitive.
+/// @}
+void test_case_insensitive_matching(void);
+
+/// @defgroup test_deprecation_comment_exists "test_deprecation_comment_exists"
+/// @{
+/// @brief The source module documents the @DEPRECATED rationale in the region header.
+/// @}
+void test_deprecation_comment_exists(void);
+
+/// @defgroup TestLayoutUtils "TestLayoutUtils"
+/// @{
+/// @brief Contract tests for layout utility functions — _estimate_markdown_height.
+/// @}
+void TestLayoutUtils(void);
+
+/// @defgroup test_empty_content "test_empty_content"
+/// @{
+/// @brief Empty string returns minimum height 19.
+/// @}
+void test_empty_content(void);
+
+/// @defgroup test_single_line_text "test_single_line_text"
+/// @{
+/// @brief Short text without padding returns expected computed height.
+/// @}
+void test_single_line_text(void);
+
+/// @defgroup test_content_with_padding "test_content_with_padding"
+/// @{
+/// @brief Content with padding:12 — 24px added to content height.
+/// @}
+void test_content_with_padding(void);
+
+/// @defgroup test_very_long_content "test_very_long_content"
+/// @{
+/// @brief Very long content (3000 chars) capped at max height 200.
+/// @}
+void test_very_long_content(void);
+
+/// @defgroup test_html_only_content "test_html_only_content"
+/// @{
+/// @brief HTML-only content (no visible text) returns minimum height 19.
+/// @}
+void test_html_only_content(void);
+
+/// @defgroup test_log_persistence "test_log_persistence"
+/// @{
+/// @brief Unit tests for TaskLogPersistenceService.
+/// @}
+void test_log_persistence(void);
+
+/// @defgroup TestLogPersistence "TestLogPersistence"
+/// @{
+/// @brief Test suite for TaskLogPersistenceService.
+/// @}
+void TestLogPersistence(void);
+
+/// @defgroup test_add_logs_single "test_add_logs_single"
+/// @{
+/// @brief Test adding a single log entry.
+/// @post Log entry persisted to database.
+/// @pre Service and session initialized.
+/// @}
+void test_add_logs_single(void);
+
+/// @defgroup test_add_logs_batch "test_add_logs_batch"
+/// @{
+/// @brief Test adding multiple log entries in batch.
+/// @post All log entries persisted to database.
+/// @pre Service and session initialized.
+/// @}
+void test_add_logs_batch(void);
+
+/// @defgroup test_add_logs_empty "test_add_logs_empty"
+/// @{
+/// @brief Test adding empty log list (should be no-op).
+/// @post No logs added.
+/// @pre Service initialized.
+/// @}
+void test_add_logs_empty(void);
+
+/// @defgroup test_get_logs_by_task_id "test_get_logs_by_task_id"
+/// @{
+/// @brief Test retrieving logs by task ID.
+/// @post Returns logs for the specified task.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_get_logs_by_task_id(void);
+
+/// @defgroup test_get_logs_with_filters "test_get_logs_with_filters"
+/// @{
+/// @brief Test retrieving logs with level and source filters.
+/// @post Returns filtered logs.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_get_logs_with_filters(void);
+
+/// @defgroup test_get_logs_with_pagination "test_get_logs_with_pagination"
+/// @{
+/// @brief Test retrieving logs with pagination.
+/// @post Returns paginated logs.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_get_logs_with_pagination(void);
+
+/// @defgroup test_get_logs_with_search "test_get_logs_with_search"
+/// @{
+/// @brief Test retrieving logs with search query.
+/// @post Returns logs matching search query.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_get_logs_with_search(void);
+
+/// @defgroup test_get_log_stats "test_get_log_stats"
+/// @{
+/// @brief Test retrieving log statistics.
+/// @post Returns LogStats model with counts by level and source.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_get_log_stats(void);
+
+/// @defgroup test_get_sources "test_get_sources"
+/// @{
+/// @brief Test retrieving unique log sources.
+/// @post Returns list of unique sources.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_get_sources(void);
+
+/// @defgroup test_delete_logs_for_task "test_delete_logs_for_task"
+/// @{
+/// @brief Test deleting logs by task ID.
+/// @post Logs for the task are deleted.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_delete_logs_for_task(void);
+
+/// @defgroup test_delete_logs_for_tasks "test_delete_logs_for_tasks"
+/// @{
+/// @brief Test deleting logs for multiple tasks.
+/// @post Logs for all specified tasks are deleted.
+/// @pre Service and session initialized, logs exist.
+/// @}
+void test_delete_logs_for_tasks(void);
+
+/// @defgroup test_delete_logs_for_tasks_empty "test_delete_logs_for_tasks_empty"
+/// @{
+/// @brief Test deleting with empty list (no-op).
+/// @post No error, no deletion.
+/// @pre Service initialized.
+/// @}
+void test_delete_logs_for_tasks_empty(void);
+
+/// @defgroup TestLogger "TestLogger"
+/// @{
+/// @brief Unit tests for the custom logger CoT JSON formatters and configuration context manager.
+/// @invariant All required log statements must correctly check the threshold.
+/// @}
+void TestLogger(void);
+
+/// @defgroup test_belief_scope_success_coherence "test_belief_scope_success_coherence"
+/// @{
+/// @brief Test that belief_scope logs REFLECT marker on success.
+/// @post Logs are verified to contain REFLECT marker.
+/// @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+/// @}
+void test_belief_scope_success_coherence(void);
+
+/// @defgroup test_belief_scope_reason_not_visible_at_info "test_belief_scope_reason_not_visible_at_info"
+/// @{
+/// @brief Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.
+/// @post REASON/REFLECT markers are not captured at INFO level.
+/// @pre belief_scope is available. caplog fixture is used.
+/// @}
+void test_belief_scope_reason_not_visible_at_info(void);
+
+/// @defgroup test_cot_json_formatter_output "test_cot_json_formatter_output"
+/// @{
+/// @brief Test that CotJsonFormatter produces valid JSON with expected fields.
+/// @}
+void test_cot_json_formatter_output(void);
+
+/// @defgroup test_cot_json_formatter_plain_message "test_cot_json_formatter_plain_message"
+/// @{
+/// @brief Test that CotJsonFormatter wraps plain messages (no extra) with default marker.
+/// @}
+void test_cot_json_formatter_plain_message(void);
+
+/// @defgroup TestLoggingAuditFixes "TestLoggingAuditFixes"
+/// @{
+/// @brief Verify Class 2 fix — no bare `except: pass` patterns remain in src/.
+/// @}
+void TestLoggingAuditFixes(void);
+
+/// @defgroup _collect_src_files "_collect_src_files"
+/// @{
+/// @brief Collect all .py files under src/ excluding test/ and mock/ directories.
+/// @}
+void _collect_src_files(void);
+
+/// @defgroup test_except_pass_replaced_with_log "test_except_pass_replaced_with_log"
+/// @{
+/// @brief AST audit: bare `except: pass` nodes are absent from src/ source files.
+/// @}
+void test_except_pass_replaced_with_log(void);
+
+/// @defgroup test_plugin_loader_uses_logger_not_print "test_plugin_loader_uses_logger_not_print"
+/// @{
+/// @brief plugin_loader.py (src/core/) uses logger for error/warning, not print().
+/// @}
+void test_plugin_loader_uses_logger_not_print(void);
+
+/// @defgroup test_plugin_loader_imports_logger "test_plugin_loader_imports_logger"
+/// @{
+/// @brief plugin_loader.py imports a logger or _logger for structured reporting.
+/// @}
+void test_plugin_loader_imports_logger(void);
+
+/// @defgroup test_plugin_loader_logger_calls_exist "test_plugin_loader_logger_calls_exist"
+/// @{
+/// @brief plugin_loader.py references logger.error/warning/info in its code.
+/// @}
+void test_plugin_loader_logger_calls_exist(void);
+
+/// @defgroup test_maintenance_api "test_maintenance_api"
+/// @{
+/// @brief Contract tests for Maintenance Banner API endpoints — T016, T025.
+/// @}
+void test_maintenance_api(void);
+
+/// @defgroup test_start_returns_202 "test_start_returns_202"
+/// @{
+/// @brief Valid request returns 202 with task_id and maintenance_id.
+/// @}
+void test_start_returns_202(void);
+
+/// @defgroup test_start_missing_tables "test_start_missing_tables"
+/// @{
+/// @brief Missing tables field returns 422.
+/// @}
+void test_start_missing_tables(void);
+
+/// @defgroup test_start_end_time_before_start "test_start_end_time_before_start"
+/// @{
+/// @brief end_time before start_time returns 400.
+/// @}
+void test_start_end_time_before_start(void);
+
+/// @defgroup test_start_too_many_tables "test_start_too_many_tables"
+/// @{
+/// @brief More than 100 tables returns 422 (Pydantic validation).
+/// @}
+void test_start_too_many_tables(void);
+
+/// @defgroup test_start_idempotency "test_start_idempotency"
+/// @{
+/// @brief Same (tables, start, end) returns already_active.
+/// @}
+void test_start_idempotency(void);
+
+/// @defgroup test_end_returns_202 "test_end_returns_202"
+/// @{
+/// @brief Valid maintenance_id returns 202.
+/// @}
+void test_end_returns_202(void);
+
+/// @defgroup test_end_not_found "test_end_not_found"
+/// @{
+/// @brief Non-existent maintenance_id returns 404.
+/// @}
+void test_end_not_found(void);
+
+/// @defgroup test_end_all_returns_202 "test_end_all_returns_202"
+/// @{
+/// @brief end-all returns 202.
+/// @}
+void test_end_all_returns_202(void);
+
+/// @defgroup test_list_events "test_list_events"
+/// @{
+/// @brief Returns active and completed events.
+/// @}
+void test_list_events(void);
+
+/// @defgroup test_expired_event_auto_ends "test_expired_event_auto_ends"
+/// @{
+/// @brief Event past end_time with ACTIVE status → create_task called with auto-end params.
+/// @}
+void test_expired_event_auto_ends(void);
+
+/// @defgroup test_future_end_time_skipped "test_future_end_time_skipped"
+/// @{
+/// @brief Event with future end_time → no task created, skipped by < now filter.
+/// @}
+void test_future_end_time_skipped(void);
+
+/// @defgroup test_no_end_time_skipped "test_no_end_time_skipped"
+/// @{
+/// @brief Event with end_time=None → no task created, skipped by isnot(None) filter.
+/// @}
+void test_no_end_time_skipped(void);
+
+/// @defgroup test_list_banners "test_list_banners"
+/// @{
+/// @brief Returns list of active banners.
+/// @}
+void test_list_banners(void);
+
+/// @defgroup test_get_settings "test_get_settings"
+/// @{
+/// @brief GET returns settings.
+/// @}
+void test_get_settings(void);
+
+/// @defgroup test_put_settings "test_put_settings"
+/// @{
+/// @brief PUT updates settings.
+/// @}
+void test_put_settings(void);
+
+/// @defgroup test_maintenance_service "test_maintenance_service"
+/// @{
+/// @brief Integration tests for MaintenanceService — T018, T026, T026a.
+/// @}
+void test_maintenance_service(void);
+
+/// @defgroup test_basic_key "test_basic_key"
+/// @{
+/// @brief Basic idempotency key with tables and times.
+/// @}
+void test_basic_key(void);
+
+/// @defgroup test_key_without_end_time "test_key_without_end_time"
+/// @{
+/// @brief Idempotency key with None end_time.
+/// @}
+void test_key_without_end_time(void);
+
+/// @defgroup test_key_table_sorting "test_key_table_sorting"
+/// @{
+/// @brief Tables are sorted alphabetically in frozenset.
+/// @}
+void test_key_table_sorting(void);
+
+/// @defgroup test_empty_tables "test_empty_tables"
+/// @{
+/// @brief Empty tables list returns empty.
+/// @}
+void test_empty_tables(void);
+
+/// @defgroup test_table_based_match "test_table_based_match"
+/// @{
+/// @brief Table-based dataset matching.
+/// @}
+void test_table_based_match(void);
+
+/// @defgroup test_virtual_dataset_match "test_virtual_dataset_match"
+/// @{
+/// @brief Virtual SQL dataset matching via SqlTableExtractor.
+/// @}
+void test_virtual_dataset_match(void);
+
+/// @defgroup test_superset_api_failure "test_superset_api_failure"
+/// @{
+/// @brief Superset API failure propagates.
+/// @}
+void test_superset_api_failure(void);
+
+/// @defgroup test_creates_new_banner "test_creates_new_banner"
+/// @{
+/// @brief No existing banner — creates new chart and banner row.
+/// @}
+void test_creates_new_banner(void);
+
+/// @defgroup test_returns_existing_banner "test_returns_existing_banner"
+/// @{
+/// @brief Existing active banner — returns it.
+/// @}
+void test_returns_existing_banner(void);
+
+/// @defgroup test_chart_creation_failure "test_chart_creation_failure"
+/// @{
+/// @brief Chart creation failure propagates.
+/// @}
+void test_chart_creation_failure(void);
+
+/// @defgroup test_single_event "test_single_event"
+/// @{
+/// @brief Single event — direct substitution.
+/// @}
+void test_single_event(void);
+
+/// @defgroup test_multiple_events "test_multiple_events"
+/// @{
+/// @brief Multiple events — combined message.
+/// @}
+void test_multiple_events(void);
+
+/// @defgroup test_empty_events "test_empty_events"
+/// @{
+/// @brief Empty events list returns empty string.
+/// @}
+void test_empty_events(void);
+
+/// @defgroup test_missing_variables "test_missing_variables"
+/// @{
+/// @brief Missing variables replaced with empty string.
+/// @}
+void test_missing_variables(void);
+
+/// @defgroup test_html_escaping "test_html_escaping"
+/// @{
+/// @brief Message is HTML-escaped.
+/// @}
+void test_html_escaping(void);
+
+/// @defgroup test_happy_path "test_happy_path"
+/// @{
+/// @brief Happy path: event with matching dashboards.
+/// @}
+void test_happy_path(void);
+
+/// @defgroup test_no_matching_dashboards "test_no_matching_dashboards"
+/// @{
+/// @brief No dashboards match the tables.
+/// @}
+void test_no_matching_dashboards(void);
+
+/// @defgroup test_event_not_found "test_event_not_found"
+/// @{
+/// @brief Event ID not in DB.
+/// @}
+void test_event_not_found(void);
+
+/// @defgroup test_already_processed_event "test_already_processed_event"
+/// @{
+/// @brief Event already ACTIVE — idempotent.
+/// @}
+void test_already_processed_event(void);
+
+/// @defgroup test_rebuild_active_banner "test_rebuild_active_banner"
+/// @{
+/// @brief Active banner with active state — rebuilds text.
+/// @}
+void test_rebuild_active_banner(void);
+
+/// @defgroup test_banner_not_found "test_banner_not_found"
+/// @{
+/// @brief Banner ID not found.
+/// @}
+void test_banner_not_found(void);
+
+/// @defgroup test_end_active_event_single_banner "test_end_active_event_single_banner"
+/// @{
+/// @brief End event with single active dashboard — banner removed entirely.
+/// @}
+void test_end_active_event_single_banner(void);
+
+/// @defgroup test_end_event_shared_banner "test_end_event_shared_banner"
+/// @{
+/// @brief Two events, same dashboard — ending one rebuilds banner, doesn't delete.
+/// @}
+void test_end_event_shared_banner(void);
+
+/// @defgroup test_end_already_completed_event "test_end_already_completed_event"
+/// @{
+/// @brief Already completed event — idempotent.
+/// @}
+void test_end_already_completed_event(void);
+
+/// @defgroup test_end_all_active_events "test_end_all_active_events"
+/// @{
+/// @brief End all active events.
+/// @}
+void test_end_all_active_events(void);
+
+/// @defgroup test_no_active_events "test_no_active_events"
+/// @{
+/// @brief No active events.
+/// @}
+void test_no_active_events(void);
+
+/// @defgroup test_mixed_active_and_completed "test_mixed_active_and_completed"
+/// @{
+/// @brief Mix of active and completed events — only active get ended.
+/// @}
+void test_mixed_active_and_completed(void);
+
+/// @defgroup TestResourceHubs "TestResourceHubs"
+/// @{
+/// @brief Contract tests for resource hub dashboards/datasets listing and pagination boundary validation.
+/// @}
+void TestResourceHubs(void);
+
+/// @defgroup test_dashboards_api "test_dashboards_api"
+/// @{
+/// @brief Verify GET /api/dashboards contract compliance
+/// @}
+void test_dashboards_api(void);
+
+/// @defgroup mock_deps "mock_deps"
+/// @{
+/// @brief Provide dependency override fixture for resource hub route tests.
+/// @invariant unconstrained mock — no spec= enforced; attribute typos will silently pass
+/// @}
+void mock_deps(void);
+
+/// @defgroup test_get_dashboards_not_found "test_get_dashboards_not_found"
+/// @{
+/// @brief Verify dashboards endpoint returns 404 for unknown environment identifier.
+/// @}
+void test_get_dashboards_not_found(void);
+
+/// @defgroup test_get_dashboards_search "test_get_dashboards_search"
+/// @{
+/// @brief Verify dashboards endpoint search filter returns matching subset.
+/// @}
+void test_get_dashboards_search(void);
+
+/// @defgroup test_datasets_api "test_datasets_api"
+/// @{
+/// @brief Verify GET /api/datasets contract compliance
+/// @}
+void test_datasets_api(void);
+
+/// @defgroup test_get_datasets_not_found "test_get_datasets_not_found"
+/// @{
+/// @brief Verify datasets endpoint returns 404 for unknown environment identifier.
+/// @}
+void test_get_datasets_not_found(void);
+
+/// @defgroup test_get_datasets_search "test_get_datasets_search"
+/// @{
+/// @brief Verify datasets endpoint search filter returns matching dataset subset.
+/// @}
+void test_get_datasets_search(void);
+
+/// @defgroup test_get_datasets_service_failure "test_get_datasets_service_failure"
+/// @{
+/// @brief Verify datasets endpoint surfaces backend fetch failure as HTTP 503.
+/// @}
+void test_get_datasets_service_failure(void);
+
+/// @defgroup test_pagination_boundaries "test_pagination_boundaries"
+/// @{
+/// @brief Verify pagination validation for GET endpoints
+/// @}
+void test_pagination_boundaries(void);
+
+/// @defgroup test_get_dashboards_pagination_zero_page "test_get_dashboards_pagination_zero_page"
+/// @{
+/// @brief Verify dashboards endpoint rejects page=0 with HTTP 400 validation error.
+/// @}
+void test_get_dashboards_pagination_zero_page(void);
+
+/// @defgroup test_get_dashboards_pagination_oversize "test_get_dashboards_pagination_oversize"
+/// @{
+/// @brief Verify dashboards endpoint rejects oversized page_size with HTTP 400.
+/// @}
+void test_get_dashboards_pagination_oversize(void);
+
+/// @defgroup test_get_datasets_pagination_zero_page "test_get_datasets_pagination_zero_page"
+/// @{
+/// @brief Verify datasets endpoint rejects page=0 with HTTP 400.
+/// @}
+void test_get_datasets_pagination_zero_page(void);
+
+/// @defgroup test_get_datasets_pagination_oversize "test_get_datasets_pagination_oversize"
+/// @{
+/// @brief Verify datasets endpoint rejects oversized page_size with HTTP 400.
+/// @}
+void test_get_datasets_pagination_oversize(void);
+
+/// @defgroup TestSecurityAuditFixes "TestSecurityAuditFixes"
+/// @{
+/// @brief Verify Class 1 security audit fixes — env-only secrets, crash-early, CORS parsing.
+/// @}
+void TestSecurityAuditFixes(void);
+
+/// @defgroup test_missing_secret_key_crashes "test_missing_secret_key_crashes"
+/// @{
+/// @brief AuthConfig.validate_secret_key raises ValueError when value is empty (crash-early).
+/// @}
+void test_missing_secret_key_crashes(void);
+
+/// @defgroup test_missing_auth_db_url_crashes "test_missing_auth_db_url_crashes"
+/// @{
+/// @brief AuthConfig.validate_auth_db_url raises ValueError when URL is empty and DEV_MODE is off.
+/// @}
+void test_missing_auth_db_url_crashes(void);
+
+/// @defgroup test_auth_db_dev_fallback_works "test_auth_db_dev_fallback_works"
+/// @{
+/// @brief When DEV_MODE=true and AUTH_DATABASE_URL is unset, dev fallback is used without crash.
+/// @}
+void test_auth_db_dev_fallback_works(void);
+
+/// @defgroup test_allowed_origins_parsing "test_allowed_origins_parsing"
+/// @{
+/// @brief os.getenv("ALLOWED_ORIGINS").split(",") correctly parses comma-separated origins.
+/// @}
+void test_allowed_origins_parsing(void);
+
+/// @defgroup test_cors_wildcard_default "test_cors_wildcard_default"
+/// @{
+/// @brief When ALLOWED_ORIGINS is not set, default returns ["*"].
+/// @}
+void test_cors_wildcard_default(void);
+
+/// @defgroup test_cors_parsing_single_value "test_cors_parsing_single_value"
+/// @{
+/// @brief Single origin returns single-element list.
+/// @}
+void test_cors_parsing_single_value(void);
+
+/// @defgroup test_cors_parsing_with_trailing_spaces "test_cors_parsing_with_trailing_spaces"
+/// @{
+/// @brief Origins with trailing spaces are preserved (no strip).
+/// @}
+void test_cors_parsing_with_trailing_spaces(void);
+
+/// @defgroup test_database_url_env_override "test_database_url_env_override"
+/// @{
+/// @brief DATABASE_URL env var takes precedence over POSTGRES_URL.
+/// @}
+void test_database_url_env_override(void);
+
+/// @defgroup test_database_url_postgres_fallback "test_database_url_postgres_fallback"
+/// @{
+/// @brief POSTGRES_URL is used when DATABASE_URL is unset.
+/// @}
+void test_database_url_postgres_fallback(void);
+
+/// @defgroup test_database_url_raises_when_both_unset "test_database_url_raises_when_both_unset"
+/// @{
+/// @brief RuntimeError is expected when both DATABASE_URL and POSTGRES_URL are unset (non-dev).
+/// @}
+void test_database_url_raises_when_both_unset(void);
+
+/// @defgroup test_auth_config_module_contract "test_auth_config_module_contract"
+/// @{
+/// @brief AuthConfig contract: the class exists, validators are documented.
+/// @}
+void test_auth_config_module_contract(void);
+
+/// @defgroup test_sql_table_extractor "test_sql_table_extractor"
+/// @{
+/// @brief Unit tests for SqlTableExtractor — T017. Verifies three-phase extraction of schema.table references from SQL+Jinja.
+/// @}
+void test_sql_table_extractor(void);
+
+/// @defgroup test_simple_select "test_simple_select"
+/// @{
+/// @brief Happy path: simple SELECT with FROM schema.table.
+/// @}
+void test_simple_select(void);
+
+/// @defgroup test_multiple_tables "test_multiple_tables"
+/// @{
+/// @brief JOIN with multiple schema-qualified tables.
+/// @}
+void test_multiple_tables(void);
+
+/// @defgroup test_empty_input "test_empty_input"
+/// @{
+/// @brief Empty string returns empty set.
+/// @}
+void test_empty_input(void);
+
+/// @defgroup test_no_schema_qualified_tables "test_no_schema_qualified_tables"
+/// @{
+/// @brief Unqualified table names are NOT matched.
+/// @}
+void test_no_schema_qualified_tables(void);
+
+/// @defgroup test_case_insensitive "test_case_insensitive"
+/// @{
+/// @brief Matching is case-insensitive; result is lowercased.
+/// @}
+void test_case_insensitive(void);
+
+/// @defgroup test_string_literal_false_positive "test_string_literal_false_positive"
+/// @{
+/// @brief Date literal like '2026.04.30' must NOT be matched as schema.table.
+/// @}
+void test_string_literal_false_positive(void);
+
+/// @defgroup test_jinja_string_concat "test_jinja_string_concat"
+/// @{
+/// @brief Table reference inside Jinja {{ 'raw.sales' }} as a direct string.
+/// @}
+void test_jinja_string_concat(void);
+
+/// @defgroup test_jinja_set_block "test_jinja_set_block"
+/// @{
+/// @brief Table name in Jinja {% set %} block string value.
+/// @}
+void test_jinja_set_block(void);
+
+/// @defgroup test_mixed_jinja_and_sql "test_mixed_jinja_and_sql"
+/// @{
+/// @brief Mixed Jinja string and plain SQL schema.table references.
+/// @}
+void test_mixed_jinja_and_sql(void);
+
+/// @defgroup test_cte_with_schema_tables "test_cte_with_schema_tables"
+/// @{
+/// @brief CTE body with schema-qualified table references.
+/// @}
+void test_cte_with_schema_tables(void);
+
+/// @defgroup test_jinja_comment_excluded "test_jinja_comment_excluded"
+/// @{
+/// @brief Jinja comment {# ... #} content should not produce table extraction (no string patterns inside comments).
+/// @}
+void test_jinja_comment_excluded(void);
+
+/// @defgroup TestStorageAuditFixes "TestStorageAuditFixes"
+/// @{
+/// @brief Verify Class 7 typo fix — "repositorys" → "repositories" across all storage/git modules.
+/// @}
+void TestStorageAuditFixes(void);
+
+/// @defgroup test_repository_typo_fixed "test_repository_typo_fixed"
+/// @{
+/// @brief FileCategory.REPOSITORY equals "repositories", NOT "repositorys".
+/// @}
+void test_repository_typo_fixed(void);
+
+/// @defgroup test_repo_path_default_fixed "test_repo_path_default_fixed"
+/// @{
+/// @brief StorageConfig().repo_path defaults to "repositories".
+/// @}
+void test_repo_path_default_fixed(void);
+
+/// @defgroup test_storage_model_compiles "test_storage_model_compiles"
+/// @{
+/// @brief All storage model classes import without errors.
+/// @}
+void test_storage_model_compiles(void);
+
+/// @defgroup test_backup_category_unchanged "test_backup_category_unchanged"
+/// @{
+/// @brief FileCategory.BACKUP still equals "backups" (not affected by typo fix).
+/// @}
+void test_backup_category_unchanged(void);
+
+/// @defgroup test_storage_config_fields_have_correct_types "test_storage_config_fields_have_correct_types"
+/// @{
+/// @brief StorageConfig fields are all strings with correct defaults.
+/// @}
+void test_storage_config_fields_have_correct_types(void);
+
+/// @defgroup TestStorageConfigMigration "TestStorageConfigMigration"
+/// @{
+/// @brief Verify StorageConfig root_path change from "backups" to "/app/storage",
+/// @}
+void TestStorageConfigMigration(void);
+
+/// @defgroup TestStorageConfigDefaults "TestStorageConfigDefaults"
+/// @{
+/// @brief Verify StorageConfig default field values after the root_path change.
+/// @}
+void TestStorageConfigDefaults(void);
+
+/// @defgroup test_root_path_default "test_root_path_default"
+/// @{
+/// @brief StorageConfig().root_path must equal "/app/storage" (was "backups").
+/// @}
+void test_root_path_default(void);
+
+/// @defgroup test_root_path_is_string "test_root_path_is_string"
+/// @{
+/// @brief root_path is always a str (type safety).
+/// @}
+void test_root_path_is_string(void);
+
+/// @defgroup test_other_defaults_unchanged "test_other_defaults_unchanged"
+/// @{
+/// @brief Other StorageConfig fields were not affected by the root_path change.
+/// @}
+void test_other_defaults_unchanged(void);
+
+/// @defgroup test_global_settings_propagates_storage "test_global_settings_propagates_storage"
+/// @{
+/// @brief GlobalSettings().storage.root_path inherits the StorageConfig default.
+/// @}
+void test_global_settings_propagates_storage(void);
+
+/// @defgroup test_override_root_path "test_override_root_path"
+/// @{
+/// @brief Explicit root_path overrides the default.
+/// @}
+void test_override_root_path(void);
+
+/// @defgroup TestConfigManagerDefaults "TestConfigManagerDefaults"
+/// @{
+/// @brief Verify ConfigManager produces correct defaults when no config.json exists.
+/// @}
+void TestConfigManagerDefaults(void);
+
+/// @defgroup test_init_falls_to_defaults "test_init_falls_to_defaults"
+/// @{
+/// @brief ConfigManager(…nonexistent…) loads defaults when both DB and config.json are absent.
+/// @}
+void test_init_falls_to_defaults(void);
+
+/// @defgroup test_default_config_root_path "test_default_config_root_path"
+/// @{
+/// @brief _default_config() hardcodes root_path == "/app/storage" via StorageConfig default.
+/// @}
+void test_default_config_root_path(void);
+
+/// @defgroup test_features_from_env_still_applied "test_features_from_env_still_applied"
+/// @{
+/// @brief Even without config.json, _apply_features_from_env runs during default init.
+/// @}
+void test_features_from_env_still_applied(void);
+
+/// @defgroup TestValidatePath "TestValidatePath"
+/// @{
+/// @brief Verify ConfigManager.validate_path contract.
+/// @}
+void TestValidatePath(void);
+
+/// @defgroup test_validate_path_creates_directory "test_validate_path_creates_directory"
+/// @{
+/// @brief validate_path creates the target directory and returns (True, "OK").
+/// @}
+void test_validate_path_creates_directory(void);
+
+/// @defgroup test_validate_path_already_exists "test_validate_path_already_exists"
+/// @{
+/// @brief validate_path succeeds when the directory already exists.
+/// @}
+void test_validate_path_already_exists(void);
+
+/// @defgroup test_validate_path_nonexistent_root "test_validate_path_nonexistent_root"
+/// @{
+/// @brief validate_path returns False for a path under / (non-writable by non-root).
+/// @}
+void test_validate_path_nonexistent_root(void);
+
+/// @defgroup test_validate_path_read_only_parent "test_validate_path_read_only_parent"
+/// @{
+/// @brief validate_path returns False when the parent directory is not writable.
+/// @}
+void test_validate_path_read_only_parent(void);
+
+/// @defgroup TestGitPluginConfigIntegration "TestGitPluginConfigIntegration"
+/// @{
+/// @brief Verify GitPlugin uses shared config_manager from src.dependencies (no config.json fallback).
+/// @}
+void TestGitPluginConfigIntegration(void);
+
+/// @defgroup test_git_plugin_uses_shared_config_manager "test_git_plugin_uses_shared_config_manager"
+/// @{
+/// @brief GitPlugin.__init__ picks up the shared config_manager from src.dependencies.
+/// @}
+void test_git_plugin_uses_shared_config_manager(void);
+
+/// @defgroup test_git_plugin_fallback_creates_new "test_git_plugin_fallback_creates_new"
+/// @{
+/// @brief When from src.dependencies import config_manager fails,
+/// @}
+void test_git_plugin_fallback_creates_new(void);
+
+/// @defgroup TestRegressionGuard "TestRegressionGuard"
+/// @{
+/// @brief Guard against regressions in existing test contracts and stale assertions.
+/// @}
+void TestRegressionGuard(void);
+
+/// @defgroup test_existing_test_would_fail "test_existing_test_would_fail"
+/// @{
+/// @brief Existing test_storage_audit_fixes.py still asserts root_path=="backups" (WRONG).
+/// @}
+void test_existing_test_would_fail(void);
+
+/// @defgroup test_storage_settings_endpoint_shape "test_storage_settings_endpoint_shape"
+/// @{
+/// @brief The API response shape for storage settings is still StorageConfig.
+/// @}
+void test_storage_settings_endpoint_shape(void);
+
+/// @defgroup test_task_manager "test_task_manager"
+/// @{
+/// @brief Unit tests for TaskManager lifecycle, CRUD, log buffering, and filtering.
+/// @invariant TaskManager state changes are deterministic and testable with mocked dependencies.
+/// @}
+void test_task_manager(void);
+
+/// @defgroup _make_manager "_make_manager"
+/// @{
+/// @}
+void _make_manager(void);
+
+/// @defgroup _cleanup_manager "_cleanup_manager"
+/// @{
+/// @}
+void _cleanup_manager(void);
+
+/// @defgroup test_task_persistence "test_task_persistence"
+/// @{
+/// @brief Unit tests for TaskPersistenceService.
+/// @}
+void test_task_persistence(void);
+
+/// @defgroup TestTaskPersistenceHelpers "TestTaskPersistenceHelpers"
+/// @{
+/// @brief Test suite for TaskPersistenceService static helper methods.
+/// @}
+void TestTaskPersistenceHelpers(void);
+
+/// @defgroup test_json_load_if_needed_none "test_json_load_if_needed_none"
+/// @{
+/// @brief Test _json_load_if_needed with None input.
+/// @}
+void test_json_load_if_needed_none(void);
+
+/// @defgroup test_json_load_if_needed_dict "test_json_load_if_needed_dict"
+/// @{
+/// @brief Test _json_load_if_needed with dict input.
+/// @}
+void test_json_load_if_needed_dict(void);
+
+/// @defgroup test_json_load_if_needed_list "test_json_load_if_needed_list"
+/// @{
+/// @brief Test _json_load_if_needed with list input.
+/// @}
+void test_json_load_if_needed_list(void);
+
+/// @defgroup test_json_load_if_needed_json_string "test_json_load_if_needed_json_string"
+/// @{
+/// @brief Test _json_load_if_needed with JSON string.
+/// @}
+void test_json_load_if_needed_json_string(void);
+
+/// @defgroup test_json_load_if_needed_empty_string "test_json_load_if_needed_empty_string"
+/// @{
+/// @brief Test _json_load_if_needed with empty/null strings.
+/// @}
+void test_json_load_if_needed_empty_string(void);
+
+/// @defgroup test_json_load_if_needed_plain_string "test_json_load_if_needed_plain_string"
+/// @{
+/// @brief Test _json_load_if_needed with non-JSON string.
+/// @}
+void test_json_load_if_needed_plain_string(void);
+
+/// @defgroup test_json_load_if_needed_integer "test_json_load_if_needed_integer"
+/// @{
+/// @brief Test _json_load_if_needed with integer.
+/// @}
+void test_json_load_if_needed_integer(void);
+
+/// @defgroup test_parse_datetime_none "test_parse_datetime_none"
+/// @{
+/// @brief Test _parse_datetime with None.
+/// @}
+void test_parse_datetime_none(void);
+
+/// @defgroup test_parse_datetime_datetime_object "test_parse_datetime_datetime_object"
+/// @{
+/// @brief Test _parse_datetime with datetime object.
+/// @}
+void test_parse_datetime_datetime_object(void);
+
+/// @defgroup test_parse_datetime_iso_string "test_parse_datetime_iso_string"
+/// @{
+/// @brief Test _parse_datetime with ISO string.
+/// @}
+void test_parse_datetime_iso_string(void);
+
+/// @defgroup test_parse_datetime_invalid_string "test_parse_datetime_invalid_string"
+/// @{
+/// @brief Test _parse_datetime with invalid string.
+/// @}
+void test_parse_datetime_invalid_string(void);
+
+/// @defgroup test_parse_datetime_integer "test_parse_datetime_integer"
+/// @{
+/// @brief Test _parse_datetime with non-string, non-datetime.
+/// @}
+void test_parse_datetime_integer(void);
+
+/// @defgroup TestTaskPersistenceService "TestTaskPersistenceService"
+/// @{
+/// @brief Test suite for TaskPersistenceService CRUD operations.
+/// @}
+void TestTaskPersistenceService(void);
+
+/// @defgroup setup_class "setup_class"
+/// @{
+/// @brief Setup in-memory test database.
+/// @}
+void setup_class(void);
+
+/// @defgroup teardown_class "teardown_class"
+/// @{
+/// @brief Dispose of test database.
+/// @}
+void teardown_class(void);
+
+/// @defgroup setup_method "setup_method"
+/// @{
+/// @brief Clean task_records table before each test.
+/// @}
+void setup_method(void);
+
+/// @defgroup test_persist_task_new "test_persist_task_new"
+/// @{
+/// @brief Test persisting a new task creates a record.
+/// @post TaskRecord exists in database.
+/// @pre Empty database.
+/// @}
+void test_persist_task_new(void);
+
+/// @defgroup test_persist_task_update "test_persist_task_update"
+/// @{
+/// @brief Test updating an existing task.
+/// @post Task record updated with new status.
+/// @pre Task already persisted.
+/// @}
+void test_persist_task_update(void);
+
+/// @defgroup test_persist_task_with_logs "test_persist_task_with_logs"
+/// @{
+/// @brief Test persisting a task with log entries.
+/// @post Logs serialized as JSON in task record.
+/// @pre Task has logs attached.
+/// @}
+void test_persist_task_with_logs(void);
+
+/// @defgroup test_persist_task_failed_extracts_error "test_persist_task_failed_extracts_error"
+/// @{
+/// @brief Test that FAILED task extracts last error message.
+/// @post record.error contains last error message.
+/// @pre Task has FAILED status with ERROR logs.
+/// @}
+void test_persist_task_failed_extracts_error(void);
+
+/// @defgroup test_persist_tasks_batch "test_persist_tasks_batch"
+/// @{
+/// @brief Test persisting multiple tasks.
+/// @post All task records created.
+/// @pre Empty database.
+/// @}
+void test_persist_tasks_batch(void);
+
+/// @defgroup test_load_tasks "test_load_tasks"
+/// @{
+/// @brief Test loading tasks from database.
+/// @post Returns list of Task objects with correct data.
+/// @pre Tasks persisted.
+/// @}
+void test_load_tasks(void);
+
+/// @defgroup test_load_tasks_with_status_filter "test_load_tasks_with_status_filter"
+/// @{
+/// @brief Test loading tasks filtered by status.
+/// @post Returns only tasks matching status filter.
+/// @pre Tasks with different statuses persisted.
+/// @}
+void test_load_tasks_with_status_filter(void);
+
+/// @defgroup test_load_tasks_with_limit "test_load_tasks_with_limit"
+/// @{
+/// @brief Test loading tasks with limit.
+/// @post Returns at most `limit` tasks.
+/// @pre Multiple tasks persisted.
+/// @}
+void test_load_tasks_with_limit(void);
+
+/// @defgroup test_delete_tasks "test_delete_tasks"
+/// @{
+/// @brief Test deleting tasks by ID list.
+/// @post Specified tasks deleted, others remain.
+/// @pre Tasks persisted.
+/// @}
+void test_delete_tasks(void);
+
+/// @defgroup test_delete_tasks_empty_list "test_delete_tasks_empty_list"
+/// @{
+/// @brief Test deleting with empty list (no-op).
+/// @post No error, no changes.
+/// @pre None.
+/// @}
+void test_delete_tasks_empty_list(void);
+
+/// @defgroup test_persist_task_with_datetime_in_params "test_persist_task_with_datetime_in_params"
+/// @{
+/// @brief Test json_serializable handles datetime in params.
+/// @post Params serialized correctly.
+/// @pre Task params contain datetime values.
+/// @}
+void test_persist_task_with_datetime_in_params(void);
+
+/// @defgroup test_persist_task_resolves_environment_slug_to_existing_id "test_persist_task_resolves_environment_slug_to_existing_id"
+/// @{
+/// @brief Ensure slug-like environment token resolves to environments.id before persisting task.
+/// @post task_records.environment_id stores actual environments.id and does not violate FK.
+/// @pre environments table contains env with name convertible to provided slug token.
+/// @}
+void test_persist_task_resolves_environment_slug_to_existing_id(void);
+
+/// @defgroup TranslateCorrectionTests "TranslateCorrectionTests"
+/// @{
+/// @brief Tests for term correction API endpoints and DictionaryManager correction methods.
+/// @}
+void TranslateCorrectionTests(void);
+
+/// @defgroup test_submit_correction_creates_entry "test_submit_correction_creates_entry"
+/// @{
+/// @brief Verify that a correction creates a new dictionary entry.
+/// @}
+void test_submit_correction_creates_entry(void);
+
+/// @defgroup test_submit_correction_conflict_detected "test_submit_correction_conflict_detected"
+/// @{
+/// @brief Verify conflict detection when entry already exists.
+/// @}
+void test_submit_correction_conflict_detected(void);
+
+/// @defgroup test_submit_correction_overwrite "test_submit_correction_overwrite"
+/// @{
+/// @brief Verify that correction overwrites existing entry.
+/// @}
+void test_submit_correction_overwrite(void);
+
+/// @defgroup test_bulk_corrections_atomic "test_bulk_corrections_atomic"
+/// @{
+/// @brief Verify bulk corrections are applied atomically.
+/// @}
+void test_bulk_corrections_atomic(void);
+
+/// @defgroup test_api_correction_missing_dict "test_api_correction_missing_dict"
+/// @{
+/// @brief Verify POST corrections without dictionary_id returns 422.
+/// @}
+void test_api_correction_missing_dict(void);
+
+/// @defgroup test_api_bulk_corrections "test_api_bulk_corrections"
+/// @{
+/// @brief Verify POST /corrections/bulk works.
+/// @}
+void test_api_bulk_corrections(void);
+
+/// @defgroup TestTranslateExecutorFilter "TestTranslateExecutorFilter"
+/// @{
+/// @brief Verify TranslationExecutor._filter_new_keys contracts — key dedup, empty-set, guard triggers.
+/// @}
+void TestTranslateExecutorFilter(void);
+
+/// @defgroup test_no_prior_run_returns_all_rows "test_no_prior_run_returns_all_rows"
+/// @{
+/// @}
+void test_no_prior_run_returns_all_rows(void);
+
+/// @defgroup test_filters_existing_keys "test_filters_existing_keys"
+/// @{
+/// @}
+void test_filters_existing_keys(void);
+
+/// @defgroup test_composite_keys "test_composite_keys"
+/// @{
+/// @}
+void test_composite_keys(void);
+
+/// @defgroup test_all_keys_existing_returns_empty "test_all_keys_existing_returns_empty"
+/// @{
+/// @}
+void test_all_keys_existing_returns_empty(void);
+
+/// @defgroup test_empty_key_cols_returns_all_rows "test_empty_key_cols_returns_all_rows"
+/// @{
+/// @}
+void test_empty_key_cols_returns_all_rows(void);
+
+/// @defgroup test_null_source_data_handled "test_null_source_data_handled"
+/// @{
+/// @}
+void test_null_source_data_handled(void);
+
+/// @defgroup test_prior_run_no_records_returns_all "test_prior_run_no_records_returns_all"
+/// @{
+/// @}
+void test_prior_run_no_records_returns_all(void);
+
+/// @defgroup test_key_cols_none_returns_all "test_key_cols_none_returns_all"
+/// @{
+/// @}
+void test_key_cols_none_returns_all(void);
+
+/// @defgroup TranslateHistoryTests "TranslateHistoryTests"
+/// @{
+/// @brief Tests for run history list/detail endpoints and metrics aggregation.
+/// @}
+void TranslateHistoryTests(void);
+
+/// @defgroup test_list_runs_empty "test_list_runs_empty"
+/// @{
+/// @brief Verify runs list returns empty result initially.
+/// @}
+void test_list_runs_empty(void);
+
+/// @defgroup test_list_runs_with_data "test_list_runs_with_data"
+/// @{
+/// @brief Verify runs list returns data when runs exist.
+/// @}
+void test_list_runs_with_data(void);
+
+/// @defgroup test_list_runs_filter_job_id "test_list_runs_filter_job_id"
+/// @{
+/// @brief Verify filtering runs by job_id works.
+/// @}
+void test_list_runs_filter_job_id(void);
+
+/// @defgroup test_list_runs_filter_status "test_list_runs_filter_status"
+/// @{
+/// @brief Verify filtering runs by status works.
+/// @}
+void test_list_runs_filter_status(void);
+
+/// @defgroup test_get_run_detail "test_get_run_detail"
+/// @{
+/// @brief Verify run detail returns config_snapshot, records, events.
+/// @}
+void test_get_run_detail(void);
+
+/// @defgroup test_get_job_metrics "test_get_job_metrics"
+/// @{
+/// @brief Verify metrics endpoint returns aggregated data.
+/// @}
+void test_get_job_metrics(void);
+
+/// @defgroup test_get_all_metrics "test_get_all_metrics"
+/// @{
+/// @brief Verify global metrics endpoint returns data.
+/// @}
+void test_get_all_metrics(void);
+
+/// @defgroup test_metrics_empty_job "test_metrics_empty_job"
+/// @{
+/// @brief Verify metrics for job with no runs returns zeros.
+/// @}
+void test_metrics_empty_job(void);
+
+/// @defgroup test_run_detail_not_found "test_run_detail_not_found"
+/// @{
+/// @brief Verify 404 on non-existent run detail.
+/// @}
+void test_run_detail_not_found(void);
+
+/// @defgroup test_list_runs_includes_language_info "test_list_runs_includes_language_info"
+/// @{
+/// @brief Verify run list includes target_languages, total_translated, and language_stats.
+/// @}
+void test_list_runs_includes_language_info(void);
+
+/// @defgroup test_metrics_per_language_breakdown "test_metrics_per_language_breakdown"
+/// @{
+/// @brief Verify metrics endpoint returns per_language_metrics.
+/// @}
+void test_metrics_per_language_breakdown(void);
+
+/// @defgroup test_metric_snapshot_stores_per_language "test_metric_snapshot_stores_per_language"
+/// @{
+/// @brief Verify MetricSnapshot stores per_language_metrics via prune_expired.
+/// @}
+void test_metric_snapshot_stores_per_language(void);
+
+/// @defgroup test_combined_metrics_live_and_snapshot "test_combined_metrics_live_and_snapshot"
+/// @{
+/// @brief Verify combined metrics merge live + snapshot per-language data.
+/// @}
+void test_combined_metrics_live_and_snapshot(void);
+
+/// @defgroup TranslateJobTests "TranslateJobTests"
+/// @{
+/// @brief Tests for translation job CRUD endpoints and service layer with column validation.
+/// @}
+void TranslateJobTests(void);
+
+/// @defgroup valid_job_payload "valid_job_payload"
+/// @{
+/// @brief Standard valid payload for creating a translation job.
+/// @}
+void valid_job_payload(void);
+
+/// @defgroup MockConfigManager "MockConfigManager"
+/// @{
+/// @brief Mock ConfigManager for service tests that returns a test environment.
+/// @}
+void MockConfigManager(void);
+
+/// @defgroup db_session "db_session"
+/// @{
+/// @brief Create a fresh DB session with transaction rollback for each test.
+/// @}
+void db_session(void);
+
+/// @defgroup mock_api_deps "mock_api_deps"
+/// @{
+/// @brief Override FastAPI dependencies (including get_db with in-memory SQLite) for API route tests.
+/// @}
+void mock_api_deps(void);
+
+/// @defgroup client "client"
+/// @{
+/// @brief FastAPI TestClient for API route tests.
+/// @}
+void client(void);
+
+/// @defgroup test_create_job_valid "test_create_job_valid"
+/// @{
+/// @brief Verify that a valid job payload creates a job successfully.
+/// @}
+void test_create_job_valid(void);
+
+/// @defgroup test_create_job_missing_translation_column "test_create_job_missing_translation_column"
+/// @{
+/// @brief Verify that creating a job with datasource but no translation column raises ValueError.
+/// @}
+void test_create_job_missing_translation_column(void);
+
+/// @defgroup test_create_job_invalid_upsert_strategy "test_create_job_invalid_upsert_strategy"
+/// @{
+/// @brief Verify that an invalid upsert strategy is rejected.
+/// @}
+void test_create_job_invalid_upsert_strategy(void);
+
+/// @defgroup test_get_job "test_get_job"
+/// @{
+/// @brief Verify that a job can be retrieved by ID.
+/// @}
+void test_get_job(void);
+
+/// @defgroup test_get_job_not_found "test_get_job_not_found"
+/// @{
+/// @brief Verify that getting a non-existent job raises ValueError.
+/// @}
+void test_get_job_not_found(void);
+
+/// @defgroup test_list_jobs "test_list_jobs"
+/// @{
+/// @brief Verify that listing jobs returns all created jobs.
+/// @}
+void test_list_jobs(void);
+
+/// @defgroup test_list_jobs_with_status_filter "test_list_jobs_with_status_filter"
+/// @{
+/// @brief Verify that listing jobs with a status filter works.
+/// @}
+void test_list_jobs_with_status_filter(void);
+
+/// @defgroup test_update_job "test_update_job"
+/// @{
+/// @brief Verify that a job can be updated.
+/// @}
+void test_update_job(void);
+
+/// @defgroup test_delete_job "test_delete_job"
+/// @{
+/// @brief Verify that a job can be deleted.
+/// @}
+void test_delete_job(void);
+
+/// @defgroup test_duplicate_job "test_duplicate_job"
+/// @{
+/// @brief Verify that a job can be duplicated.
+/// @}
+void test_duplicate_job(void);
+
+/// @defgroup test_duplicate_job_custom_name "test_duplicate_job_custom_name"
+/// @{
+/// @brief Verify that a job can be duplicated with a custom name.
+/// @}
+void test_duplicate_job_custom_name(void);
+
+/// @defgroup test_detect_virtual_columns "test_detect_virtual_columns"
+/// @{
+/// @brief Verify virtual column detection from column metadata.
+/// @}
+void test_detect_virtual_columns(void);
+
+/// @defgroup test_get_dialect_from_database "test_get_dialect_from_database"
+/// @{
+/// @brief Verify dialect extraction from Superset database records.
+/// @}
+void test_get_dialect_from_database(void);
+
+/// @defgroup test_get_dialect_from_database_unsupported "test_get_dialect_from_database_unsupported"
+/// @{
+/// @brief Verify that unsupported dialects raise ValueError.
+/// @}
+void test_get_dialect_from_database_unsupported(void);
+
+/// @defgroup test_api_create_job "test_api_create_job"
+/// @{
+/// @brief Verify POST /api/translate/jobs returns 201 with valid payload.
+/// @}
+void test_api_create_job(void);
+
+/// @defgroup test_api_list_jobs "test_api_list_jobs"
+/// @{
+/// @brief Verify GET /api/translate/jobs returns 200.
+/// @}
+void test_api_list_jobs(void);
+
+/// @defgroup test_api_get_job_not_found "test_api_get_job_not_found"
+/// @{
+/// @brief Verify GET non-existent job returns 404.
+/// @}
+void test_api_get_job_not_found(void);
+
+/// @defgroup test_api_delete_job_not_found "test_api_delete_job_not_found"
+/// @{
+/// @brief Verify DELETE non-existent job returns 404.
+/// @}
+void test_api_delete_job_not_found(void);
+
+/// @defgroup test_api_duplicate_job_not_found "test_api_duplicate_job_not_found"
+/// @{
+/// @brief Verify duplicating a non-existent job returns 404.
+/// @}
+void test_api_duplicate_job_not_found(void);
+
+/// @defgroup test_api_create_job_422_missing_name "test_api_create_job_422_missing_name"
+/// @{
+/// @brief Verify POST with missing required fields returns 422.
+/// @}
+void test_api_create_job_422_missing_name(void);
+
+/// @defgroup test_api_datasource_columns_missing_env "test_api_datasource_columns_missing_env"
+/// @{
+/// @brief Verify datasource columns endpoint without env_id returns 422.
+/// @}
+void test_api_datasource_columns_missing_env(void);
+
+/// @defgroup test_api_datasource_columns_bad_env "test_api_datasource_columns_bad_env"
+/// @{
+/// @brief Verify datasource columns with unknown env returns 400.
+/// @}
+void test_api_datasource_columns_bad_env(void);
+
+/// @defgroup test_api_update_job_not_found "test_api_update_job_not_found"
+/// @{
+/// @brief Verify PUT non-existent job returns 404.
+/// @}
+void test_api_update_job_not_found(void);
+
+/// @defgroup TranslateSchedulerTests "TranslateSchedulerTests"
+/// @{
+/// @brief Tests for TranslationScheduler CRUD and APScheduler integration.
+/// @}
+void TranslateSchedulerTests(void);
+
+/// @defgroup test_create_schedule "test_create_schedule"
+/// @{
+/// @brief Verify schedule creation with valid params.
+/// @}
+void test_create_schedule(void);
+
+/// @defgroup test_update_schedule "test_update_schedule"
+/// @{
+/// @brief Verify schedule update.
+/// @}
+void test_update_schedule(void);
+
+/// @defgroup test_delete_schedule "test_delete_schedule"
+/// @{
+/// @brief Verify schedule deletion.
+/// @}
+void test_delete_schedule(void);
+
+/// @defgroup test_enable_disable_schedule "test_enable_disable_schedule"
+/// @{
+/// @brief Verify enable/disable toggle.
+/// @}
+void test_enable_disable_schedule(void);
+
+/// @defgroup test_get_schedule_not_found "test_get_schedule_not_found"
+/// @{
+/// @brief Verify ValueError on getting non-existent schedule.
+/// @}
+void test_get_schedule_not_found(void);
+
+/// @defgroup test_list_active_schedules "test_list_active_schedules"
+/// @{
+/// @brief Verify listing only active schedules.
+/// @}
+void test_list_active_schedules(void);
+
+/// @defgroup test_get_next_executions "test_get_next_executions"
+/// @{
+/// @brief Verify next execution time computation.
+/// @}
+void test_get_next_executions(void);
+
+/// @defgroup test_get_next_executions_invalid "test_get_next_executions_invalid"
+/// @{
+/// @brief Verify invalid cron returns empty list.
+/// @}
+void test_get_next_executions_invalid(void);
+
+/// @defgroup TestTranslateSchedulerExecution "TestTranslateSchedulerExecution"
+/// @{
+/// @brief Verify execute_scheduled_translation contracts — trigger_type dispatch, baseline expiry fallback.
+/// @}
+void TestTranslateSchedulerExecution(void);
+
+/// @defgroup test_new_key_only_mode "test_new_key_only_mode"
+/// @{
+/// @}
+void test_new_key_only_mode(void);
+
+/// @defgroup test_baseline_expired_fallback "test_baseline_expired_fallback"
+/// @{
+/// @}
+void test_baseline_expired_fallback(void);
+
+/// @defgroup test_full_mode_default "test_full_mode_default"
+/// @{
+/// @}
+void test_full_mode_default(void);
+
+/// @defgroup test_inactive_schedule_skips "test_inactive_schedule_skips"
+/// @{
+/// @}
+void test_inactive_schedule_skips(void);
+
+/// @defgroup test_schedule_not_found_skips "test_schedule_not_found_skips"
+/// @{
+/// @}
+void test_schedule_not_found_skips(void);
+
+/// @defgroup test_baseline_expired_full_mode "test_baseline_expired_full_mode"
+/// @{
+/// @}
+void test_baseline_expired_full_mode(void);
+
+/// @defgroup test_execution_error_handled "test_execution_error_handled"
+/// @{
+/// @}
+void test_execution_error_handled(void);
+
+/// @defgroup TestTranslateSchedulerGuard "TestTranslateSchedulerGuard"
+/// @{
+/// @brief Verify execute_scheduled_translation concurrency guard and stale-PENDING clearance contracts.
+/// @}
+void TestTranslateSchedulerGuard(void);
+
+/// @defgroup test_concurrent_run_skips "test_concurrent_run_skips"
+/// @{
+/// @}
+void test_concurrent_run_skips(void);
+
+/// @defgroup test_recent_pending_run_not_stale "test_recent_pending_run_not_stale"
+/// @{
+/// @}
+void test_recent_pending_run_not_stale(void);
+
+/// @defgroup test_stale_pending_cleared_and_proceeds "test_stale_pending_cleared_and_proceeds"
+/// @{
+/// @}
+void test_stale_pending_cleared_and_proceeds(void);
+
+/// @defgroup test_multiple_stale_pending_all_cleared "test_multiple_stale_pending_all_cleared"
+/// @{
+/// @}
+void test_multiple_stale_pending_all_cleared(void);
+
+/// @defgroup docker_backend_Dockerfile "docker.backend.Dockerfile"
+/// @{
+/// @brief Backend Dockerfile — Python 3.11 slim + Playwright + entrypoint с установкой сертификатов.
+/// @post Образ с backend API, Playwright, entrypoint для bootstrap admin и установки сертификатов.
+/// @pre Docker builder context — корень проекта. backend/ и docker/ доступны.
+/// @}
+void docker_backend_Dockerfile(void);
+
+/// @defgroup docker_backend_entrypoint "docker.backend.entrypoint"
+/// @{
+/// @brief Container entrypoint — установка корп. сертификатов, Playwright (lazy), bootstrap admin,
+/// @}
+void docker_backend_entrypoint(void);
+
+/// @defgroup docker_backend_entrypoint_install_certificates "docker.backend.entrypoint.install_certificates"
+/// @{
+/// @brief Устанавливает корпоративные .crt сертификаты из CERTS_PATH в системное хранилище Debian.
+/// @pre CERTS_PATH указывает на директорию (может быть пуста или не существовать).
+/// @}
+void docker_backend_entrypoint_install_certificates(void);
+
+/// @defgroup docker_backend_entrypoint_bootstrap_admin "docker.backend.entrypoint.bootstrap_admin"
+/// @{
+/// @brief Создание admin пользователя из переменных окружения (идемпотентно).
+/// @post Admin пользователь создан в БД (если ещё не существовал).
+/// @pre INITIAL_ADMIN_CREATE=true, INITIAL_ADMIN_USERNAME и INITIAL_ADMIN_PASSWORD заданы.
+/// @}
+void docker_backend_entrypoint_bootstrap_admin(void);
+
+/// @defgroup docker_backend_entrypoint_install_playwright "docker.backend.entrypoint.install_playwright"
+/// @{
+/// @brief Lazy установка Playwright Chromium (~377 MB) при первом запуске.
+/// @post Chromium установлен в PLAYWRIGHT_BROWSERS_PATH.
+/// @pre ~/.cache/ms-playwright доступен (можно закешировать volume).
+/// @}
+void docker_backend_entrypoint_install_playwright(void);
+
+/// @defgroup docker_frontend_Dockerfile "docker.frontend.Dockerfile"
+/// @{
+/// @brief Frontend Dockerfile — сборка SvelteKit (node:20) + nginx runtime с опциональным SSL.
+/// @post nginx:alpine образ со статикой SvelteKit, entrypoint для выбора HTTP/SSL конфига.
+/// @pre Docker builder context — корень проекта. frontend/ и docker/ доступны.
+/// @}
+void docker_frontend_Dockerfile(void);
+
+/// @defgroup docker_frontend_entrypoint "docker.frontend.entrypoint"
+/// @{
+/// @brief Entrypoint для nginx-контейнера — установка корп. CA-сертификатов в Alpine,
+/// @}
+void docker_frontend_entrypoint(void);
+
+/// @defgroup docker_frontend_entrypoint_install_ca_certificates "docker.frontend.entrypoint.install_ca_certificates"
+/// @{
+/// @brief Устанавливает .crt файлы из /opt/certs в системное хранилище Alpine.
+/// @post Сертификаты скопированы в /usr/local/share/ca-certificates/ и добавлены в trust.
+/// @pre /opt/certs может быть пуст или не существовать.
+/// @}
+void docker_frontend_entrypoint_install_ca_certificates(void);
+
+/// @defgroup docker_frontend_entrypoint_select_nginx_config "docker.frontend.entrypoint.select_nginx_config"
+/// @{
+/// @brief Определяет, есть ли сертификаты для SSL, и копирует нужный nginx конфиг.
+/// @post Если есть оба файла — /etc/nginx/ssl/ создан, server.crt/key скопированы,
+/// @pre /opt/certs/server.crt и /opt/certs/server.key — опциональные SSL-сертификаты.
+/// @}
+void docker_frontend_entrypoint_select_nginx_config(void);
+
+/// @defgroup docker_nginx_ssl_conf "docker.nginx.ssl.conf"
+/// @{
+/// @brief Nginx config с опциональным SSL — HTTP (порт 80) + HTTPS (порт 443).
+/// @}
+void docker_nginx_ssl_conf(void);
+
+/// @defgroup AuthFixture "AuthFixture"
+/// @{
+/// @brief Playwright fixture for authenticated browser contexts.
+/// @}
+void AuthFixture(void);
+
+/// @defgroup GlobalSetup "GlobalSetup"
+/// @{
+/// @brief Pre-flight check before any E2E tests run.
+/// @post Exits with 1 if either service is down, else sets ENV vars.
+/// @pre Backend and frontend must be reachable.
+/// @}
+void GlobalSetup(void);
+
+/// @defgroup ApiHelper "ApiHelper"
+/// @{
+/// @brief Helper for backend API calls in E2E tests (settings CRUD, etc.)
+/// @}
+void ApiHelper(void);
+
+/// @defgroup frontend_e2e_helpers_api_helper_js__getToken "frontend/e2e/helpers/api.helper.js::getToken"
+/// @{
+/// @}
+void frontend_e2e_helpers_api_helper_js__getToken(void);
+
+/// @defgroup frontend_e2e_helpers_api_helper_js__apiGet "frontend/e2e/helpers/api.helper.js::apiGet"
+/// @{
+/// @}
+void frontend_e2e_helpers_api_helper_js__apiGet(void);
+
+/// @defgroup frontend_e2e_helpers_api_helper_js__apiPost "frontend/e2e/helpers/api.helper.js::apiPost"
+/// @{
+/// @}
+void frontend_e2e_helpers_api_helper_js__apiPost(void);
+
+/// @defgroup frontend_e2e_helpers_api_helper_js__apiPut "frontend/e2e/helpers/api.helper.js::apiPut"
+/// @{
+/// @}
+void frontend_e2e_helpers_api_helper_js__apiPut(void);
+
+/// @defgroup frontend_e2e_helpers_api_helper_js__apiDelete "frontend/e2e/helpers/api.helper.js::apiDelete"
+/// @{
+/// @}
+void frontend_e2e_helpers_api_helper_js__apiDelete(void);
+
+/// @defgroup run_enterprise_clean_e2e "run-enterprise-clean-e2e"
+/// @{
+/// @brief Enterprise Clean E2E Orchestrator — полный протокол тестирования пустого образа перед передачей.
+/// @}
+void run_enterprise_clean_e2e(void);
+
+/// @defgroup EnterpriseCleanSetupE2E "EnterpriseCleanSetupE2E"
+/// @{
+/// @brief Stage 1: E2E test for enterprise-clean empty image — first-run setup via StartupEnvironmentWizard.
+/// @@RATIONALE All 4 tests pass after fixing: (1) button ambiguity — zero-state page and wizard modal both have 'Начать настройку' button, resolved by scoping to wizard modal via .fixed.inset-0.z-50; (2) wizard detection — changed from waitForSelector('text=...') to getByText() with regex for locale-robust matching; (3) form fill — connections.* i18n keys missing in Docker build, switched to placeholder-based locators scoped within wizard; (4) settings navigation — use authPage fixture for consistent login
+/// @@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues
+/// @}
+void EnterpriseCleanSetupE2E(void);
+
+/// @defgroup GitE2E "GitE2E"
+/// @{
+/// @brief E2E tests for Git integration — config CRUD, connection test.
+/// @}
+void GitE2E(void);
+
+/// @defgroup LiveProjectCheckE2E "LiveProjectCheckE2E"
+/// @{
+/// @brief Stage 2: E2E test for live project verification — validates dashboard LLM analysis,
+/// @}
+void LiveProjectCheckE2E(void);
+
+/// @defgroup LoginE2E "LoginE2E"
+/// @{
+/// @brief E2E tests for login/logout flow.
+/// @}
+void LoginE2E(void);
+
+/// @defgroup MigrationE2E "MigrationE2E"
+/// @{
+/// @brief E2E tests for dataset/environment migration and sync.
+/// @}
+void MigrationE2E(void);
+
+/// @defgroup SettingsE2E "SettingsE2E"
+/// @{
+/// @brief E2E tests for Settings page — environments, LLM providers, Git config.
+/// @}
+void SettingsE2E(void);
+
+/// @defgroup SmokeE2E "SmokeE2E"
+/// @{
+/// @brief Golden-path smoke test: login → settings → translate → git → verify.
+/// @}
+void SmokeE2E(void);
+
+/// @defgroup TranslationE2E "TranslationE2E"
+/// @{
+/// @brief E2E tests for the translation job lifecycle: create → preview → accept → run.
+/// @}
+void TranslationE2E(void);
+
+/// @defgroup PlaywrightConfig "PlaywrightConfig"
+/// @{
+/// @brief Playwright E2E test configuration for ss-tools frontend.
+/// @invariant All E2E tests run against a fully deployed stack (DB + backend + frontend).
+/// @}
+void PlaywrightConfig(void);
+
+/// @defgroup handleValidate_Function "handleValidate:Function"
+/// @{
+/// @brief Triggers dashboard validation task.
+/// @}
+void handleValidate_Function(void);
+
+/// @defgroup openGit_Function "openGit:Function"
+/// @{
+/// @brief Opens the Git management modal for a dashboard.
+/// @}
+void openGit_Function(void);
+
+/// @defgroup initializeForm_Function "initializeForm:Function"
+/// @{
+/// @brief Initialize form data with default values from the schema.
+/// @post formData is initialized with default values or empty strings.
+/// @pre schema is provided and contains properties.
+/// @}
+void initializeForm_Function(void);
+
+/// @defgroup Footer "Footer"
+/// @{
+/// @brief Displays the application footer with copyright information.
+/// @}
+void Footer(void);
+
+/// @defgroup updateMapping_Function "updateMapping:Function"
+/// @{
+/// @brief Updates a mapping for a specific source database.
+/// @post Parent callback receives normalized mapping payload.
+/// @pre sourceUuid and targetUuid are provided.
+/// @}
+void updateMapping_Function(void);
+
+/// @defgroup getSuggestion_Function "getSuggestion:Function"
+/// @{
+/// @brief Finds a suggestion for a source database.
+/// @post Returns matching suggestion object or undefined.
+/// @pre sourceUuid is provided.
+/// @}
+void getSuggestion_Function(void);
+
+/// @defgroup MissingMappingModal "MissingMappingModal"
+/// @{
+/// @brief Prompts the user to provide a database mapping when one is missing during migration.
+/// @invariant Modal blocks migration progress until resolved or cancelled.
+/// @}
+void MissingMappingModal(void);
+
+/// @defgroup resolve_Function "resolve:Function"
+/// @{
+/// @brief Resolves the missing mapping via callback prop.
+/// @post Parent callback receives mapping payload and modal closes.
+/// @pre selectedTargetUuid must be set.
+/// @}
+void resolve_Function(void);
+
+/// @defgroup cancel_Function "cancel:Function"
+/// @{
+/// @brief Cancels the mapping resolution modal.
+/// @post Parent cancel callback is invoked and modal is hidden.
+/// @pre Modal is open.
+/// @}
+void cancel_Function(void);
+
+/// @defgroup Navbar "Navbar"
+/// @{
+/// @brief Main navigation bar for the application.
+/// @}
+void Navbar(void);
+
+/// @defgroup PasswordPrompt "PasswordPrompt"
+/// @{
+/// @brief A modal component to prompt the user for database passwords when a migration task is paused.
+/// @}
+void PasswordPrompt(void);
+
+/// @defgroup handleSubmit_Function "handleSubmit:Function"
+/// @{
+/// @brief Validates and forwards passwords to resume the task.
+/// @post Parent resume callback receives passwords payload.
+/// @pre All database passwords must be entered.
+/// @}
+void handleSubmit_Function(void);
+
+/// @defgroup handleCancel_Function "handleCancel:Function"
+/// @{
+/// @brief Cancels the password prompt.
+/// @post Parent cancel callback is invoked and show is set to false.
+/// @pre Modal is open.
+/// @}
+void handleCancel_Function(void);
+
+/// @defgroup handleSort_Function "handleSort:Function"
+/// @{
+/// @brief Toggles sort direction or changes sort column.
+/// @post sortColumn and sortDirection state updated.
+/// @pre column name is provided.
+/// @}
+void handleSort_Function(void);
+
+/// @defgroup handleSelectionChange_Function "handleSelectionChange:Function"
+/// @{
+/// @brief Handles individual checkbox changes.
+/// @post selectedIds array updated.
+/// @pre dashboard ID and checked status provided.
+/// @}
+void handleSelectionChange_Function(void);
+
+/// @defgroup handleSelectAll_Function "handleSelectAll:Function"
+/// @{
+/// @brief Handles select all checkbox.
+/// @post selectedIds array updated for all paginated items.
+/// @pre checked status provided.
+/// @}
+void handleSelectAll_Function(void);
+
+/// @defgroup goToPage_Function "goToPage:Function"
+/// @{
+/// @brief Changes current page.
+/// @post currentPage state updated if within valid range.
+/// @pre page index is provided.
+/// @}
+void goToPage_Function(void);
+
+/// @defgroup getRepositoryStatusToken_Function "getRepositoryStatusToken:Function"
+/// @{
+/// @brief Returns normalized repository status token for a dashboard.
+/// @post Returns one of loading|no_repo|synced|changes|behind_remote|ahead_remote|diverged|error.
+/// @pre Dashboard exists.
+/// @}
+void getRepositoryStatusToken_Function(void);
+
+/// @defgroup isRepositoryReady_Function "isRepositoryReady:Function"
+/// @{
+/// @brief Determines whether git actions can run for a dashboard.
+/// @}
+void isRepositoryReady_Function(void);
+
+/// @defgroup invalidateRepositoryStatuses_Function "invalidateRepositoryStatuses:Function"
+/// @{
+/// @brief Marks dashboard statuses as loading so they are refetched.
+/// @}
+void invalidateRepositoryStatuses_Function(void);
+
+/// @defgroup resolveRepositoryStatusToken_Function "resolveRepositoryStatusToken:Function"
+/// @{
+/// @brief Converts git status payload into a stable UI status token.
+/// @}
+void resolveRepositoryStatusToken_Function(void);
+
+/// @defgroup loadRepositoryStatuses_Function "loadRepositoryStatuses:Function"
+/// @{
+/// @brief Hydrates repository status map for dashboards in repository mode.
+/// @}
+void loadRepositoryStatuses_Function(void);
+
+/// @defgroup runBulkGitAction_Function "runBulkGitAction:Function"
+/// @{
+/// @brief Executes git action for selected dashboards with limited parallelism.
+/// @}
+void runBulkGitAction_Function(void);
+
+/// @defgroup handleBulkSync_Function "handleBulkSync:Function"
+/// @{
+/// @}
+void handleBulkSync_Function(void);
+
+/// @defgroup handleBulkCommit_Function "handleBulkCommit:Function"
+/// @{
+/// @}
+void handleBulkCommit_Function(void);
+
+/// @defgroup handleBulkPull_Function "handleBulkPull:Function"
+/// @{
+/// @}
+void handleBulkPull_Function(void);
+
+/// @defgroup handleBulkPush_Function "handleBulkPush:Function"
+/// @{
+/// @}
+void handleBulkPush_Function(void);
+
+/// @defgroup handleBulkDelete_Function "handleBulkDelete:Function"
+/// @{
+/// @brief Removes selected repositories from storage and binding table.
+/// @}
+void handleBulkDelete_Function(void);
+
+/// @defgroup handleManageSelected_Function "handleManageSelected:Function"
+/// @{
+/// @brief Opens Git manager for exactly one selected dashboard.
+/// @}
+void handleManageSelected_Function(void);
+
+/// @defgroup resolveDashboardRef_Function "resolveDashboardRef:Function"
+/// @{
+/// @brief Resolves dashboard slug from payload fields.
+/// @post Returns slug string or null if unavailable.
+/// @pre Dashboard metadata is provided.
+/// @}
+void resolveDashboardRef_Function(void);
+
+/// @defgroup openGitManagerForDashboard_Function "openGitManagerForDashboard:Function"
+/// @{
+/// @brief Opens Git manager for provided dashboard metadata.
+/// @}
+void openGitManagerForDashboard_Function(void);
+
+/// @defgroup handleInitializeRepositories_Function "handleInitializeRepositories:Function"
+/// @{
+/// @brief Opens Git manager from bulk actions to initialize selected repository.
+/// @}
+void handleInitializeRepositories_Function(void);
+
+/// @defgroup getSortStatusValue_Function "getSortStatusValue:Function"
+/// @{
+/// @brief Returns sort value for status column based on mode.
+/// @}
+void getSortStatusValue_Function(void);
+
+/// @defgroup getStatusLabel_Function "getStatusLabel:Function"
+/// @{
+/// @brief Returns localized label for status column.
+/// @}
+void getStatusLabel_Function(void);
+
+/// @defgroup getStatusBadgeClass_Function "getStatusBadgeClass:Function"
+/// @{
+/// @brief Returns badge style for status column.
+/// @}
+void getStatusBadgeClass_Function(void);
+
+/// @defgroup TaskHistory "TaskHistory"
+/// @{
+/// @brief Displays a list of recent tasks with their status and allows selecting them for viewing logs.
+/// @}
+void TaskHistory(void);
+
+/// @defgroup getStatusColor_Function "getStatusColor:Function"
+/// @{
+/// @brief Returns the CSS color class for a given task status.
+/// @post Returns tailwind color class string.
+/// @pre status string is provided.
+/// @}
+void getStatusColor_Function(void);
+
+/// @defgroup onDestroy_Function "onDestroy:Function"
+/// @{
+/// @brief Cleans up the polling interval when the component is destroyed.
+/// @post Polling interval is cleared.
+/// @pre Component is being destroyed.
+/// @}
+void onDestroy_Function(void);
+
+/// @defgroup TaskList "TaskList"
+/// @{
+/// @brief Displays a list of tasks with their status and execution details.
+/// @}
+void TaskList(void);
+
+/// @defgroup handleTaskClick_Function "handleTaskClick:Function"
+/// @{
+/// @brief Forwards the selected task through a callback prop.
+/// @post Parent callback receives task id and task payload.
+/// @pre taskId is provided.
+/// @}
+void handleTaskClick_Function(void);
+
+/// @defgroup TaskLogViewer "TaskLogViewer"
+/// @{
+/// @brief Displays task logs inline (in drawer) or as modal. Merges real-time WebSocket logs with polled historical logs.
+/// @invariant Real-time logs are always appended without duplicates.
+/// @}
+void TaskLogViewer(void);
+
+/// @defgroup connect_Function "connect:Function"
+/// @{
+/// @brief Establishes WebSocket connection with exponential backoff and filter parameters.
+/// @post WebSocket instance created and listeners attached.
+/// @pre selectedTask must be set in the store.
+/// @}
+void connect_Function(void);
+
+/// @defgroup handleFilterChange_Function "handleFilterChange:Function"
+/// @{
+/// @brief Handles filter changes and reconnects WebSocket with new parameters.
+/// @post WebSocket reconnected with new filter parameters, logs cleared.
+/// @pre event.detail contains source and level filter values.
+/// @}
+void handleFilterChange_Function(void);
+
+/// @defgroup fetchTargetDatabases_Function "fetchTargetDatabases:Function"
+/// @{
+/// @brief Fetches available databases from target environment for mapping.
+/// @post targetDatabases array populated with available databases.
+/// @pre selectedTask must have to_env parameter set.
+/// @}
+void fetchTargetDatabases_Function(void);
+
+/// @defgroup handleMappingResolve_Function "handleMappingResolve:Function"
+/// @{
+/// @brief Resolves missing database mapping and continues migration.
+/// @post Mapping created in backend, task resumed with resolution params.
+/// @pre event.detail contains sourceDbUuid, targetDbUuid, targetDbName.
+/// @}
+void handleMappingResolve_Function(void);
+
+/// @defgroup handlePasswordResume_Function "handlePasswordResume:Function"
+/// @{
+/// @brief Submits passwords and resumes paused migration task.
+/// @post Task resumed with passwords, connection status restored to connected.
+/// @pre event.detail contains passwords object.
+/// @}
+void handlePasswordResume_Function(void);
+
+/// @defgroup startDataTimeout_Function "startDataTimeout:Function"
+/// @{
+/// @brief Starts timeout timer to detect idle connection.
+/// @post waitingForData set to true after 5 seconds if no data received.
+/// @pre connectionStatus is 'connected'.
+/// @}
+void startDataTimeout_Function(void);
+
+/// @defgroup resetDataTimeout_Function "resetDataTimeout:Function"
+/// @{
+/// @brief Resets data timeout timer when new data arrives.
+/// @post waitingForData reset to false, new timeout started.
+/// @pre dataTimeout must be set.
+/// @}
+void resetDataTimeout_Function(void);
+
+/// @defgroup Toast "Toast"
+/// @{
+/// @brief Displays transient notifications (toasts) in the bottom-right corner.
+/// @}
+void Toast(void);
+
+/// @defgroup TaskLogViewerTest_Module "TaskLogViewerTest:Module"
+/// @{
+/// @brief Unit tests for TaskLogViewer component by mounting it and observing the DOM.
+/// @invariant Duplicate logs are never appended. Polling only active for in-progress tasks.
+/// @}
+void TaskLogViewerTest_Module(void);
+
+/// @defgroup verifySessionAndAccess_Function "verifySessionAndAccess:Function"
+/// @{
+/// @brief Validates session and optional permission gate before allowing protected content render.
+/// @post hasRouteAccess=true only when user identity is valid and permission check (if provided) passes.
+/// @pre auth store is initialized and can provide token/user state; navigation is available.
+/// @}
+void verifySessionAndAccess_Function(void);
+
+/// @defgroup handleCreateBackup_Function "handleCreateBackup:Function"
+/// @{
+/// @brief Triggers a new backup task for the selected environment.
+/// @post A new task is created on the backend.
+/// @pre selectedEnvId must be a valid environment ID.
+/// @return {Promise}
+/// @}
+void handleCreateBackup_Function(void);
+
+/// @defgroup handleUpdateSchedule_Function "handleUpdateSchedule:Function"
+/// @{
+/// @brief Updates the backup schedule for the selected environment.
+/// @post Environment config is updated on the backend.
+/// @pre selectedEnvId must be set.
+/// @}
+void handleUpdateSchedule_Function(void);
+
+/// @defgroup loadBranches_Function "loadBranches:Function"
+/// @{
+/// @brief Загружает список веток для дашборда.
+/// @post branches обновлен.
+/// @pre dashboardId is provided.
+/// @}
+void loadBranches_Function(void);
+
+/// @defgroup handleSelect_Function "handleSelect:Function"
+/// @{
+/// @brief Handles branch selection from dropdown.
+/// @post handleCheckout is called with selected branch.
+/// @pre event contains branch name.
+/// @}
+void handleSelect_Function(void);
+
+/// @defgroup handleCheckout_Function "handleCheckout:Function"
+/// @{
+/// @brief Переключает текущую ветку.
+/// @param {string} branchName - Имя ветки.
+/// @post currentBranch обновлен, родительский callback вызван.
+/// @}
+void handleCheckout_Function(void);
+
+/// @defgroup handleCreate_Function "handleCreate:Function"
+/// @{
+/// @brief Создает новую ветку.
+/// @post Новая ветка создана и загружена; showCreate reset.
+/// @pre newBranchName is not empty.
+/// @}
+void handleCreate_Function(void);
+
+/// @defgroup loadHistory_Function "loadHistory:Function"
+/// @{
+/// @brief Fetch commit history from the backend.
+/// @post history state is updated.
+/// @pre dashboardId is valid.
+/// @}
+void loadHistory_Function(void);
+
+/// @defgroup handleGenerateMessage_Function "handleGenerateMessage:Function"
+/// @{
+/// @brief Generates a commit message using LLM.
+/// @}
+void handleGenerateMessage_Function(void);
+
+/// @defgroup loadStatus_Function "loadStatus:Function"
+/// @{
+/// @brief Загружает текущий статус репозитория и diff.
+/// @pre dashboardId должен быть валидным.
+/// @}
+void loadStatus_Function(void);
+
+/// @defgroup handleCommit_Function "handleCommit:Function"
+/// @{
+/// @brief Создает коммит с указанным сообщением.
+/// @post Коммит создан и модальное окно закрыто.
+/// @pre message не должно быть пустым.
+/// @}
+void handleCommit_Function(void);
+
+/// @defgroup loadStatus_Watcher "loadStatus:Watcher"
+/// @{
+/// @}
+void loadStatus_Watcher(void);
+
+/// @defgroup normalizeEnvStage_Function "normalizeEnvStage:Function"
+/// @{
+/// @brief Normalize environment stage with legacy production fallback.
+/// @post Returns DEV/PREPROD/PROD.
+/// @}
+void normalizeEnvStage_Function(void);
+
+/// @defgroup resolveEnvUrl_Function "resolveEnvUrl:Function"
+/// @{
+/// @brief Resolve environment URL from consolidated or git-specific payload shape.
+/// @post Returns stable URL string.
+/// @}
+void resolveEnvUrl_Function(void);
+
+/// @defgroup loadEnvironments_Function "loadEnvironments:Function"
+/// @{
+/// @brief Fetch available environments from API.
+/// @post environments state is populated.
+/// @}
+void loadEnvironments_Function(void);
+
+/// @defgroup handleDeploy_Function "handleDeploy:Function"
+/// @{
+/// @brief Trigger deployment to selected environment.
+/// @post Deploy request finishes and modal closes on success.
+/// @pre selectedEnv must be set.
+/// @}
+void handleDeploy_Function(void);
+
+/// @defgroup GitInitPanel "GitInitPanel"
+/// @{
+/// @brief Git initialization panel: select config, create remote repo, init local repo.
+/// @}
+void GitInitPanel(void);
+
+/// @defgroup GitManager "GitManager"
+/// @{
+/// @brief Central Git management UI — thin shell delegating to sub-panels and composable handlers.
+/// @}
+void GitManager(void);
+
+/// @defgroup GitMergeDialog "GitMergeDialog"
+/// @{
+/// @brief Unfinished merge recovery dialog: abort, continue, resolve conflicts.
+/// @}
+void GitMergeDialog(void);
+
+/// @defgroup GitOperationsPanel "GitOperationsPanel"
+/// @{
+/// @brief Git server operations panel: pull, push, and deploy actions.
+/// @}
+void GitOperationsPanel(void);
+
+/// @defgroup GitReleasePanel "GitReleasePanel"
+/// @{
+/// @brief Git release panel: promote branches via MR or direct mode.
+/// @}
+void GitReleasePanel(void);
+
+/// @defgroup GitWorkspacePanel "GitWorkspacePanel"
+/// @{
+/// @brief Git workspace panel: sync, commit message input, diff viewer, commit action.
+/// @}
+void GitWorkspacePanel(void);
+
+/// @defgroup GitManagerUnfinishedMergeIntegrationTest_Module "GitManagerUnfinishedMergeIntegrationTest:Module"
+/// @{
+/// @brief Protect unresolved-merge dialog contract in GitManager pull flow.
+/// @}
+void GitManagerUnfinishedMergeIntegrationTest_Module(void);
+
+/// @defgroup UseGitManager "UseGitManager"
+/// @{
+/// @brief Composable for GitManager handler functions — extracted to reduce component size per INV_7.
+/// @}
+void UseGitManager(void);
+
+/// @defgroup DocPreview "DocPreview"
+/// @{
+/// @brief UI component for previewing generated dataset documentation before saving.
+/// @}
+void DocPreview(void);
+
+/// @defgroup ProviderConfig "ProviderConfig"
+/// @{
+/// @brief UI form for managing LLM provider configurations.
+/// @}
+void ProviderConfig(void);
+
+/// @defgroup ValidationReport "ValidationReport"
+/// @{
+/// @brief Displays the results of an LLM-based dashboard validation task.
+/// @}
+void ValidationReport(void);
+
+/// @defgroup provider_config_edit_contract_tests_Function "provider_config_edit_contract_tests:Function"
+/// @{
+/// @brief Validate edit and delete handler wiring plus normalized edit form state mapping.
+/// @post Contract checks ensure edit click cannot degrade into no-op flow.
+/// @pre ProviderConfig component source exists in expected path.
+/// @}
+void provider_config_edit_contract_tests_Function(void);
+
+/// @defgroup isDirectory_Function "isDirectory:Function"
+/// @{
+/// @brief Checks if a file object represents a directory.
+/// @param {Object} file - The file object to check.
+/// @post Returns boolean.
+/// @pre file object has mime_type property.
+/// @return {boolean} True if it's a directory, false otherwise.
+/// @}
+void isDirectory_Function(void);
+
+/// @defgroup formatSize_Function "formatSize:Function"
+/// @{
+/// @brief Formats file size in bytes into a human-readable string.
+/// @param {number} bytes - The size in bytes.
+/// @post Returns formatted string.
+/// @pre bytes is a number.
+/// @return {string} Formatted size (e.g., "1.2 MB").
+/// @}
+void formatSize_Function(void);
+
+/// @defgroup formatDate_Function "formatDate:Function"
+/// @{
+/// @brief Formats an ISO date string into a localized readable format.
+/// @param {string} dateStr - The date string to format.
+/// @post Returns localized string.
+/// @pre dateStr is a valid date string.
+/// @return {string} Localized date and time.
+/// @}
+void formatDate_Function(void);
+
+/// @defgroup handleDownload_Function "handleDownload:Function"
+/// @{
+/// @brief Downloads selected file through authenticated API request.
+/// @post Browser download starts or user sees toast on failure.
+/// @pre file is a non-directory storage entry with category/path.
+/// @}
+void handleDownload_Function(void);
+
+/// @defgroup handleUpload_Function "handleUpload:Function"
+/// @{
+/// @brief Handles the file upload process.
+/// @post The file is uploaded to the server and a success toast is shown.
+/// @pre A file must be selected in the file input.
+/// @}
+void handleUpload_Function(void);
+
+/// @defgroup handleDrop_Function "handleDrop:Function"
+/// @{
+/// @brief Handles the file drop event for drag-and-drop.
+/// @param {DragEvent} event - The drop event.
+/// @}
+void handleDrop_Function(void);
+
+/// @defgroup LogEntryRow "LogEntryRow"
+/// @{
+/// @brief Renders a single log entry with stacked layout optimized for narrow drawer panels.
+/// @}
+void LogEntryRow(void);
+
+/// @defgroup formatTime_Function "formatTime:Function"
+/// @{
+/// @brief Format ISO timestamp to HH:MM:SS
+/// @}
+void formatTime_Function(void);
+
+/// @defgroup LogFilterBar "LogFilterBar"
+/// @{
+/// @brief Compact filter toolbar for logs — level, source, and text search in a single dense row.
+/// @}
+void LogFilterBar(void);
+
+/// @defgroup TaskLogPanel "TaskLogPanel"
+/// @{
+/// @brief Combines log filtering and display into a single cohesive light-themed panel.
+/// @invariant Must always display logs in chronological order and respect auto-scroll preference.
+/// @}
+void TaskLogPanel(void);
+
+/// @defgroup TaskResultPanel "TaskResultPanel"
+/// @{
+/// @brief Displays formatted task result summary with status badges and result details.
+/// @}
+void TaskResultPanel(void);
+
+/// @defgroup handleRunDebug_Function "handleRunDebug:Function"
+/// @{
+/// @brief Triggers the debug task.
+/// @post Task is started and polling begins.
+/// @pre Required fields are selected.
+/// @return {Promise}
+/// @}
+void handleRunDebug_Function(void);
+
+/// @defgroup startPolling_Function "startPolling:Function"
+/// @{
+/// @brief Polls for task completion.
+/// @param {string} taskId - ID of the task.
+/// @post Polls until success/failure.
+/// @pre Task ID is valid.
+/// @return {void}
+/// @}
+void startPolling_Function(void);
+
+/// @defgroup MapperTool "MapperTool"
+/// @{
+/// @brief UI component for mapping dataset column verbose names using Superset SQL Lab or Excel files.
+/// @}
+void MapperTool(void);
+
+/// @defgroup fetchData_Function "fetchData:Function"
+/// @{
+/// @brief Fetches environments.
+/// @post envs array is populated.
+/// @pre None.
+/// @}
+void fetchData_Function(void);
+
+/// @defgroup handleRunMapper_Function "handleRunMapper:Function"
+/// @{
+/// @brief Triggers the MapperPlugin task via new sqllab/excel sources.
+/// @post Mapper task is started and selectedTask is updated.
+/// @pre selectedEnv and datasetId are set; source-specific fields are valid.
+/// @}
+void handleRunMapper_Function(void);
+
+/// @defgroup handleGenerateDocs_Function "handleGenerateDocs:Function"
+/// @{
+/// @brief Triggers the LLM Documentation task.
+/// @post Documentation task is started.
+/// @pre selectedEnv and datasetId are set.
+/// @}
+void handleGenerateDocs_Function(void);
+
+/// @defgroup Counter "Counter"
+/// @{
+/// @brief Simple counter demo component
+/// @}
+void Counter(void);
+
+/// @defgroup ApiModule "ApiModule"
+/// @{
+/// @brief Handles all communication with the backend API via fetch wrappers with auth, error normalization, and toast feedback.
+/// @}
+void ApiModule(void);
+
+/// @defgroup ReportsApiTest "ReportsApiTest"
+/// @{
+/// @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+/// @}
+void ReportsApiTest(void);
+
+/// @defgroup ReportsApiTest_Module "ReportsApiTest:Module"
+/// @{
+/// @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+/// @invariant Pure functions produce deterministic output. Async wrappers propagate structured errors.
+/// @}
+void ReportsApiTest_Module(void);
+
+/// @defgroup TestBuildReportQueryString_Class "TestBuildReportQueryString:Class"
+/// @{
+/// @brief Validate query string construction from filter options.
+/// @post Correct URLSearchParams string produced.
+/// @pre Options object with various filter fields.
+/// @}
+void TestBuildReportQueryString_Class(void);
+
+/// @defgroup TestNormalizeApiError_Class "TestNormalizeApiError:Class"
+/// @{
+/// @brief Validate error normalization for UI-state mapping.
+/// @post Always returns {message, code, retryable} object.
+/// @pre Various error types (Error, string, object).
+/// @}
+void TestNormalizeApiError_Class(void);
+
+/// @defgroup TestGetReportsAsync_Class "TestGetReportsAsync:Class"
+/// @{
+/// @brief Validate getReports and getReportDetail with mocked api.fetchApi.
+/// @post Functions call correct endpoints and propagate results/errors.
+/// @pre api.fetchApi is mocked via vi.mock.
+/// @}
+void TestGetReportsAsync_Class(void);
+
+/// @defgroup AssistantApi "AssistantApi"
+/// @{
+/// @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, conversation management, and history retrieval.
+/// @}
+void AssistantApi(void);
+
+/// @defgroup AssistantApi_Module "AssistantApi:Module"
+/// @{
+/// @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, and history retrieval.
+/// @invariant All assistant requests must use requestApi wrapper (no native fetch).
+/// @}
+void AssistantApi_Module(void);
+
+/// @defgroup sendAssistantMessage_Function "sendAssistantMessage:Function"
+/// @{
+/// @brief Send a user message to assistant orchestrator endpoint.
+/// @post Returns assistant response object with deterministic state.
+/// @pre payload.message is a non-empty string.
+/// @}
+void sendAssistantMessage_Function(void);
+
+/// @defgroup buildAssistantSeedMessage_Function "buildAssistantSeedMessage:Function"
+/// @{
+/// @brief Compose visible assistant seed text from context label and prompt body.
+/// @post Returns trimmed seed message string for prefilled input.
+/// @pre prompt contains the user-visible request.
+/// @}
+void buildAssistantSeedMessage_Function(void);
+
+/// @defgroup confirmAssistantOperation_Function "confirmAssistantOperation:Function"
+/// @{
+/// @brief Confirm a pending risky assistant operation.
+/// @post Returns execution response (started/success/failed).
+/// @pre confirmationId references an existing pending token.
+/// @}
+void confirmAssistantOperation_Function(void);
+
+/// @defgroup cancelAssistantOperation_Function "cancelAssistantOperation:Function"
+/// @{
+/// @brief Cancel a pending risky assistant operation.
+/// @post Operation is cancelled and cannot be executed by this token.
+/// @pre confirmationId references an existing pending token.
+/// @}
+void cancelAssistantOperation_Function(void);
+
+/// @defgroup getAssistantHistory_Function "getAssistantHistory:Function"
+/// @{
+/// @brief Retrieve paginated assistant conversation history.
+/// @post Returns a paginated payload with history items.
+/// @pre page/pageSize are positive integers.
+/// @}
+void getAssistantHistory_Function(void);
+
+/// @defgroup getAssistantConversations_Function "getAssistantConversations:Function"
+/// @{
+/// @brief Retrieve paginated conversation list for assistant sidebar/history switcher.
+/// @post Returns paginated conversation summaries.
+/// @pre page/pageSize are positive integers.
+/// @}
+void getAssistantConversations_Function(void);
+
+/// @defgroup deleteAssistantConversation_Function "deleteAssistantConversation:Function"
+/// @{
+/// @brief Soft-delete or hard-delete a conversation.
+/// @post Returns success status.
+/// @pre conversationId string is provided.
+/// @}
+void deleteAssistantConversation_Function(void);
+
+/// @defgroup DatasetReviewApi "DatasetReviewApi"
+/// @{
+/// @brief Shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and session DTO normalization.
+/// @}
+void DatasetReviewApi(void);
+
+/// @defgroup DatasetReviewApi_Module "DatasetReviewApi:Module"
+/// @{
+/// @brief Provide shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and refreshed session DTO normalization.
+/// @}
+void DatasetReviewApi_Module(void);
+
+/// @defgroup buildDatasetReviewRequestOptions_Function "buildDatasetReviewRequestOptions:Function"
+/// @{
+/// @brief Attach optimistic-lock session version header when the current version is known.
+/// @post Returns requestApi-compatible options object.
+/// @pre sessionVersion may be null when no loaded session version exists yet.
+/// @}
+void buildDatasetReviewRequestOptions_Function(void);
+
+/// @defgroup requestDatasetReviewApi_Function "requestDatasetReviewApi:Function"
+/// @{
+/// @brief Proxy dataset review mutations through requestApi with optional optimistic-lock headers.
+/// @post Executes requestApi with X-Session-Version only when a session version is known.
+/// @pre endpoint and method are valid requestApi inputs.
+/// @}
+void requestDatasetReviewApi_Function(void);
+
+/// @defgroup isDatasetReviewConflictError_Function "isDatasetReviewConflictError:Function"
+/// @{
+/// @brief Detect optimistic-lock conflicts from dataset review mutations.
+/// @post Returns true when the mutation failed with 409 conflict semantics.
+/// @pre error may be null or a normalized API error.
+/// @}
+void isDatasetReviewConflictError_Function(void);
+
+/// @defgroup getDatasetReviewConflictMessage_Function "getDatasetReviewConflictMessage:Function"
+/// @{
+/// @brief Return explicit 409-style guidance for stale dataset review mutations.
+/// @post Returns a user-facing conflict message string.
+/// @pre error may be null or a normalized API error.
+/// @}
+void getDatasetReviewConflictMessage_Function(void);
+
+/// @defgroup extractDatasetReviewVersion_Function "extractDatasetReviewVersion:Function"
+/// @{
+/// @brief Resolve the latest session version from refreshed DTO fragments.
+/// @post Returns the newest known session version or null.
+/// @pre payload may be a session summary, a detail payload, or a mutation fragment.
+/// @}
+void extractDatasetReviewVersion_Function(void);
+
+/// @defgroup normalizeDatasetReviewDetail_Function "normalizeDatasetReviewDetail:Function"
+/// @{
+/// @brief Normalize refreshed session-detail DTOs into the legacy route-friendly workspace shape.
+/// @post Returns a shape with flattened summary fields plus refreshed collections and version metadata.
+/// @pre detail may already be legacy-flat or refreshed with nested session/session_version fields.
+/// @}
+void normalizeDatasetReviewDetail_Function(void);
+
+/// @defgroup MaintenanceApi "MaintenanceApi"
+/// @{
+/// @brief API client for Maintenance Banner endpoints. Uses requestApi for all calls.
+/// @}
+void MaintenanceApi(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__startMaintenance "frontend/src/lib/api/maintenance.js::startMaintenance"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__startMaintenance(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__endMaintenance "frontend/src/lib/api/maintenance.js::endMaintenance"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__endMaintenance(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__endAllMaintenance "frontend/src/lib/api/maintenance.js::endAllMaintenance"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__endAllMaintenance(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__getSettings "frontend/src/lib/api/maintenance.js::getSettings"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__getSettings(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__updateSettings "frontend/src/lib/api/maintenance.js::updateSettings"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__updateSettings(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__listEvents "frontend/src/lib/api/maintenance.js::listEvents"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__listEvents(void);
+
+/// @defgroup frontend_src_lib_api_maintenance_js__listDashboardBanners "frontend/src/lib/api/maintenance.js::listDashboardBanners"
+/// @{
+/// @}
+void frontend_src_lib_api_maintenance_js__listDashboardBanners(void);
+
+/// @defgroup ReportsApi "ReportsApi"
+/// @{
+/// @brief Wrapper-based reports API client for list/detail retrieval through the shared API wrapper.
+/// @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+/// @pre Shared API wrapper is configured for the current frontend auth/session context.
+/// @}
+void ReportsApi(void);
+
+/// @defgroup ReportsApi_Module "ReportsApi:Module"
+/// @{
+/// @brief Wrapper-based reports API client for list/detail retrieval without direct native fetch usage.
+/// @invariant Uses existing api wrapper methods and returns structured errors for UI-state mapping.
+/// @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+/// @pre Shared API wrapper is configured for the current frontend auth/session context.
+/// @}
+void ReportsApi_Module(void);
+
+/// @defgroup buildReportQueryString_Function "buildReportQueryString:Function"
+/// @{
+/// @brief Build query string for reports list endpoint from filter options.
+/// @post Returns URL query string without leading '?'.
+/// @pre options is an object with optional report query fields.
+/// @}
+void buildReportQueryString_Function(void);
+
+/// @defgroup normalizeApiError_Function "normalizeApiError:Function"
+/// @{
+/// @brief Convert unknown API exceptions into deterministic UI-consumable error objects.
+/// @post Returns structured error object.
+/// @pre error may be Error/string/object.
+/// @}
+void normalizeApiError_Function(void);
+
+/// @defgroup getReports_Function "getReports:Function"
+/// @{
+/// @brief Fetch unified report list using existing request wrapper.
+/// @post Returns parsed payload or structured error for UI-state mapping.
+/// @pre valid auth context for protected endpoint.
+/// @}
+void getReports_Function(void);
+
+/// @defgroup getReportDetail_Function "getReportDetail:Function"
+/// @{
+/// @brief Fetch one report detail by report_id.
+/// @post Returns parsed detail payload or structured error object.
+/// @pre reportId is non-empty string; valid auth context.
+/// @}
+void getReportDetail_Function(void);
+
+/// @defgroup TranslateApi "TranslateApi"
+/// @{
+/// @brief Barrel module re-exporting all translate API functions from domain-split modules.
+/// @}
+void TranslateApi(void);
+
+/// @defgroup TargetSchemaApiTest "TargetSchemaApiTest"
+/// @{
+/// @brief Unit tests for checkTargetTableSchema API client fetch wrapper.
+/// @}
+void TargetSchemaApiTest(void);
+
+/// @defgroup test_success "test_success"
+/// @{
+/// @brief Happy path — API returns full validation result.
+/// @}
+void test_success(void);
+
+/// @defgroup test_api_error "test_api_error"
+/// @{
+/// @brief API error returns fallback response with error message.
+/// @}
+void test_api_error(void);
+
+/// @defgroup test_error_string_fallback "test_error_string_fallback"
+/// @{
+/// @brief String error is captured as message.
+/// @}
+void test_error_string_fallback(void);
+
+/// @defgroup TranslateCorrectionsApi "TranslateCorrectionsApi"
+/// @{
+/// @brief API client for translation corrections — inline edits, dictionary submission, bulk find-and-replace, CSV download.
+/// @}
+void TranslateCorrectionsApi(void);
+
+/// @defgroup TranslateDatasourcesApi "TranslateDatasourcesApi"
+/// @{
+/// @brief API client for translation datasources — column fetching, preview, row-level review actions.
+/// @}
+void TranslateDatasourcesApi(void);
+
+/// @defgroup TranslateDictionariesApi "TranslateDictionariesApi"
+/// @{
+/// @brief API client for translation dictionary CRUD — list, create, update, delete, entries, import.
+/// @}
+void TranslateDictionariesApi(void);
+
+/// @defgroup TranslateJobsApi "TranslateJobsApi"
+/// @{
+/// @brief API client for translation job CRUD — list, create, update, delete, duplicate.
+/// @}
+void TranslateJobsApi(void);
+
+/// @defgroup TranslateRunsApi "TranslateRunsApi"
+/// @{
+/// @brief API client for translation run control — trigger, status, history, records, retry, cancel, metrics.
+/// @}
+void TranslateRunsApi(void);
+
+/// @defgroup TranslateSchedulesApi "TranslateSchedulesApi"
+/// @{
+/// @brief API client for translation job scheduling — CRUD, enable/disable, next executions.
+/// @}
+void TranslateSchedulesApi(void);
+
+/// @defgroup TranslateTargetSchemaApi "TranslateTargetSchemaApi"
+/// @{
+/// @brief API client for target table schema validation.
+/// @}
+void TranslateTargetSchemaApi(void);
+
+/// @defgroup frontend_src_lib_api_translate_target_schema_js__checkTargetTableSchema "frontend/src/lib/api/translate/target-schema.js::checkTargetTableSchema"
+/// @{
+/// @}
+void frontend_src_lib_api_translate_target_schema_js__checkTargetTableSchema(void);
+
+/// @defgroup ValidationApi "ValidationApi"
+/// @{
+/// @brief API client functions for the Validation section — tasks and runs CRUD.
+/// @}
+void ValidationApi(void);
+
+/// @defgroup buildParams_Function "buildParams:Function"
+/// @{
+/// @brief Build URLSearchParams from a params object, skipping null/undefined/empty values.
+/// @param {Record} params
+/// @}
+void buildParams_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__buildParams "frontend/src/lib/api/validation.js::buildParams"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__buildParams(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__fetchTasks "frontend/src/lib/api/validation.js::fetchTasks"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__fetchTasks(void);
+
+/// @defgroup createTask_Function "createTask:Function"
+/// @{
+/// @param {Record} data
+/// @}
+void createTask_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__createTask "frontend/src/lib/api/validation.js::createTask"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__createTask(void);
+
+/// @defgroup fetchTask_Function "fetchTask:Function"
+/// @{
+/// @param {string} id
+/// @}
+void fetchTask_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__fetchTask "frontend/src/lib/api/validation.js::fetchTask"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__fetchTask(void);
+
+/// @defgroup updateTask_Function "updateTask:Function"
+/// @{
+/// @param {string} id @param {Record} data
+/// @}
+void updateTask_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__updateTask "frontend/src/lib/api/validation.js::updateTask"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__updateTask(void);
+
+/// @defgroup deleteTask_Function "deleteTask:Function"
+/// @{
+/// @param {string} id @param {boolean} [deleteRuns]
+/// @}
+void deleteTask_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__deleteTask "frontend/src/lib/api/validation.js::deleteTask"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__deleteTask(void);
+
+/// @defgroup triggerRun_Function "triggerRun:Function"
+/// @{
+/// @param {string} id
+/// @}
+void triggerRun_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__triggerRun "frontend/src/lib/api/validation.js::triggerRun"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__triggerRun(void);
+
+/// @defgroup duplicateTask_Function "duplicateTask:Function"
+/// @{
+/// @param {string} id
+/// @}
+void duplicateTask_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__duplicateTask "frontend/src/lib/api/validation.js::duplicateTask"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__duplicateTask(void);
+
+/// @defgroup fetchRuns_Function "fetchRuns:Function"
+/// @{
+/// @param {{ task_id?: string, dashboard_id?: string, environment_id?: string, status?: string, date_from?: string, date_to?: string, page?: number, page_size?: number }} [params]
+/// @}
+void fetchRuns_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__fetchRuns "frontend/src/lib/api/validation.js::fetchRuns"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__fetchRuns(void);
+
+/// @defgroup fetchRunDetail_Function "fetchRunDetail:Function"
+/// @{
+/// @param {string} id
+/// @}
+void fetchRunDetail_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__fetchRunDetail "frontend/src/lib/api/validation.js::fetchRunDetail"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__fetchRunDetail(void);
+
+/// @defgroup deleteRun_Function "deleteRun:Function"
+/// @{
+/// @param {string} id
+/// @}
+void deleteRun_Function(void);
+
+/// @defgroup frontend_src_lib_api_validation_js__deleteRun "frontend/src/lib/api/validation.js::deleteRun"
+/// @{
+/// @}
+void frontend_src_lib_api_validation_js__deleteRun(void);
+
+/// @defgroup PermissionsTest "PermissionsTest"
+/// @{
+/// @brief Verifies frontend RBAC permission parsing and access checks.
+/// @}
+void PermissionsTest(void);
+
+/// @defgroup PermissionsTest_Module "PermissionsTest:Module"
+/// @{
+/// @brief Verifies frontend RBAC permission parsing and access checks.
+/// @}
+void PermissionsTest_Module(void);
+
+/// @defgroup PermissionsModule "PermissionsModule"
+/// @{
+/// @brief Shared frontend RBAC utilities for route guards, permission checks, and menu visibility based on user roles.
+/// @}
+void PermissionsModule(void);
+
+/// @defgroup Permissions_Module "Permissions:Module"
+/// @{
+/// @brief Shared frontend RBAC utilities for route guards and menu visibility.
+/// @invariant Admin role always bypasses explicit permission checks.
+/// @}
+void Permissions_Module(void);
+
+/// @defgroup normalizePermissionRequirement_Function "normalizePermissionRequirement:Function"
+/// @{
+/// @brief Convert permission requirement string to canonical resource/action tuple.
+/// @post Returns normalized object with action in uppercase.
+/// @pre Permission can be "resource" or "resource:ACTION" where resource itself may contain ":".
+/// @}
+void normalizePermissionRequirement_Function(void);
+
+/// @defgroup isAdminUser_Function "isAdminUser:Function"
+/// @{
+/// @brief Determine whether user has Admin role.
+/// @post Returns true when at least one role name equals "Admin" (case-insensitive).
+/// @pre user can be null or partially populated.
+/// @}
+void isAdminUser_Function(void);
+
+/// @defgroup hasPermission_Function "hasPermission:Function"
+/// @{
+/// @brief Check if user has a required resource/action permission.
+/// @post Returns true when requirement is empty, user is admin, or matching permission exists.
+/// @pre user contains roles with permissions from /api/auth/me payload.
+/// @}
+void hasPermission_Function(void);
+
+/// @defgroup AuthStore "AuthStore"
+/// @{
+/// @brief Manages the global authentication state including JWT token, user profile, and login/logout lifecycle.
+/// @}
+void AuthStore(void);
+
+/// @defgroup authStore_Store "authStore:Store"
+/// @{
+/// @brief Manages the global authentication state on the frontend.
+/// @}
+void authStore_Store(void);
+
+/// @defgroup AuthState_Interface "AuthState:Interface"
+/// @{
+/// @brief Defines the structure of the authentication state.
+/// @}
+void AuthState_Interface(void);
+
+/// @defgroup frontend_src_lib_auth_store_ts__AuthState "frontend/src/lib/auth/store.ts::AuthState"
+/// @{
+/// @}
+void frontend_src_lib_auth_store_ts__AuthState(void);
+
+/// @defgroup createAuthStore_Function "createAuthStore:Function"
+/// @{
+/// @brief Creates and configures the auth store with helper methods.
+/// @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+/// @pre No preconditions - initialization function.
+/// @return {Writable}
+/// @}
+void createAuthStore_Function(void);
+
+/// @defgroup frontend_src_lib_auth_store_ts__createAuthStore "frontend/src/lib/auth/store.ts::createAuthStore"
+/// @{
+/// @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+/// @pre No preconditions - initialization function.
+/// @}
+void frontend_src_lib_auth_store_ts__createAuthStore(void);
+
+/// @defgroup setToken_Function "setToken:Function"
+/// @{
+/// @brief Updates the store with a new JWT token.
+/// @param {string} token - The JWT access token.
+/// @post Store updated with new token, isAuthenticated set to true.
+/// @pre token must be a valid JWT string.
+/// @}
+void setToken_Function(void);
+
+/// @defgroup setUser_Function "setUser:Function"
+/// @{
+/// @brief Sets the current user profile data.
+/// @param {any} user - The user profile object.
+/// @post Store updated with user, isAuthenticated true, loading false.
+/// @pre User object must contain valid profile data.
+/// @}
+void setUser_Function(void);
+
+/// @defgroup logout_Function "logout:Function"
+/// @{
+/// @brief Clears authentication state and storage.
+/// @post Auth token removed from localStorage, store reset to initial state.
+/// @pre User is currently authenticated.
+/// @}
+void logout_Function(void);
+
+/// @defgroup setLoading_Function "setLoading:Function"
+/// @{
+/// @brief Updates the loading state.
+/// @param {boolean} loading - Loading status.
+/// @post Store loading state updated.
+/// @pre None.
+/// @}
+void setLoading_Function(void);
+
+/// @defgroup AssistantClarificationCard "AssistantClarificationCard"
+/// @{
+/// @brief Render the active dataset-review clarification queue inside AssistantChatPanel so users can answer, skip, defer, and resume questions without leaving the assistant workspace.
+/// @post Clarification queue state is readable in-chat and answer mutations refresh the active question state without requiring a dedicated dialog.
+/// @pre sessionId belongs to the current dataset review workspace and the assistant drawer is open for session-scoped work.
+/// @}
+void AssistantClarificationCard(void);
+
+/// @defgroup readJson_Function "readJson:Function"
+/// @{
+/// @brief Read and parse JSON fixture file from disk.
+/// @post Returns parsed object representation.
+/// @pre filePath points to existing UTF-8 JSON file.
+/// @}
+void readJson_Function(void);
+
+/// @defgroup AssistantClarificationIntegrationTest_Module "AssistantClarificationIntegrationTest:Module"
+/// @{
+/// @brief Verify AssistantChatPanel hosts the resumable dataset-review clarification flow inside the assistant drawer and refreshes workspace session state after answering.
+/// @}
+void AssistantClarificationIntegrationTest_Module(void);
+
+/// @defgroup AssistantFirstMessageIntegrationTest_Module "AssistantFirstMessageIntegrationTest:Module"
+/// @{
+/// @brief Verify first optimistic user message stays visible while a new conversation request is pending.
+/// @invariant Starting a new conversation must not trigger history reload that overwrites the first local user message.
+/// @}
+void AssistantFirstMessageIntegrationTest_Module(void);
+
+/// @defgroup assistant_first_message_tests_Function "assistant_first_message_tests:Function"
+/// @{
+/// @brief Guard optimistic first-message UX against history reload race in new conversation flow.
+/// @post First user message remains visible before pending send request resolves.
+/// @pre Assistant panel renders with open state and mocked network dependencies.
+/// @}
+void assistant_first_message_tests_Function(void);
+
+/// @defgroup CompiledSQLPreview "CompiledSQLPreview"
+/// @{
+/// @brief Present the exact Superset-generated compiled SQL preview, expose readiness or staleness clearly, and preserve readable recovery paths when preview generation fails.
+/// @post Users can distinguish missing, pending, ready, stale, and error preview states and can trigger only Superset-backed preview generation.
+/// @pre Session id is available and preview state comes from the current ownership-scoped session detail payload.
+/// @}
+void CompiledSQLPreview(void);
+
+/// @defgroup ExecutionMappingReview "ExecutionMappingReview"
+/// @{
+/// @brief Review imported-filter to template-variable mappings, surface effective values and blockers, and require explicit approval for warning-sensitive execution inputs before preview or launch.
+/// @post Users can review effective mapping values, approve warning-sensitive transformations, or manually override them while unresolved required-value blockers remain visible.
+/// @pre Session id, execution mappings, imported filters, and template variables belong to the current ownership-scoped session payload.
+/// @}
+void ExecutionMappingReview(void);
+
+/// @defgroup LaunchConfirmationPanel "LaunchConfirmationPanel"
+/// @{
+/// @brief Summarize final execution context, surface launch blockers explicitly, and confirm only a gate-complete SQL Lab launch request.
+/// @post Users can see why launch is blocked or confirm a run-ready launch with explicit SQL Lab handoff evidence.
+/// @pre Session detail, mappings, findings, preview state, and latest run context belong to the current ownership-scoped session payload.
+/// @}
+void LaunchConfirmationPanel(void);
+
+/// @defgroup SemanticLayerReview "SemanticLayerReview"
+/// @{
+/// @brief Surface field-level semantic decisions with provenance, confidence, candidate acceptance, and manual override safeguards for US2 review flow.
+/// @post Users can review the current semantic value, accept a candidate, apply manual override, and lock or unlock field state without violating backend provenance rules.
+/// @pre Session id is available and semantic field entries come from the current ownership-scoped session detail payload.
+/// @}
+void SemanticLayerReview(void);
+
+/// @defgroup SourceIntakePanel "SourceIntakePanel"
+/// @{
+/// @brief Collect initial dataset source input through Superset link paste or dataset selection entry paths.
+/// @}
+void SourceIntakePanel(void);
+
+/// @defgroup ValidationFindingsPanel "ValidationFindingsPanel"
+/// @{
+/// @brief Present validation findings grouped by severity with explicit resolution and actionability signals.
+/// @}
+void ValidationFindingsPanel(void);
+
+/// @defgroup SourceIntakePanelUxTests_Module "SourceIntakePanelUxTests:Module"
+/// @{
+/// @brief Verify source intake entry paths, validation feedback, and submit payload behavior for US1.
+/// @}
+void SourceIntakePanelUxTests_Module(void);
+
+/// @defgroup DatasetReviewUs2WorkspaceUxTests_Module "DatasetReviewUs2WorkspaceUxTests:Module"
+/// @{
+/// @brief Verify US2 dataset review surfaces keep semantic review actionable, route clarification through AssistantChatPanel, and preserve explicit preview/mapping gates.
+/// @}
+void DatasetReviewUs2WorkspaceUxTests_Module(void);
+
+/// @defgroup DatasetReviewUs3UxTests_Module "DatasetReviewUs3UxTests:Module"
+/// @{
+/// @brief Verify US3 mapping review, Superset preview, and launch confirmation UX contracts.
+/// @}
+void DatasetReviewUs3UxTests_Module(void);
+
+/// @defgroup ValidationFindingsPanelUxTests_Module "ValidationFindingsPanelUxTests:Module"
+/// @{
+/// @brief Verify grouped findings visibility, empty state, and remediation jump behavior for US1.
+/// @}
+void ValidationFindingsPanelUxTests_Module(void);
+
+/// @defgroup HealthMatrix "HealthMatrix"
+/// @{
+/// @brief Visual grid summary representing dashboard health status counts.
+/// @}
+void HealthMatrix(void);
+
+/// @defgroup PolicyForm "PolicyForm"
+/// @{
+/// @brief Form for creating and editing validation policies.
+/// @post Form submission forwards the current draft to onSave and cancel delegates dismissal to the parent callback without mutating external state directly.
+/// @pre Parent provides callable onSave/onCancel handlers and an environments collection that may be empty but remains array-like.
+/// @}
+void PolicyForm(void);
+
+/// @defgroup ScheduleAtAGlance "ScheduleAtAGlance"
+/// @{
+/// @brief Compact weekly schedule widget showing active validation tasks with day grid, time windows, and cross-referenced health status.
+/// @}
+void ScheduleAtAGlance(void);
+
+/// @defgroup Sidebar "Sidebar"
+/// @{
+/// @brief Persistent left sidebar with grouped sections (Resources/Operations/System), expand/collapse, health indicators, RBAC filtering, profile footer.
+/// @}
+void Sidebar(void);
+
+/// @defgroup disconnectWebSocket_Function "disconnectWebSocket:Function"
+/// @{
+/// @brief Disconnects the active WebSocket connection
+/// @post ws is closed and set to null
+/// @pre ws may or may not be initialized
+/// @}
+void disconnectWebSocket_Function(void);
+
+/// @defgroup loadRecentTasks_Function "loadRecentTasks:Function"
+/// @{
+/// @brief Load recent tasks for list mode display
+/// @post recentTasks array populated with task list
+/// @pre User is on task drawer or api is ready.
+/// @}
+void loadRecentTasks_Function(void);
+
+/// @defgroup selectTask_Function "selectTask:Function"
+/// @{
+/// @brief Select a task from list to view details
+/// @post drawer state updated to show task details
+/// @pre task is a valid task object
+/// @}
+void selectTask_Function(void);
+
+/// @defgroup goBackToList_Function "goBackToList:Function"
+/// @{
+/// @brief Return to task list view from task details
+/// @post Drawer switches to list view and reloads tasks
+/// @pre Drawer is open and activeTaskId is set
+/// @}
+void goBackToList_Function(void);
+
+/// @defgroup SidebarNavigationTest_Module "SidebarNavigationTest:Module"
+/// @{
+/// @brief Verifies RBAC-based sidebar sections and category visibility.
+/// @}
+void SidebarNavigationTest_Module(void);
+
+/// @defgroup BreadcrumbsContractTest_Module "BreadcrumbsContractTest:Module"
+/// @{
+/// @brief Contract-focused unit tests for Breadcrumbs.svelte logic and UX annotations
+/// @}
+void BreadcrumbsContractTest_Module(void);
+
+/// @defgroup SidebarStoreTest_Module "SidebarStoreTest:Module"
+/// @{
+/// @brief Unit tests for Sidebar.svelte component
+/// @}
+void SidebarStoreTest_Module(void);
+
+/// @defgroup TaskDrawerStoreTest_Module "TaskDrawerStoreTest:Module"
+/// @{
+/// @brief Unit tests for TaskDrawer.svelte component
+/// @}
+void TaskDrawerStoreTest_Module(void);
+
+/// @defgroup TopNavbarStoreTest_Module "TopNavbarStoreTest:Module"
+/// @{
+/// @brief Unit tests for TopNavbar.svelte component
+/// @}
+void TopNavbarStoreTest_Module(void);
+
+/// @defgroup PageContracts "PageContracts"
+/// @{
+/// @brief Contract implemented by all Svelte route pages — defines page-level behavior and routing structure.
+/// @}
+void PageContracts(void);
+
+/// @defgroup NavigationContracts "NavigationContracts"
+/// @{
+/// @brief Contract for navigation structure — sidebar sections, route categories, and menu item hierarchy.
+/// @}
+void NavigationContracts(void);
+
+/// @defgroup SidebarNavigation_Module "SidebarNavigation:Module"
+/// @{
+/// @brief Build sidebar navigation sections and categories filtered by user permissions and feature flags.
+/// @invariant Admin role can access all categories and subitems through permission utility.
+/// @}
+void SidebarNavigation_Module(void);
+
+/// @defgroup isItemAllowed_Function "isItemAllowed:Function"
+/// @{
+/// @brief Check whether a single menu node can be shown for a given user.
+/// @post Returns true when no permission is required or permission check passes.
+/// @pre item can contain optional requiredPermission/requiredAction.
+/// @}
+void isItemAllowed_Function(void);
+
+/// @defgroup isFeatureEnabled_Function "isFeatureEnabled:Function"
+/// @{
+/// @}
+void isFeatureEnabled_Function(void);
+
+/// @defgroup buildSidebarSections_Function "buildSidebarSections:Function"
+/// @{
+/// @brief Build translated sidebar sections with categories, filtered by RBAC permissions and feature flags.
+/// @post Returns only sections/categories/subitems available for provided user and enabled features.
+/// @pre i18nState provides nav labels; user can be null; features default to {} (all enabled).
+/// @}
+void buildSidebarSections_Function(void);
+
+/// @defgroup ReportCardTest_Module "ReportCardTest:Module"
+/// @{
+/// @brief Test UX states and transitions for ReportCard component
+/// @invariant Each test asserts at least one observable UX contract outcome.
+/// @}
+void ReportCardTest_Module(void);
+
+/// @defgroup ReportDetailIntegrationTest_Module "ReportDetailIntegrationTest:Module"
+/// @{
+/// @brief Validate detail-panel behavior for failed reports and recovery guidance visibility.
+/// @invariant Failed report detail exposes actionable next actions when available.
+/// @}
+void ReportDetailIntegrationTest_Module(void);
+
+/// @defgroup ReportDetailUxTest_Module "ReportDetailUxTest:Module"
+/// @{
+/// @brief Test UX states and recovery for ReportDetailPanel component
+/// @invariant Detail UX tests keep placeholder-safe rendering and recovery visibility verifiable.
+/// @}
+void ReportDetailUxTest_Module(void);
+
+/// @defgroup _EXT_frontend_ReportTypeProfiles_Test_Module "[EXT:frontend:ReportTypeProfiles]Test:Module"
+/// @{
+/// @brief Validate report type profile mapping and unknown fallback behavior.
+/// @invariant Unknown task_type always resolves to the fallback profile.
+/// @}
+void _EXT_frontend_ReportTypeProfiles_Test_Module(void);
+
+/// @defgroup ReportsFilterPerformanceTest_Module "ReportsFilterPerformanceTest:Module"
+/// @{
+/// @brief Guard test for report filter responsiveness on moderate in-memory dataset.
+/// @}
+void ReportsFilterPerformanceTest_Module(void);
+
+/// @defgroup ReportsListTest_Module "ReportsListTest:Module"
+/// @{
+/// @brief Test ReportsList component iteration and event forwarding.
+/// @}
+void ReportsListTest_Module(void);
+
+/// @defgroup ReportsPageTest_Module "ReportsPageTest:Module"
+/// @{
+/// @brief Integration-style checks for unified mixed-type reports rendering expectations.
+/// @invariant Mixed fixture includes all supported report types in one list.
+/// @}
+void ReportsPageTest_Module(void);
+
+/// @defgroup ReportTypeProfiles_Module "ReportTypeProfiles:Module"
+/// @{
+/// @brief Deterministic mapping from report task_type to visual profile with one fallback.
+/// @}
+void ReportTypeProfiles_Module(void);
+
+/// @defgroup getReportTypeProfile_Function "getReportTypeProfile:Function"
+/// @{
+/// @brief Resolve visual profile by task type with guaranteed fallback.
+/// @post Returns one profile object.
+/// @pre taskType may be known/unknown/empty.
+/// @}
+void getReportTypeProfile_Function(void);
+
+/// @defgroup ApiKeysTab "ApiKeysTab"
+/// @{
+/// @brief API Key management tab — list, generate (one-time reveal), and revoke API keys.
+/// @}
+void ApiKeysTab(void);
+
+/// @defgroup BulkCorrectionSidebar "BulkCorrectionSidebar"
+/// @{
+/// @brief Component component: lib/components/translate/BulkCorrectionSidebar.svelte
+/// @}
+void BulkCorrectionSidebar(void);
+
+/// @defgroup BulkReplaceModal "BulkReplaceModal"
+/// @{
+/// @brief Modal dialog for bulk find-and-replace on translated values within a completed run.
+/// @}
+void BulkReplaceModal(void);
+
+/// @defgroup CorrectionCell "CorrectionCell"
+/// @{
+/// @brief Inline-editable cell for translation run results with edit-save-cancel UX and submit-to-dictionary flow.
+/// @}
+void CorrectionCell(void);
+
+/// @defgroup ScheduleConfig "ScheduleConfig"
+/// @{
+/// @brief Component component: lib/components/translate/ScheduleConfig.svelte
+/// @}
+void ScheduleConfig(void);
+
+/// @defgroup TargetSchemaHint "TargetSchemaHint"
+/// @{
+/// @brief Подсказка о колонках целевой таблицы + кнопка "Проверить схему".
+/// @}
+void TargetSchemaHint(void);
+
+/// @defgroup TermCorrectionPopup "TermCorrectionPopup"
+/// @{
+/// @brief Component component: lib/components/translate/TermCorrectionPopup.svelte
+/// @}
+void TermCorrectionPopup(void);
+
+/// @defgroup TranslationMetricsDashboard "TranslationMetricsDashboard"
+/// @{
+/// @brief Component component: lib/components/translate/TranslationMetricsDashboard.svelte
+/// @}
+void TranslationMetricsDashboard(void);
+
+/// @defgroup TranslationPreview "TranslationPreview"
+/// @{
+/// @brief Component component: lib/components/translate/TranslationPreview.svelte
+/// @}
+void TranslationPreview(void);
+
+/// @defgroup TranslationRunGlobalIndicator "TranslationRunGlobalIndicator"
+/// @{
+/// @brief Persistent rich progress panel for active translation runs, rendered in root layout.
+/// @}
+void TranslationRunGlobalIndicator(void);
+
+/// @defgroup TranslationRunProgress "TranslationRunProgress"
+/// @{
+/// @brief Component component: lib/components/translate/TranslationRunProgress.svelte
+/// @}
+void TranslationRunProgress(void);
+
+/// @defgroup TranslationRunResult "TranslationRunResult"
+/// @{
+/// @brief Component component: lib/components/translate/TranslationRunResult.svelte
+/// @}
+void TranslationRunResult(void);
+
+/// @defgroup TargetSchemaHintTest "TargetSchemaHintTest"
+/// @{
+/// @brief Contract-focused unit tests for TargetSchemaHint.svelte component.
+/// @}
+void TargetSchemaHintTest(void);
+
+/// @defgroup test_component_exists "test_component_exists"
+/// @{
+/// @brief Verify component file exists.
+/// @}
+void test_component_exists(void);
+
+/// @defgroup test_ux_state_contracts "test_ux_state_contracts"
+/// @{
+/// @brief Component contains required UX state tags.
+/// @}
+void test_ux_state_contracts(void);
+
+/// @defgroup test_props_definition "test_props_definition"
+/// @{
+/// @brief Component accepts required props.
+/// @}
+void test_props_definition(void);
+
+/// @defgroup test_button_check_disabled_logic "test_button_check_disabled_logic"
+/// @{
+/// @brief Button disabled logic: canCheck derived checks all required props.
+/// @}
+void test_button_check_disabled_logic(void);
+
+/// @defgroup test_idle_state "test_idle_state"
+/// @{
+/// @brief Idle state shows hint text and check button.
+/// @}
+void test_idle_state(void);
+
+/// @defgroup test_checking_state "test_checking_state"
+/// @{
+/// @brief Checking state shows spinner and disables button.
+/// @}
+void test_checking_state(void);
+
+/// @defgroup test_complete_state "test_complete_state"
+/// @{
+/// @brief Complete state shows result with green/yellow/red indicators.
+/// @}
+void test_complete_state(void);
+
+/// @defgroup test_error_state "test_error_state"
+/// @{
+/// @brief Error state shows connection error message.
+/// @}
+void test_error_state(void);
+
+/// @defgroup test_i18n_usage "test_i18n_usage"
+/// @{
+/// @brief Component uses i18n _() for all user-facing strings with fallbacks.
+/// @}
+void test_i18n_usage(void);
+
+/// @defgroup test_abort_controller "test_abort_controller"
+/// @{
+/// @brief Component uses AbortController for request cancellation.
+/// @}
+void test_abort_controller(void);
+
+/// @defgroup BulkReplaceModalTests "BulkReplaceModalTests"
+/// @{
+/// @brief Contract-focused unit tests for BulkReplaceModal.svelte component.
+/// @}
+void BulkReplaceModalTests(void);
+
+/// @defgroup CorrectionCellTests "CorrectionCellTests"
+/// @{
+/// @brief Contract-focused unit tests for CorrectionCell.svelte component.
+/// @}
+void CorrectionCellTests(void);
+
+/// @defgroup test_component_file_exists_Function "test_component_file_exists:Function"
+/// @{
+/// @brief Verify component file exists and has required contracts
+/// @}
+void test_component_file_exists_Function(void);
+
+/// @defgroup TranslateApiTests_Class "TranslateApiTests:Class"
+/// @{
+/// @brief Unit tests for translate API preview functions.
+/// @}
+void TranslateApiTests_Class(void);
+
+/// @defgroup test_fetchPreview_Function "test_fetchPreview:Function"
+/// @{
+/// @brief Verify fetchPreview calls postApi with correct endpoint and payload.
+/// @}
+void test_fetchPreview_Function(void);
+
+/// @defgroup test_approveRow_Function "test_approveRow:Function"
+/// @{
+/// @brief Verify approveRow calls requestApi with correct action.
+/// @}
+void test_approveRow_Function(void);
+
+/// @defgroup test_editRow_Function "test_editRow:Function"
+/// @{
+/// @brief Verify editRow calls requestApi with edit action and translation.
+/// @}
+void test_editRow_Function(void);
+
+/// @defgroup test_rejectRow_Function "test_rejectRow:Function"
+/// @{
+/// @brief Verify rejectRow calls requestApi with reject action.
+/// @}
+void test_rejectRow_Function(void);
+
+/// @defgroup test_acceptPreview_Function "test_acceptPreview:Function"
+/// @{
+/// @brief Verify acceptPreview calls postApi with correct endpoint.
+/// @}
+void test_acceptPreview_Function(void);
+
+/// @defgroup test_fetchPreviewRecords_Function "test_fetchPreviewRecords:Function"
+/// @{
+/// @brief Verify fetchPreviewRecords calls fetchApi with correct endpoint.
+/// @}
+void test_fetchPreviewRecords_Function(void);
+
+/// @defgroup test_normalizeTranslateError_Function "test_normalizeTranslateError:Function"
+/// @{
+/// @brief Verify API errors are normalized consistently.
+/// @}
+void test_normalizeTranslateError_Function(void);
+
+/// @defgroup I18nModule "I18nModule"
+/// @{
+/// @brief Centralized internationalization management using Svelte stores with Russian and English locale support persisted in LocalStorage.
+/// @}
+void I18nModule(void);
+
+/// @defgroup i18n_Module "i18n:Module"
+/// @{
+/// @brief Centralized internationalization management using Svelte stores.
+/// @invariant Persistence is handled via LocalStorage.
+/// @}
+void i18n_Module(void);
+
+/// @defgroup locale_Store "locale:Store"
+/// @{
+/// @brief Holds the current active locale string.
+/// @}
+void locale_Store(void);
+
+/// @defgroup t_Store "t:Store"
+/// @{
+/// @brief Derived store providing the translation dictionary.
+/// @}
+void t_Store(void);
+
+/// @defgroup __Function "_:Function"
+/// @{
+/// @brief Get translation by key path.
+/// @param key - Translation key path (e.g., 'nav.dashboard')
+/// @return Translation string or key if not found
+/// @}
+void __Function(void);
+
+/// @defgroup frontend_src_lib_i18n_index_ts___ "frontend/src/lib/i18n/index.ts::_"
+/// @{
+/// @}
+void frontend_src_lib_i18n_index_ts___(void);
+
+/// @defgroup StoresModule "StoresModule"
+/// @{
+/// @brief Global Svelte writable stores for plugins, tasks, and UI page state management.
+/// @}
+void StoresModule(void);
+
+/// @defgroup stores_module_Module "stores_module:Module"
+/// @{
+/// @brief Global state management using Svelte stores.
+/// @}
+void stores_module_Module(void);
+
+/// @defgroup plugins_Data "plugins:Data"
+/// @{
+/// @brief Store for the list of available plugins.
+/// @}
+void plugins_Data(void);
+
+/// @defgroup tasks_Data "tasks:Data"
+/// @{
+/// @brief Store for the list of tasks.
+/// @}
+void tasks_Data(void);
+
+/// @defgroup selectedPlugin_Data "selectedPlugin:Data"
+/// @{
+/// @brief Store for the currently selected plugin.
+/// @}
+void selectedPlugin_Data(void);
+
+/// @defgroup selectedTask_Data "selectedTask:Data"
+/// @{
+/// @brief Store for the currently selected task.
+/// @}
+void selectedTask_Data(void);
+
+/// @defgroup currentPage_Data "currentPage:Data"
+/// @{
+/// @brief Store for the current page.
+/// @}
+void currentPage_Data(void);
+
+/// @defgroup taskLogs_Data "taskLogs:Data"
+/// @{
+/// @brief Store for the logs of the currently selected task.
+/// @}
+void taskLogs_Data(void);
+
+/// @defgroup fetchPlugins_Function "fetchPlugins:Function"
+/// @{
+/// @brief Fetches plugins from the API and updates the plugins store.
+/// @post plugins store is updated with data from the API.
+/// @pre None.
+/// @}
+void fetchPlugins_Function(void);
+
+/// @defgroup fetchTasks_Function "fetchTasks:Function"
+/// @{
+/// @brief Fetches tasks from the API and updates the tasks store.
+/// @post tasks store is updated with data from the API.
+/// @pre None.
+/// @}
+void fetchTasks_Function(void);
+
+/// @defgroup _EXT_frontend_AssistantChatTest_s "[EXT:frontend:AssistantChatTest]s"
+/// @{
+/// @brief Unit tests for assistant chat store validating open/close/toggle, conversation binding, session context, and seed message state transitions.
+/// @}
+void _EXT_frontend_AssistantChatTest_s(void);
+
+/// @defgroup _EXT_frontend_AssistantChatTest__Module "[EXT:frontend:AssistantChatTest]:Module"
+/// @{
+/// @brief Validate assistant chat store visibility and conversation binding transitions.
+/// @invariant Each test starts from default closed state.
+/// @}
+void _EXT_frontend_AssistantChatTest__Module(void);
+
+/// @defgroup assistantChatStore_tests_Function "assistantChatStore_tests:Function"
+/// @{
+/// @brief Group store unit scenarios for assistant panel behavior.
+/// @post Open/close/toggle/conversation transitions are validated.
+/// @pre Store can be reset to baseline state in beforeEach hook.
+/// @}
+void assistantChatStore_tests_Function(void);
+
+/// @defgroup MockEnvPublic "MockEnvPublic"
+/// @{
+/// @}
+void MockEnvPublic(void);
+
+/// @defgroup mock_env_public_Module "mock_env_public:Module"
+/// @{
+/// @brief Mock for $env/static/public SvelteKit module in vitest
+/// @}
+void mock_env_public_Module(void);
+
+/// @defgroup EnvironmentMock "EnvironmentMock"
+/// @{
+/// @brief Mock for $app/environment in vitest, supplying browser, dev, and building flags.
+/// @}
+void EnvironmentMock(void);
+
+/// @defgroup EnvironmentMock_Module "EnvironmentMock:Module"
+/// @{
+/// @brief Mock for $app/environment in tests
+/// @}
+void EnvironmentMock_Module(void);
+
+/// @defgroup NavigationMock "NavigationMock"
+/// @{
+/// @brief Mock for $app/navigation in vitest, supplying goto, push, replace, prefetch, and prefetchRoutes stubs.
+/// @}
+void NavigationMock(void);
+
+/// @defgroup NavigationMock_Module "NavigationMock:Module"
+/// @{
+/// @brief Mock for $app/navigation in tests
+/// @invariant Includes SvelteKit v1-only APIs (push, prefetchRoutes) as compatibility surface for legacy test consumers; keep until all imports migrate to SvelteKit v2-compatible mocks.
+/// @}
+void NavigationMock_Module(void);
+
+/// @defgroup StateMock "StateMock"
+/// @{
+/// @brief Mock for $app/state page data in vitest route/component tests, supplying default params, route, URL, status, and data.
+/// @}
+void StateMock(void);
+
+/// @defgroup state_mock_Module "state_mock:Module"
+/// @{
+/// @brief Mock for AppState in vitest route/component tests.
+/// @}
+void state_mock_Module(void);
+
+/// @defgroup StoresMock "StoresMock"
+/// @{
+/// @}
+void StoresMock(void);
+
+/// @defgroup StoresMock_Module "StoresMock:Module"
+/// @{
+/// @brief Mock for $app/stores in tests
+/// @invariant Mocks $app/stores which is a SvelteKit v1 module; SvelteKit v2 uses $app/state. Verify no active test files import this mock before removal.
+/// @}
+void StoresMock_Module(void);
+
+/// @defgroup SetupTestsModule "SetupTestsModule"
+/// @{
+/// @brief Global vitest test setup with mocks for SvelteKit modules ($app/environment, $app/stores, $app/navigation, localStorage).
+/// @}
+void SetupTestsModule(void);
+
+/// @defgroup setupTests_Module "setupTests:Module"
+/// @{
+/// @brief Global test setup with mocks for SvelteKit modules
+/// @}
+void setupTests_Module(void);
+
+/// @defgroup SidebarTest "SidebarTest"
+/// @{
+/// @brief Unit tests for sidebar store validating expansion toggles, active item selection, and mobile open/close transitions.
+/// @}
+void SidebarTest(void);
+
+/// @defgroup SidebarTest_Module "SidebarTest:Module"
+/// @{
+/// @brief Unit tests for sidebar store
+/// @invariant Sidebar store transitions must be deterministic across desktop/mobile toggles.
+/// @}
+void SidebarTest_Module(void);
+
+/// @defgroup test_sidebar_initial_state_Function "test_sidebar_initial_state:Function"
+/// @{
+/// @brief Verify initial sidebar store values when no persisted state is available.
+/// @post Default state is { isExpanded: true, activeCategory: 'dashboards', activeItem: '/dashboards', isMobileOpen: false }
+/// @pre No localStorage state
+/// @test Store initializes with default values
+/// @}
+void test_sidebar_initial_state_Function(void);
+
+/// @defgroup test_toggleSidebar_Function "test_toggleSidebar:Function"
+/// @{
+/// @brief Verify desktop sidebar expansion toggles deterministically.
+/// @post isExpanded is toggled from previous value
+/// @pre Store is initialized
+/// @test toggleSidebar toggles isExpanded state
+/// @}
+void test_toggleSidebar_Function(void);
+
+/// @defgroup test_setActiveItem_Function "test_setActiveItem:Function"
+/// @{
+/// @brief Verify active-category updates remain deterministic after item selection.
+/// @post activeCategory and activeItem are updated
+/// @pre Store is initialized
+/// @test setActiveItem updates activeCategory and activeItem
+/// @}
+void test_setActiveItem_Function(void);
+
+/// @defgroup test_mobile_functions_Function "test_mobile_functions:Function"
+/// @{
+/// @brief Verify mobile sidebar helpers update open-state transitions predictably.
+/// @post isMobileOpen is correctly updated
+/// @pre Store is initialized
+/// @test Mobile functions correctly update isMobileOpen
+/// @}
+void test_mobile_functions_Function(void);
+
+/// @defgroup TaskDrawerTests "TaskDrawerTests"
+/// @{
+/// @brief Unit tests for task drawer store validating open/close, preference-aware opening, resource task mapping, and status-driven cleanup.
+/// @}
+void TaskDrawerTests(void);
+
+/// @defgroup ActivityTestModule "ActivityTestModule"
+/// @{
+/// @brief Unit tests validating activity store derived count and recent task tracking behavior.
+/// @}
+void ActivityTestModule(void);
+
+/// @defgroup ActivityTest_Module "ActivityTest:Module"
+/// @{
+/// @brief Unit tests for activity store
+/// @}
+void ActivityTest_Module(void);
+
+/// @defgroup DatasetReviewSessionTests "DatasetReviewSessionTests"
+/// @{
+/// @brief Unit tests for dataset review session store: session set/reset, loading, error, dirty flag, and patch operations.
+/// @}
+void DatasetReviewSessionTests(void);
+
+/// @defgroup DatasetReviewSessionStoreTests_Module "DatasetReviewSessionStoreTests:Module"
+/// @{
+/// @brief Unit tests for dataset review session store.
+/// @}
+void DatasetReviewSessionStoreTests_Module(void);
+
+/// @defgroup SidebarTestModule "SidebarTestModule"
+/// @{
+/// @brief Unit tests for sidebar store validating initial state, toggle, navigation, mobile overlay, and localStorage persistence.
+/// @}
+void SidebarTestModule(void);
+
+/// @defgroup SidebarIntegrationTest_Module "SidebarIntegrationTest:Module"
+/// @{
+/// @brief Unit tests for sidebar store
+/// @}
+void SidebarIntegrationTest_Module(void);
+
+/// @defgroup TaskDrawerTestModule "TaskDrawerTestModule"
+/// @{
+/// @brief Unit tests for task drawer store validating open/close transitions, preference-aware opening, and resource-task mapping lifecycle.
+/// @}
+void TaskDrawerTestModule(void);
+
+/// @defgroup TaskDrawerTest_Module "TaskDrawerTest:Module"
+/// @{
+/// @brief Unit tests for task drawer store
+/// @invariant Store state transitions remain deterministic for open/close and task-status mapping.
+/// @}
+void TaskDrawerTest_Module(void);
+
+/// @defgroup ActivityStore "ActivityStore"
+/// @{
+/// @brief Derived store that counts active running tasks for navbar indicator badge.
+/// @}
+void ActivityStore(void);
+
+/// @defgroup activity_Store "activity:Store"
+/// @{
+/// @brief Track active task count for navbar indicator
+/// @}
+void activity_Store(void);
+
+/// @defgroup AssistantChatStore "AssistantChatStore"
+/// @{
+/// @brief Control assistant chat panel visibility, conversation binding, session context, and seeded prompts.
+/// @}
+void AssistantChatStore(void);
+
+/// @defgroup assistantChat_Store "assistantChat:Store"
+/// @{
+/// @brief Control assistant chat panel visibility and active conversation binding.
+/// @}
+void assistantChat_Store(void);
+
+/// @defgroup toggleAssistantChat_Function "toggleAssistantChat:Function"
+/// @{
+/// @brief Toggle assistant panel visibility.
+/// @post isOpen value inverted.
+/// @pre Store is initialized.
+/// @}
+void toggleAssistantChat_Function(void);
+
+/// @defgroup openAssistantChat_Function "openAssistantChat:Function"
+/// @{
+/// @brief Open assistant panel.
+/// @post isOpen = true.
+/// @pre Store is initialized.
+/// @}
+void openAssistantChat_Function(void);
+
+/// @defgroup openAssistantChatWithContext_Function "openAssistantChatWithContext:Function"
+/// @{
+/// @brief Open assistant panel with dataset review session context and optional seeded prompt/focus target.
+/// @post Assistant drawer opens with session binding and visible focus metadata.
+/// @pre Context payload may be partial.
+/// @}
+void openAssistantChatWithContext_Function(void);
+
+/// @defgroup closeAssistantChat_Function "closeAssistantChat:Function"
+/// @{
+/// @brief Close assistant panel.
+/// @post isOpen = false.
+/// @pre Store is initialized.
+/// @}
+void closeAssistantChat_Function(void);
+
+/// @defgroup setAssistantConversationId_Function "setAssistantConversationId:Function"
+/// @{
+/// @brief Bind current conversation id in UI state.
+/// @post store.conversationId updated.
+/// @pre conversationId is string-like identifier.
+/// @}
+void setAssistantConversationId_Function(void);
+
+/// @defgroup setAssistantDatasetReviewSessionId_Function "setAssistantDatasetReviewSessionId:Function"
+/// @{
+/// @brief Bind active dataset review session to assistant state.
+/// @post store.datasetReviewSessionId updated.
+/// @pre session identifier may be null when workspace context is cleared.
+/// @}
+void setAssistantDatasetReviewSessionId_Function(void);
+
+/// @defgroup setAssistantSeedMessage_Function "setAssistantSeedMessage:Function"
+/// @{
+/// @brief Stage a seeded assistant prompt for contextual send UX.
+/// @post store.seedMessage updated.
+/// @pre seedMessage can be empty to clear staged draft.
+/// @}
+void setAssistantSeedMessage_Function(void);
+
+/// @defgroup setAssistantFocusTarget_Function "setAssistantFocusTarget:Function"
+/// @{
+/// @brief Track the workspace entity currently referenced by assistant context.
+/// @post store.focusTarget updated.
+/// @pre focusTarget may be null to clear prior focus.
+/// @}
+void setAssistantFocusTarget_Function(void);
+
+/// @defgroup DatasetReviewSessionStore "DatasetReviewSessionStore"
+/// @{
+/// @brief Manage active dataset review session state including loading, local edits, error capture, and reset semantics.
+/// @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+/// @pre Consumers provide session-shaped payloads and initialize the store before reading derived session fields.
+/// @}
+void DatasetReviewSessionStore(void);
+
+/// @defgroup datasetReviewSession_Store "datasetReviewSession:Store"
+/// @{
+/// @brief Manage active dataset review session state, including loading, local edits, error capture, and reset semantics for the active review workspace.
+/// @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+/// @pre Consumers provide session-shaped payloads when setting or patching state and initialize the store before reading derived session fields.
+/// @}
+void datasetReviewSession_Store(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__setSession "frontend/src/lib/stores/datasetReviewSession.js::setSession"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__setSession(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__setLoading "frontend/src/lib/stores/datasetReviewSession.js::setLoading"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__setLoading(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__setError "frontend/src/lib/stores/datasetReviewSession.js::setError"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__setError(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__setDirty "frontend/src/lib/stores/datasetReviewSession.js::setDirty"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__setDirty(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__resetSession "frontend/src/lib/stores/datasetReviewSession.js::resetSession"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__resetSession(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__patchSession "frontend/src/lib/stores/datasetReviewSession.js::patchSession"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__patchSession(void);
+
+/// @defgroup frontend_src_lib_stores_datasetReviewSession_js__getSessionUiPhase "frontend/src/lib/stores/datasetReviewSession.js::getSessionUiPhase"
+/// @{
+/// @}
+void frontend_src_lib_stores_datasetReviewSession_js__getSessionUiPhase(void);
+
+/// @defgroup EnvironmentContextStore "EnvironmentContextStore"
+/// @{
+/// @brief Global selected environment context for navigation, safety cues, and environment-based filtering.
+/// @}
+void EnvironmentContextStore(void);
+
+/// @defgroup environmentContext_Store "environmentContext:Store"
+/// @{
+/// @brief Global selected environment context for navigation and safety cues.
+/// @}
+void environmentContext_Store(void);
+
+/// @defgroup HealthStore "HealthStore"
+/// @{
+/// @brief Manage dashboard health summary state and failing counts for UI badges.
+/// @}
+void HealthStore(void);
+
+/// @defgroup health_store_Store "health_store:Store"
+/// @{
+/// @brief Manage dashboard health summary state and failing counts for UI badges.
+/// @}
+void health_store_Store(void);
+
+/// @defgroup frontend_src_lib_stores_health_js__createHealthStore "frontend/src/lib/stores/health.js::createHealthStore"
+/// @{
+/// @}
+void frontend_src_lib_stores_health_js__createHealthStore(void);
+
+/// @defgroup frontend_src_lib_stores_health_js__refresh "frontend/src/lib/stores/health.js::refresh"
+/// @{
+/// @}
+void frontend_src_lib_stores_health_js__refresh(void);
+
+/// @defgroup MaintenanceStore "MaintenanceStore"
+/// @{
+/// @brief Svelte 5 (Runes) store for maintenance banner state. Auto-polls events every 30s via interval.
+/// @return {object} Maintenance store with runes state and methods.
+/// @}
+void MaintenanceStore(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__createMaintenanceStore "frontend/src/lib/stores/maintenance.svelte.js::createMaintenanceStore"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__createMaintenanceStore(void);
+
+/// @defgroup MaintenanceStore_state "MaintenanceStore.state"
+/// @{
+/// @}
+void MaintenanceStore_state(void);
+
+/// @defgroup MaintenanceStore_methods "MaintenanceStore.methods"
+/// @{
+/// @}
+void MaintenanceStore_methods(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__loadEvents "frontend/src/lib/stores/maintenance.svelte.js::loadEvents"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__loadEvents(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__loadDashboardBanners "frontend/src/lib/stores/maintenance.svelte.js::loadDashboardBanners"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__loadDashboardBanners(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__loadSettings "frontend/src/lib/stores/maintenance.svelte.js::loadSettings"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__loadSettings(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__endEvent "frontend/src/lib/stores/maintenance.svelte.js::endEvent"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__endEvent(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__endAllEvents "frontend/src/lib/stores/maintenance.svelte.js::endAllEvents"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__endAllEvents(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__updateSettings "frontend/src/lib/stores/maintenance.svelte.js::updateSettings"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__updateSettings(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__init "frontend/src/lib/stores/maintenance.svelte.js::init"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__init(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__startPolling "frontend/src/lib/stores/maintenance.svelte.js::startPolling"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__startPolling(void);
+
+/// @defgroup frontend_src_lib_stores_maintenance_svelte_js__stopPolling "frontend/src/lib/stores/maintenance.svelte.js::stopPolling"
+/// @{
+/// @}
+void frontend_src_lib_stores_maintenance_svelte_js__stopPolling(void);
+
+/// @defgroup SidebarStore "SidebarStore"
+/// @{
+/// @brief Manage sidebar visibility, expansion state, active navigation item, and mobile overlay.
+/// @}
+void SidebarStore(void);
+
+/// @defgroup sidebar_Store "sidebar:Store"
+/// @{
+/// @brief Manage sidebar visibility and navigation state
+/// @invariant isExpanded state is always synced with localStorage
+/// @}
+void sidebar_Store(void);
+
+/// @defgroup frontend_src_lib_stores_sidebar_js__toggleSidebar "frontend/src/lib/stores/sidebar.js::toggleSidebar"
+/// @{
+/// @}
+void frontend_src_lib_stores_sidebar_js__toggleSidebar(void);
+
+/// @defgroup frontend_src_lib_stores_sidebar_js__setActiveItem "frontend/src/lib/stores/sidebar.js::setActiveItem"
+/// @{
+/// @}
+void frontend_src_lib_stores_sidebar_js__setActiveItem(void);
+
+/// @defgroup frontend_src_lib_stores_sidebar_js__setMobileOpen "frontend/src/lib/stores/sidebar.js::setMobileOpen"
+/// @{
+/// @}
+void frontend_src_lib_stores_sidebar_js__setMobileOpen(void);
+
+/// @defgroup frontend_src_lib_stores_sidebar_js__closeMobile "frontend/src/lib/stores/sidebar.js::closeMobile"
+/// @{
+/// @}
+void frontend_src_lib_stores_sidebar_js__closeMobile(void);
+
+/// @defgroup frontend_src_lib_stores_sidebar_js__toggleMobileSidebar "frontend/src/lib/stores/sidebar.js::toggleMobileSidebar"
+/// @{
+/// @}
+void frontend_src_lib_stores_sidebar_js__toggleMobileSidebar(void);
+
+/// @defgroup TaskDrawerStore "TaskDrawerStore"
+/// @{
+/// @brief Manage Task Drawer visibility, active task binding, and resource-to-task mapping.
+/// @}
+void TaskDrawerStore(void);
+
+/// @defgroup taskDrawer_Store "taskDrawer:Store"
+/// @{
+/// @brief Manage Task Drawer visibility and resource-to-task mapping
+/// @}
+void taskDrawer_Store(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__openDrawerForTask "frontend/src/lib/stores/taskDrawer.js::openDrawerForTask"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__openDrawerForTask(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__setTaskDrawerAutoOpenPreference "frontend/src/lib/stores/taskDrawer.js::setTaskDrawerAutoOpenPreference"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__setTaskDrawerAutoOpenPreference(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__getTaskDrawerAutoOpenPreference "frontend/src/lib/stores/taskDrawer.js::getTaskDrawerAutoOpenPreference"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__getTaskDrawerAutoOpenPreference(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__openDrawerForTaskIfPreferred "frontend/src/lib/stores/taskDrawer.js::openDrawerForTaskIfPreferred"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__openDrawerForTaskIfPreferred(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__openDrawer "frontend/src/lib/stores/taskDrawer.js::openDrawer"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__openDrawer(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__closeDrawer "frontend/src/lib/stores/taskDrawer.js::closeDrawer"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__closeDrawer(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__updateResourceTask "frontend/src/lib/stores/taskDrawer.js::updateResourceTask"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__updateResourceTask(void);
+
+/// @defgroup frontend_src_lib_stores_taskDrawer_js__getTaskForResource "frontend/src/lib/stores/taskDrawer.js::getTaskForResource"
+/// @{
+/// @}
+void frontend_src_lib_stores_taskDrawer_js__getTaskForResource(void);
+
+/// @defgroup TranslationRunStore "TranslationRunStore"
+/// @{
+/// @brief Global store for active translation run progress — survives page navigation.
+/// @}
+void TranslationRunStore(void);
+
+/// @defgroup frontend_src_lib_stores_translationRun_js__clearOnCompleteCallback "frontend/src/lib/stores/translationRun.js::clearOnCompleteCallback"
+/// @{
+/// @}
+void frontend_src_lib_stores_translationRun_js__clearOnCompleteCallback(void);
+
+/// @defgroup frontend_src_lib_stores_translationRun_js__startTranslationRun "frontend/src/lib/stores/translationRun.js::startTranslationRun"
+/// @{
+/// @}
+void frontend_src_lib_stores_translationRun_js__startTranslationRun(void);
+
+/// @defgroup frontend_src_lib_stores_translationRun_js__stopTranslationRun "frontend/src/lib/stores/translationRun.js::stopTranslationRun"
+/// @{
+/// @}
+void frontend_src_lib_stores_translationRun_js__stopTranslationRun(void);
+
+/// @defgroup frontend_src_lib_stores_translationRun_js__resetTranslationRun "frontend/src/lib/stores/translationRun.js::resetTranslationRun"
+/// @{
+/// @}
+void frontend_src_lib_stores_translationRun_js__resetTranslationRun(void);
+
+/// @defgroup frontend_src_lib_stores_translationRun_js__updateTranslationRunState "frontend/src/lib/stores/translationRun.js::updateTranslationRunState"
+/// @{
+/// @}
+void frontend_src_lib_stores_translationRun_js__updateTranslationRunState(void);
+
+/// @defgroup frontend_src_lib_stores_translationRun_js__pollStatus "frontend/src/lib/stores/translationRun.js::pollStatus"
+/// @{
+/// @}
+void frontend_src_lib_stores_translationRun_js__pollStatus(void);
+
+/// @defgroup ToastsModule "ToastsModule"
+/// @{
+/// @brief Manages toast notifications using a Svelte writable store with deduplication and auto-removal.
+/// @}
+void ToastsModule(void);
+
+/// @defgroup toasts_module_Module "toasts_module:Module"
+/// @{
+/// @brief Manages toast notifications using a Svelte writable store.
+/// @}
+void toasts_module_Module(void);
+
+/// @defgroup toasts_Data "toasts:Data"
+/// @{
+/// @brief Writable store containing the list of active toasts.
+/// @}
+void toasts_Data(void);
+
+/// @defgroup addToast_Function "addToast:Function"
+/// @{
+/// @brief Adds a new toast message.
+/// @param duration (number) - Duration in ms before the toast is removed.
+/// @post New toast is added to the store and scheduled for removal.
+/// @pre message string is provided.
+/// @}
+void addToast_Function(void);
+
+/// @defgroup removeToast_Function "removeToast:Function"
+/// @{
+/// @brief Removes a toast message by ID.
+/// @param id (string) - The ID of the toast to remove.
+/// @post Toast is removed from the store.
+/// @pre id is provided.
+/// @}
+void removeToast_Function(void);
+
+/// @defgroup Button "Button"
+/// @{
+/// @brief Standardized button component with variants and loading states.
+/// @invariant Supports accessible labels and keyboard navigation.
+/// @}
+void Button(void);
+
+/// @defgroup Card "Card"
+/// @{
+/// @brief Standardized container with padding and elevation.
+/// @}
+void Card(void);
+
+/// @defgroup Icon "Icon"
+/// @{
+/// @brief Render the shared inline SVG icon set with consistent sizing and stroke props.
+/// @invariant Icon output remains aria-hidden because labels belong to the interactive parent.
+/// @}
+void Icon(void);
+
+/// @defgroup Input "Input"
+/// @{
+/// @brief Standardized text input component with label and error handling.
+/// @invariant Consistent spacing and focus states.
+/// @}
+void Input(void);
+
+/// @defgroup LanguageSwitcher "LanguageSwitcher"
+/// @{
+/// @brief Dropdown component to switch between supported languages.
+/// @}
+void LanguageSwitcher(void);
+
+/// @defgroup PageHeader "PageHeader"
+/// @{
+/// @brief Standardized page header with title and action area.
+/// @}
+void PageHeader(void);
+
+/// @defgroup Select "Select"
+/// @{
+/// @brief Standardized dropdown selection component.
+/// @}
+void Select(void);
+
+/// @defgroup ui_Module "ui:Module"
+/// @{
+/// @brief Central export point for standardized UI components.
+/// @invariant All components exported here must follow Semantic Protocol.
+/// @}
+void ui_Module(void);
+
+/// @defgroup UtilsModule "UtilsModule"
+/// @{
+/// @}
+void UtilsModule(void);
+
+/// @defgroup Utils_Module "Utils:Module"
+/// @{
+/// @brief General utility functions (class merging)
+/// @}
+void Utils_Module(void);
+
+/// @defgroup frontend_src_lib_utils_js__cn "frontend/src/lib/utils.js::cn"
+/// @{
+/// @}
+void frontend_src_lib_utils_js__cn(void);
+
+/// @defgroup DebounceModule "DebounceModule"
+/// @{
+/// @}
+void DebounceModule(void);
+
+/// @defgroup Debounce_Module "Debounce:Module"
+/// @{
+/// @brief Debounce utility for limiting function execution rate
+/// @}
+void Debounce_Module(void);
+
+/// @defgroup frontend_src_lib_utils_debounce_js__debounce "frontend/src/lib/utils/debounce.js::debounce"
+/// @{
+/// @}
+void frontend_src_lib_utils_debounce_js__debounce(void);
+
+/// @defgroup onMount_Function "onMount:Function"
+/// @{
+/// @brief Fetch plugins when the component mounts.
+/// @post plugins store is populated with available tools.
+/// @pre Component is mounting.
+/// @}
+void onMount_Function(void);
+
+/// @defgroup selectPlugin_Function "selectPlugin:Function"
+/// @{
+/// @brief Selects a plugin to display its form.
+/// @param {Object} plugin - The plugin object to select.
+/// @post selectedPlugin store is updated.
+/// @pre plugin object is provided.
+/// @}
+void selectPlugin_Function(void);
+
+/// @defgroup loadSettings_Function "loadSettings:Function"
+/// @{
+/// @brief Loads settings from the backend.
+/// @post settings object is populated with backend data.
+/// @pre Component mounted or refresh requested.
+/// @}
+void loadSettings_Function(void);
+
+/// @defgroup handleSaveGlobal_Function "handleSaveGlobal:Function"
+/// @{
+/// @brief Saves global settings to the backend.
+/// @post Backend global settings are updated.
+/// @pre settings.settings contains valid configuration.
+/// @}
+void handleSaveGlobal_Function(void);
+
+/// @defgroup handleAddOrUpdateEnv_Function "handleAddOrUpdateEnv:Function"
+/// @{
+/// @brief Adds or updates an environment.
+/// @post Environment list is updated on backend and reloaded locally.
+/// @pre newEnv contains valid environment details.
+/// @}
+void handleAddOrUpdateEnv_Function(void);
+
+/// @defgroup handleDeleteEnv_Function "handleDeleteEnv:Function"
+/// @{
+/// @brief Deletes an environment.
+/// @param {string} id - The ID of the environment to delete.
+/// @post Environment is removed from backend and list is reloaded.
+/// @pre id of environment to delete is provided.
+/// @}
+void handleDeleteEnv_Function(void);
+
+/// @defgroup handleTestEnv_Function "handleTestEnv:Function"
+/// @{
+/// @brief Tests the connection to an environment.
+/// @param {string} id - The ID of the environment to test.
+/// @post Connection test result is displayed via toast.
+/// @pre Environment ID is valid.
+/// @}
+void handleTestEnv_Function(void);
+
+/// @defgroup editEnv_Function "editEnv:Function"
+/// @{
+/// @brief Sets the form to edit an existing environment.
+/// @param {Object} env - The environment object to edit.
+/// @post newEnv is populated with env data and editingEnvId is set.
+/// @pre env object is provided.
+/// @}
+void editEnv_Function(void);
+
+/// @defgroup resetEnvForm_Function "resetEnvForm:Function"
+/// @{
+/// @brief Resets the environment form.
+/// @post newEnv is reset to initial state and editingEnvId is cleared.
+/// @pre None.
+/// @}
+void resetEnvForm_Function(void);
+
+/// @defgroup ErrorPage "ErrorPage"
+/// @{
+/// @brief Global error page displaying HTTP status code and error message with navigation back to dashboard.
+/// @}
+void ErrorPage(void);
+
+/// @defgroup RootLayout "RootLayout"
+/// @{
+/// @brief Root layout component providing global UI structure: Sidebar, TopNavbar, Footer, TaskDrawer, Toasts.
+/// @invariant Sidebar width adapts (ml-60 vs ml-16) based on sidebar expanded state.
+/// @}
+void RootLayout(void);
+
+/// @defgroup RootLayoutConfig_Module "RootLayoutConfig:Module"
+/// @{
+/// @brief Root layout configuration (SPA mode)
+/// @}
+void RootLayoutConfig_Module(void);
+
+/// @defgroup HomePage "HomePage"
+/// @{
+/// @brief Redirect to preferred start page (dashboards/datasets/reports) based on profile settings, with safe fallback.
+/// @invariant Redirect target resolves to one of /dashboards, /datasets, /reports.
+/// @}
+void HomePage(void);
+
+/// @defgroup load_Function "load:Function"
+/// @{
+/// @brief Loads initial plugin data for the dashboard.
+/// @post Returns an object with plugins or an error message.
+/// @pre None.
+/// @}
+void load_Function(void);
+
+/// @defgroup frontend_src_routes__page_ts__load "frontend/src/routes/+page.ts::load"
+/// @{
+/// @}
+void frontend_src_routes__page_ts__load(void);
+
+/// @defgroup openCreateModal_Function "openCreateModal:Function"
+/// @{
+/// @brief Initializes state for creating a new role.
+/// @post showModal is true, roleForm is reset.
+/// @pre None.
+/// @}
+void openCreateModal_Function(void);
+
+/// @defgroup openEditModal_Function "openEditModal:Function"
+/// @{
+/// @brief Initializes state for editing an existing role.
+/// @post showModal is true, roleForm is populated.
+/// @pre role object is provided.
+/// @}
+void openEditModal_Function(void);
+
+/// @defgroup handleSaveRole_Function "handleSaveRole:Function"
+/// @{
+/// @brief Submits role data (create or update).
+/// @post Role is saved, modal closed, data reloaded.
+/// @pre roleForm contains valid data.
+/// @}
+void handleSaveRole_Function(void);
+
+/// @defgroup handleDeleteRole_Function "handleDeleteRole:Function"
+/// @{
+/// @brief Deletes a role after confirmation.
+/// @post Role is deleted if confirmed, data reloaded.
+/// @pre role object is provided.
+/// @}
+void handleDeleteRole_Function(void);
+
+/// @defgroup handleCreateMapping_Function "handleCreateMapping:Function"
+/// @{
+/// @brief Submits a new AD Group to Role mapping to the backend.
+/// @post A new mapping is created in the database and the table is refreshed.
+/// @pre 'newMapping' object contains valid 'ad_group' and 'role_id'.
+/// @return {Promise}
+/// @}
+void handleCreateMapping_Function(void);
+
+/// @defgroup loadLoggingConfig_Function "loadLoggingConfig:Function"
+/// @{
+/// @brief Fetches current logging configuration from the backend.
+/// @post loggingConfig variable is updated with backend data.
+/// @pre Component is mounted and user has active session.
+/// @return {Promise}
+/// @}
+void loadLoggingConfig_Function(void);
+
+/// @defgroup saveLoggingConfig_Function "saveLoggingConfig:Function"
+/// @{
+/// @brief Saves logging configuration to the backend.
+/// @post Configuration is saved and feedback is shown.
+/// @pre loggingConfig contains valid values.
+/// @return {Promise}
+/// @}
+void saveLoggingConfig_Function(void);
+
+/// @defgroup LLMReportPage "LLMReportPage"
+/// @{
+/// @brief Admin settings page for LLM provider configuration.
+/// @}
+void LLMReportPage(void);
+
+/// @defgroup handleSaveUser_Function "handleSaveUser:Function"
+/// @{
+/// @brief Submits user data to the backend (create or update).
+/// @post User created or updated, modal closed, data reloaded.
+/// @pre userForm must be valid.
+/// @}
+void handleSaveUser_Function(void);
+
+/// @defgroup handleDeleteUser_Function "handleDeleteUser:Function"
+/// @{
+/// @brief Deletes a user after confirmation.
+/// @param {Object} user - The user to delete.
+/// @post User deleted if confirmed, data reloaded.
+/// @pre user object must be valid.
+/// @}
+void handleDeleteUser_Function(void);
+
+/// @defgroup DashboardHub_normalizeTaskStatus_Function "DashboardHub.normalizeTaskStatus:Function"
+/// @{
+/// @brief Normalize raw task status to stable lowercase token for UI.
+/// @post returns null or normalized token without enum namespace.
+/// @pre status can be enum-like string or null.
+/// @}
+void DashboardHub_normalizeTaskStatus_Function(void);
+
+/// @defgroup DashboardHub_normalizeValidationStatus_Function "DashboardHub.normalizeValidationStatus:Function"
+/// @{
+/// @brief Normalize validation status to pass/fail/warn/unknown.
+/// @post returns one of pass|fail|warn|unknown.
+/// @pre status can be any scalar.
+/// @}
+void DashboardHub_normalizeValidationStatus_Function(void);
+
+/// @defgroup DashboardHub_getValidationBadgeClass_Function "DashboardHub.getValidationBadgeClass:Function"
+/// @{
+/// @brief Map validation level to badge class tuple.
+/// @post returns deterministic tailwind class string.
+/// @pre level in pass|fail|warn|unknown.
+/// @}
+void DashboardHub_getValidationBadgeClass_Function(void);
+
+/// @defgroup DashboardHub_getValidationLabel_Function "DashboardHub.getValidationLabel:Function"
+/// @{
+/// @brief Map normalized validation level to compact UI label.
+/// @post returns uppercase status label.
+/// @pre level in pass|fail|warn|unknown.
+/// @}
+void DashboardHub_getValidationLabel_Function(void);
+
+/// @defgroup DashboardHub_normalizeOwners_Function "DashboardHub.normalizeOwners:Function"
+/// @{
+/// @brief Normalize owners payload to unique non-empty display labels.
+/// @post Returns owner labels preserving source order.
+/// @pre owners can be null, list of strings, or list of user objects.
+/// @}
+void DashboardHub_normalizeOwners_Function(void);
+
+/// @defgroup DashboardHub_loadDashboards_Function "DashboardHub.loadDashboards:Function"
+/// @{
+/// @brief Load full dashboard dataset for current environment and hydrate grid projection.
+/// @post allDashboards, dashboards, pagination and selection state are synchronized.
+/// @pre selectedEnv is not null.
+/// @}
+void DashboardHub_loadDashboards_Function(void);
+
+/// @defgroup DashboardHub_handleTemporaryShowAll_Function "DashboardHub.handleTemporaryShowAll:Function"
+/// @{
+/// @brief Temporarily disable profile-default dashboard filter for current page context.
+/// @post Next request is sent with override_show_all=true.
+/// @pre Dashboards list is loaded in dashboards_main context.
+/// @}
+void DashboardHub_handleTemporaryShowAll_Function(void);
+
+/// @defgroup DashboardHub_handleRestoreProfileFilter_Function "DashboardHub.handleRestoreProfileFilter:Function"
+/// @{
+/// @brief Re-enable persisted profile-default filtering after temporary override.
+/// @post Next request is sent with override_show_all=false.
+/// @pre Current page is in override mode.
+/// @}
+void DashboardHub_handleRestoreProfileFilter_Function(void);
+
+/// @defgroup DashboardHub_formatDate_Function "DashboardHub.formatDate:Function"
+/// @{
+/// @brief Convert ISO timestamp to locale date string.
+/// @post returns formatted date or "-".
+/// @pre value may be null or invalid date string.
+/// @}
+void DashboardHub_formatDate_Function(void);
+
+/// @defgroup DashboardHub_getGitSummaryLabel_Function "DashboardHub.getGitSummaryLabel:Function"
+/// @{
+/// @brief Compute stable text label for git state column.
+/// @post returns localized summary string.
+/// @pre dashboard has git projection fields.
+/// @}
+void DashboardHub_getGitSummaryLabel_Function(void);
+
+/// @defgroup DashboardHub_getLlmSummaryLabel_Function "DashboardHub.getLlmSummaryLabel:Function"
+/// @{
+/// @brief Compute normalized LLM validation summary label.
+/// @post returns UNKNOWN fallback for missing status.
+/// @pre dashboard may have null lastTask.
+/// @}
+void DashboardHub_getLlmSummaryLabel_Function(void);
+
+/// @defgroup DashboardHub_getColumnCellValue_Function "DashboardHub.getColumnCellValue:Function"
+/// @{
+/// @brief Resolve comparable/filterable display value for any grid column.
+/// @post returns non-empty scalar display value.
+/// @pre column belongs to filterable column set.
+/// @}
+void DashboardHub_getColumnCellValue_Function(void);
+
+/// @defgroup DashboardHub_getFilterOptions_Function "DashboardHub.getFilterOptions:Function"
+/// @{
+/// @brief Build unique sorted value list for a column filter dropdown.
+/// @post returns de-duplicated sorted options.
+/// @pre allDashboards is hydrated.
+/// @}
+void DashboardHub_getFilterOptions_Function(void);
+
+/// @defgroup DashboardHub_getVisibleFilterOptions_Function "DashboardHub.getVisibleFilterOptions:Function"
+/// @{
+/// @brief Apply in-dropdown search over full filter options.
+/// @post returns subset for current filter popover list.
+/// @pre columnFilterSearch contains search token for column.
+/// @}
+void DashboardHub_getVisibleFilterOptions_Function(void);
+
+/// @defgroup DashboardHub_toggleFilterDropdown_Function "DashboardHub.toggleFilterDropdown:Function"
+/// @{
+/// @brief Toggle active column filter popover.
+/// @post openFilterColumn updated.
+/// @pre column is valid filter key.
+/// @}
+void DashboardHub_toggleFilterDropdown_Function(void);
+
+/// @defgroup DashboardHub_toggleFilterValue_Function "DashboardHub.toggleFilterValue:Function"
+/// @{
+/// @brief Add/remove specific filter value and reapply projection.
+/// @post columnFilters updated and grid reprojected from page 1.
+/// @pre value comes from option list of the same column.
+/// @}
+void DashboardHub_toggleFilterValue_Function(void);
+
+/// @defgroup DashboardHub_clearColumnFilter_Function "DashboardHub.clearColumnFilter:Function"
+/// @{
+/// @brief Reset selected values for one column.
+/// @post filter cleared and projection refreshed.
+/// @pre column is valid filter key.
+/// @}
+void DashboardHub_clearColumnFilter_Function(void);
+
+/// @defgroup DashboardHub_selectAllColumnFilterValues_Function "DashboardHub.selectAllColumnFilterValues:Function"
+/// @{
+/// @brief Select all currently visible values in filter popover.
+/// @post column filter equals current visible option set.
+/// @pre visible options computed for current search token.
+/// @}
+void DashboardHub_selectAllColumnFilterValues_Function(void);
+
+/// @defgroup DashboardHub_updateColumnFilterSearch_Function "DashboardHub.updateColumnFilterSearch:Function"
+/// @{
+/// @brief Update local search token for one filter popover.
+/// @post columnFilterSearch updated immutably.
+/// @pre value is text from input.
+/// @}
+void DashboardHub_updateColumnFilterSearch_Function(void);
+
+/// @defgroup DashboardHub_hasColumnFilter_Function "DashboardHub.hasColumnFilter:Function"
+/// @{
+/// @brief Determine if column has active selected values.
+/// @post returns boolean activation marker.
+/// @pre column is valid filter key.
+/// @}
+void DashboardHub_hasColumnFilter_Function(void);
+
+/// @defgroup DashboardHub_doesDashboardPassColumnFilters_Function "DashboardHub.doesDashboardPassColumnFilters:Function"
+/// @{
+/// @brief Evaluate dashboard row against all active column filters.
+/// @post returns true only when row matches every active filter.
+/// @pre dashboard contains projected values for each filterable column.
+/// @}
+void DashboardHub_doesDashboardPassColumnFilters_Function(void);
+
+/// @defgroup DashboardHub_getSortValue_Function "DashboardHub.getSortValue:Function"
+/// @{
+/// @brief Compute stable comparable sort key for chosen column.
+/// @post returns string/number key suitable for deterministic comparison.
+/// @pre column belongs to sortable set.
+/// @}
+void DashboardHub_getSortValue_Function(void);
+
+/// @defgroup DashboardHub_handleSort_Function "DashboardHub.handleSort:Function"
+/// @{
+/// @brief Toggle or switch sort order and reapply grid projection.
+/// @post sortColumn/sortDirection updated and page reset to 1.
+/// @pre column belongs to sortable set.
+/// @}
+void DashboardHub_handleSort_Function(void);
+
+/// @defgroup DashboardHub_getSortIndicator_Function "DashboardHub.getSortIndicator:Function"
+/// @{
+/// @brief Return visual indicator for active/inactive sort header.
+/// @post returns one of ↕ | ↑ | ↓.
+/// @pre column belongs to sortable set.
+/// @}
+void DashboardHub_getSortIndicator_Function(void);
+
+/// @defgroup DashboardHub_applyGridTransforms_Function "DashboardHub.applyGridTransforms:Function"
+/// @{
+/// @brief Apply search + column filters + sort + pagination to grid data.
+/// @post filteredDashboards/dashboards/total/totalPages are synchronized.
+/// @pre allDashboards is current source collection.
+/// @}
+void DashboardHub_applyGridTransforms_Function(void);
+
+/// @defgroup DashboardHeader "DashboardHeader"
+/// @{
+/// @brief Top title area, breadcrumb, Git branch selector, and action buttons for dashboard detail.
+/// @}
+void DashboardHeader(void);
+
+/// @defgroup DashboardProfileOverrideIntegrationTest_Module "DashboardProfileOverrideIntegrationTest:Module"
+/// @{
+/// @brief Verifies temporary show-all override and restore-on-return behavior for profile-default dashboard filtering.
+/// @}
+void DashboardProfileOverrideIntegrationTest_Module(void);
+
+/// @defgroup HealthCenterPage "HealthCenterPage"
+/// @{
+/// @brief Main page for the Dashboard Health Center showing health matrix table with environment filtering.
+/// @}
+void HealthCenterPage(void);
+
+/// @defgroup loadData_Function "loadData:Function"
+/// @{
+/// @brief Load health summary rows and environment options for the current filter.
+/// @post `healthData` and `environments` reflect latest backend response.
+/// @pre Page is mounted or environment selection changed.
+/// @}
+void loadData_Function(void);
+
+/// @defgroup handleEnvChange_Function "handleEnvChange:Function"
+/// @{
+/// @brief Apply environment filter and trigger health summary reload.
+/// @post selectedEnvId is updated and new data load starts.
+/// @pre DOM change event carries target value.
+/// @}
+void handleEnvChange_Function(void);
+
+/// @defgroup handleDeleteReport_Function "handleDeleteReport:Function"
+/// @{
+/// @brief Delete one health report row with confirmation and optimistic button lock.
+/// @post Row is removed from backend and page data is reloaded on success.
+/// @pre item contains `record_id` from health summary payload.
+/// @}
+void handleDeleteReport_Function(void);
+
+/// @defgroup HealthPageIntegrationTest_Module "HealthPageIntegrationTest:Module"
+/// @{
+/// @brief Lock dashboard health page contract for slug navigation and report deletion.
+/// @}
+void HealthPageIntegrationTest_Module(void);
+
+/// @defgroup DatasetHub "DatasetHub"
+/// @{
+/// @}
+void DatasetHub(void);
+
+/// @defgroup ColumnsTable "ColumnsTable"
+/// @{
+/// @brief Table of dataset columns with type chips, description, and inline-edit capability.
+/// @}
+void ColumnsTable(void);
+
+/// @defgroup DatasetList "DatasetList"
+/// @{
+/// @brief Renders paginated dataset cards with mapping progress bars, checkboxes, and quick actions.
+/// @}
+void DatasetList(void);
+
+/// @defgroup DatasetPreview "DatasetPreview"
+/// @{
+/// @brief Right panel showing dataset detail: header info, columns table, metrics table, linked dashboards. Presentational.
+/// @}
+void DatasetPreview(void);
+
+/// @defgroup MetricsTable "MetricsTable"
+/// @{
+/// @brief Table of dataset metrics with expression, description, and inline-edit capability.
+/// @}
+void MetricsTable(void);
+
+/// @defgroup StatsBar "StatsBar"
+/// @{
+/// @brief Compact filter pills showing aggregate counts (All, Without mapping, Mapped, Linked).
+/// @}
+void StatsBar(void);
+
+/// @defgroup DatasetReviewWorkspaceEntry "DatasetReviewWorkspaceEntry"
+/// @{
+/// @brief Entry route for Dataset Review Workspace — start a new resumable review session or navigate to existing sessions.
+/// @}
+void DatasetReviewWorkspaceEntry(void);
+
+/// @defgroup ReviewWorkspaceHeader "ReviewWorkspaceHeader"
+/// @{
+/// @brief Header section for the dataset review workspace with title, description, and status badges.
+/// @}
+void ReviewWorkspaceHeader(void);
+
+/// @defgroup ReviewWorkspaceLeftSidebar "ReviewWorkspaceLeftSidebar"
+/// @{
+/// @brief Left sidebar for dataset review workspace: source info, import status, session summary, clarification focus, primary actions.
+/// @}
+void ReviewWorkspaceLeftSidebar(void);
+
+/// @defgroup ReviewWorkspaceRightRail "ReviewWorkspaceRightRail"
+/// @{
+/// @brief Right rail for dataset review workspace: next action, blockers, health counts, exports, SQL preview, launch panel.
+/// @}
+void ReviewWorkspaceRightRail(void);
+
+/// @defgroup DatasetReviewWorkspace "DatasetReviewWorkspace"
+/// @{
+/// @brief Main dataset review workspace — thin shell delegating to extracted components.
+/// @deprecated N/A — active workspace page.
+/// @}
+void DatasetReviewWorkspace(void);
+
+/// @defgroup DatasetReviewEntryUxTests "DatasetReviewEntryUxTests"
+/// @{
+/// @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+/// @}
+void DatasetReviewEntryUxTests(void);
+
+/// @defgroup DatasetReviewEntryUxPageTests "DatasetReviewEntryUxPageTests"
+/// @{
+/// @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+/// @}
+void DatasetReviewEntryUxPageTests(void);
+
+/// @defgroup ReviewWorkspaceHelpers "ReviewWorkspaceHelpers"
+/// @{
+/// @brief Shared helper functions for the dataset review workspace.
+/// @}
+void ReviewWorkspaceHelpers(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__buildImportMilestones "frontend/src/routes/datasets/review/review-workspace-helpers.js::buildImportMilestones"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__buildImportMilestones(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__buildWorkspaceLaunchBlockers "frontend/src/routes/datasets/review/review-workspace-helpers.js::buildWorkspaceLaunchBlockers"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__buildWorkspaceLaunchBlockers(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__buildAssistantSeedPrompt "frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantSeedPrompt"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__buildAssistantSeedPrompt(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__buildAssistantContextPrompt "frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantContextPrompt"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__buildAssistantContextPrompt(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__getWorkspaceStateLabel "frontend/src/routes/datasets/review/review-workspace-helpers.js::getWorkspaceStateLabel"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__getWorkspaceStateLabel(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__getRecommendedActionLabel "frontend/src/routes/datasets/review/review-workspace-helpers.js::getRecommendedActionLabel"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__getRecommendedActionLabel(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__getPrimaryActionCtaLabel "frontend/src/routes/datasets/review/review-workspace-helpers.js::getPrimaryActionCtaLabel"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__getPrimaryActionCtaLabel(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__mergeCollectionItem "frontend/src/routes/datasets/review/review-workspace-helpers.js::mergeCollectionItem"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__mergeCollectionItem(void);
+
+/// @defgroup frontend_src_routes_datasets_review_review_workspace_helpers_js__stringifyValue "frontend/src/routes/datasets/review/review-workspace-helpers.js::stringifyValue"
+/// @{
+/// @}
+void frontend_src_routes_datasets_review_review_workspace_helpers_js__stringifyValue(void);
+
+/// @defgroup UseReviewSession "UseReviewSession"
+/// @{
+/// @brief Composable for dataset review session state management — load, update, export, and clarify.
+/// @}
+void UseReviewSession(void);
+
+/// @defgroup GitDashboardPage "GitDashboardPage"
+/// @{
+/// @brief Git integration page for selecting environments and managing dashboard repositories.
+/// @}
+void GitDashboardPage(void);
+
+/// @defgroup LoginPage "LoginPage"
+/// @{
+/// @brief Provides the user interface for local (username/password) and ADFS SSO authentication.
+/// @invariant Shows both local login form and ADFS SSO button.
+/// @}
+void LoginPage(void);
+
+/// @defgroup MaintenanceBannerPage "MaintenanceBannerPage"
+/// @{
+/// @brief Maintenance Banners management page. Composes SettingsPanel and EventsTable from store.
+/// @}
+void MaintenanceBannerPage(void);
+
+/// @defgroup ReactiveDashboardFetch_Block "ReactiveDashboardFetch:Block"
+/// @{
+/// @brief Automatically fetch dashboards when the source environment is changed.
+/// @post fetchDashboards is called with the new sourceEnvId.
+/// @pre sourceEnvId is not empty.
+/// @}
+void ReactiveDashboardFetch_Block(void);
+
+/// @defgroup handleMappingUpdate_Function "handleMappingUpdate:Function"
+/// @{
+/// @brief Saves a mapping to the backend.
+/// @post Mapping is saved and local mappings list is updated.
+/// @pre event.detail contains sourceUuid and targetUuid.
+/// @}
+void handleMappingUpdate_Function(void);
+
+/// @defgroup handleViewLogs_Function "handleViewLogs:Function"
+/// @{
+/// @brief Opens the log viewer for a specific task.
+/// @post logViewer state updated and showLogViewer set to true.
+/// @pre event.detail contains task object.
+/// @}
+void handleViewLogs_Function(void);
+
+/// @defgroup handlePasswordPrompt_Function "handlePasswordPrompt:Function"
+/// @{
+/// @brief Reactive logic to show password prompt when a task is awaiting input.
+/// @post showPasswordPrompt set to true with request data.
+/// @pre selectedTask status is AWAITING_INPUT.
+/// @}
+void handlePasswordPrompt_Function(void);
+
+/// @defgroup ReactivePasswordPrompt_Block "ReactivePasswordPrompt:Block"
+/// @{
+/// @brief Monitor selected task for input requests and trigger password prompt.
+/// @post showPasswordPrompt is set to true if input_request is database_password.
+/// @pre $selectedTask is not null and status is AWAITING_INPUT.
+/// @}
+void ReactivePasswordPrompt_Block(void);
+
+/// @defgroup handleResumeMigration_Function "handleResumeMigration:Function"
+/// @{
+/// @brief Resumes a migration task with provided passwords.
+/// @post resumeTask is called and showPasswordPrompt is hidden on success.
+/// @pre event.detail contains passwords.
+/// @}
+void handleResumeMigration_Function(void);
+
+/// @defgroup startMigration_Function "startMigration:Function"
+/// @{
+/// @brief Initiates the migration process by sending the selection to the backend.
+/// @post A migration task is created and selectedTask store is updated.
+/// @pre sourceEnvId and targetEnvId are set and different; at least one dashboard is selected.
+/// @}
+void startMigration_Function(void);
+
+/// @defgroup startDryRun_Function "startDryRun:Function"
+/// @{
+/// @brief Performs a dry-run migration to identify potential risks and changes.
+/// @post dryRunResult is populated with the pre-flight analysis.
+/// @pre source/target environments and selected dashboards are valid.
+/// @}
+void startDryRun_Function(void);
+
+/// @defgroup MigrationMappingsPage "MigrationMappingsPage"
+/// @{
+/// @brief Render and orchestrate mapping management UI for source/target environments with backend persistence.
+/// @invariant Persisted mapping state in backend remains the source of truth for rendered mapping pairs.
+/// @post UI exposes deterministic Idle/Loading/Error/Success states for environment loading, database fetch, and mapping save.
+/// @pre Translation store and API client are available; route is mounted in authenticated UI shell.
+/// @}
+void MigrationMappingsPage(void);
+
+/// @defgroup MappingsPageScript_Block "MappingsPageScript:Block"
+/// @{
+/// @brief Define imports, state, and handlers that drive migration mappings page FSM.
+/// @}
+void MappingsPageScript_Block(void);
+
+/// @defgroup Imports_Block "Imports:Block"
+/// @{
+/// @}
+void Imports_Block(void);
+
+/// @defgroup UiState_Store "UiState:Store"
+/// @{
+/// @brief Maintain local page state for environments, fetched databases, mappings, suggestions, and UX messages.
+/// @}
+void UiState_Store(void);
+
+/// @defgroup belief_scope_Function "belief_scope:Function"
+/// @{
+/// @brief Frontend semantic scope wrapper for CRITICAL trace boundaries without changing business behavior.
+/// @post Executes run exactly once and returns/rejects with the same outcome.
+/// @pre scopeId is non-empty and run is callable.
+/// @}
+void belief_scope_Function(void);
+
+/// @defgroup fetchDatabases_Function "fetchDatabases:Function"
+/// @{
+/// @brief Fetch both environment database catalogs, existing mappings, and suggested matches.
+/// @post fetchingDbs=false and sourceDatabases/targetDatabases/mappings/suggestions updated or error set.
+/// @pre sourceEnvId and targetEnvId are both selected and non-empty.
+/// @}
+void fetchDatabases_Function(void);
+
+/// @defgroup handleUpdate_Function "handleUpdate:Function"
+/// @{
+/// @brief Persist a selected mapping pair and reconcile local mapping list by source database UUID.
+/// @post mapping persisted; local mappings replaced for same source UUID; success or error feedback shown.
+/// @pre event.detail includes sourceUuid/targetUuid and matching source/target database records exist.
+/// @}
+void handleUpdate_Function(void);
+
+/// @defgroup MappingsPageTemplate "MappingsPageTemplate"
+/// @{
+/// @brief Mapping page template with environment selectors, database mapping table, and action buttons.
+/// @}
+void MappingsPageTemplate(void);
+
+/// @defgroup ProfilePage "ProfilePage"
+/// @{
+/// @brief User profile page for viewing and editing personal preferences and settings.
+/// @}
+void ProfilePage(void);
+
+/// @defgroup ProfileFixtures_Module "ProfileFixtures:Module"
+/// @{
+/// @brief Shared deterministic fixture inputs for profile page integration tests.
+/// @invariant lookupFailedManualFallback.warning is a hardcoded English string; drift risk if i18n key profile.lookup_error changes without updating this fixture.
+/// @}
+void ProfileFixtures_Module(void);
+
+/// @defgroup ProfilePreferencesIntegrationTest "ProfilePreferencesIntegrationTest"
+/// @{
+/// @brief Verifies profile page loads preferences and saves them.
+/// @}
+void ProfilePreferencesIntegrationTest(void);
+
+/// @defgroup ProfileSettingsStateIntegrationTest "ProfileSettingsStateIntegrationTest"
+/// @{
+/// @brief Verifies profile loads preferences, allows changes, and saves correctly.
+/// @}
+void ProfileSettingsStateIntegrationTest(void);
+
+/// @defgroup UnifiedReportsPage "UnifiedReportsPage"
+/// @{
+/// @brief Unified reports page with task-type and status filtering, list selection, detail panel, and resilient UX states for mixed task types.
+/// @}
+void UnifiedReportsPage(void);
+
+/// @defgroup ReportPageContractTest_Module "ReportPageContractTest:Module"
+/// @{
+/// @brief Protect the LLM report page from self-triggering screenshot load effects.
+/// @}
+void ReportPageContractTest_Module(void);
+
+/// @defgroup llm_report_screenshot_effect_contract_Function "llm_report_screenshot_effect_contract:Function"
+/// @{
+/// @brief Ensure screenshot loading stays untracked from blob-url mutation state.
+/// @post Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.
+/// @pre Report page source exists.
+/// @}
+void llm_report_screenshot_effect_contract_Function(void);
+
+/// @defgroup SettingsPage "SettingsPage"
+/// @{
+/// @brief Consolidated Settings Page shell — thin layout that delegates each tab to its own component.
+/// @deprecated N/A
+/// @post Page exposes consolidated settings tabs; each tab manages its own state.
+/// @pre Route is loaded in the authenticated UI shell.
+/// @}
+void SettingsPage(void);
+
+/// @defgroup frontend_src_routes_settings__page_ts__load "frontend/src/routes/settings/+page.ts::load"
+/// @{
+/// @}
+void frontend_src_routes_settings__page_ts__load(void);
+
+/// @defgroup FeaturesSettings "FeaturesSettings"
+/// @{
+/// @brief Feature flags configuration tab: enable/disable top-level application features.
+/// @post User can toggle feature flags.
+/// @pre settings object with features config is provided.
+/// @}
+void FeaturesSettings(void);
+
+/// @defgroup LlmSettings "LlmSettings"
+/// @{
+/// @brief LLM configuration tab: providers, bindings, prompts for chatbot and validation.
+/// @post User can configure LLM provider bindings and prompts.
+/// @pre settings object with llm config and llm_providers list is provided.
+/// @}
+void LlmSettings(void);
+
+/// @defgroup LoggingSettings "LoggingSettings"
+/// @{
+/// @brief Logging configuration tab: log level, task log level, belief state toggle.
+/// @post User can adjust logging levels and toggle belief state.
+/// @pre settings object with logging config is provided.
+/// @}
+void LoggingSettings(void);
+
+/// @defgroup MigrationMappingsTable "MigrationMappingsTable"
+/// @{
+/// @brief Mappings data table with search, filtering, and pagination for migration sync resources. Isolated from the main MigrationSettings to keep each module < 400 lines.
+/// @post User can search, filter by environment/type, and paginate through resource mappings.
+/// @pre API client initialized, refreshKey provided by parent.
+/// @}
+void MigrationMappingsTable(void);
+
+/// @defgroup MigrationSettings "MigrationSettings"
+/// @{
+/// @brief Migration sync configuration tab: cron schedule, sync now, mappings table with filtering and pagination.
+/// @post User can configure sync schedule, trigger sync, and browse resource mappings.
+/// @pre API client initialized.
+/// @}
+void MigrationSettings(void);
+
+/// @defgroup StorageSettings "StorageSettings"
+/// @{
+/// @brief Storage configuration tab: root path, backup path, repo path.
+/// @post User can view and edit storage paths.
+/// @pre settings object with storage config is provided.
+/// @}
+void StorageSettings(void);
+
+/// @defgroup SystemSettings "SystemSettings"
+/// @{
+/// @brief System settings tab: timezone configuration and API key management.
+/// @post User can select the application timezone and manage API keys.
+/// @pre settings object is provided with app_timezone field.
+/// @}
+void SystemSettings(void);
+
+/// @defgroup SettingsPageUxTest_Module "SettingsPageUxTest:Module"
+/// @{
+/// @brief Test UX states and transitions
+/// @}
+void SettingsPageUxTest_Module(void);
+
+/// @defgroup AutomationPage "AutomationPage"
+/// @{
+/// @brief Settings page for managing validation policies.
+/// @}
+void AutomationPage(void);
+
+/// @defgroup loadConfigs_Function "loadConfigs:Function"
+/// @{
+/// @brief Fetches existing git configurations.
+/// @post configs state is populated.
+/// @pre Component is mounted.
+/// @}
+void loadConfigs_Function(void);
+
+/// @defgroup handleTest_Function "handleTest:Function"
+/// @{
+/// @brief Tests connection to a git server with current form data.
+/// @post testing state is managed; toast shown with result.
+/// @pre newConfig contains valid provider, url, and pat.
+/// @}
+void handleTest_Function(void);
+
+/// @defgroup handleSave_Function "handleSave:Function"
+/// @{
+/// @brief Saves a new git configuration.
+/// @post New config is saved to DB and added to configs list.
+/// @pre newConfig is valid and tested.
+/// @}
+void handleSave_Function(void);
+
+/// @defgroup handleEdit_Function "handleEdit:Function"
+/// @{
+/// @brief Populates the form with an existing config to edit.
+/// @param {Object} config - Configuration object to edit.
+/// @post Form is populated and isEditing state is set.
+/// @}
+void handleEdit_Function(void);
+
+/// @defgroup resetForm_Function "resetForm:Function"
+/// @{
+/// @brief Resets the configuration form.
+/// @}
+void resetForm_Function(void);
+
+/// @defgroup loadGiteaRepos_Function "loadGiteaRepos:Function"
+/// @{
+/// @brief Loads repositories from selected Gitea config.
+/// @post giteaRepos state updated.
+/// @pre selectedGiteaConfigId is set.
+/// @}
+void loadGiteaRepos_Function(void);
+
+/// @defgroup handleCreateGiteaRepo_Function "handleCreateGiteaRepo:Function"
+/// @{
+/// @brief Creates new repository on selected Gitea server.
+/// @post Repository created and repos list reloaded.
+/// @pre selectedGiteaConfigId and newGiteaRepo.name are set.
+/// @}
+void handleCreateGiteaRepo_Function(void);
+
+/// @defgroup handleDeleteGiteaRepo_Function "handleDeleteGiteaRepo:Function"
+/// @{
+/// @brief Deletes repository from selected Gitea server.
+/// @post Repository deleted and repos list reloaded.
+/// @pre selectedGiteaConfigId is set.
+/// @}
+void handleDeleteGiteaRepo_Function(void);
+
+/// @defgroup GitSettingsPageUxTest_Module "GitSettingsPageUxTest:Module"
+/// @{
+/// @brief Test UX states and transitions for the Git Settings page
+/// @}
+void GitSettingsPageUxTest_Module(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__readTabFromUrl "frontend/src/routes/settings/settings-utils.js::readTabFromUrl"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__readTabFromUrl(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__writeTabToUrl "frontend/src/routes/settings/settings-utils.js::writeTabToUrl"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__writeTabToUrl(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__normalizeTab "frontend/src/routes/settings/settings-utils.js::normalizeTab"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__normalizeTab(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__normalizeLlmSettings "frontend/src/routes/settings/settings-utils.js::normalizeLlmSettings"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__normalizeLlmSettings(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__isDashboardValidationBindingValid "frontend/src/routes/settings/settings-utils.js::isDashboardValidationBindingValid"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__isDashboardValidationBindingValid(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__getProviderById "frontend/src/routes/settings/settings-utils.js::getProviderById"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__getProviderById(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__normalizeSupersetBaseUrl "frontend/src/routes/settings/settings-utils.js::normalizeSupersetBaseUrl"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__normalizeSupersetBaseUrl(void);
+
+/// @defgroup frontend_src_routes_settings_settings_utils_js__resolveEnvStage "frontend/src/routes/settings/settings-utils.js::resolveEnvStage"
+/// @{
+/// @}
+void frontend_src_routes_settings_settings_utils_js__resolveEnvStage(void);
+
+/// @defgroup StorageIndexPage "StorageIndexPage"
+/// @{
+/// @brief Redirect to the backups page as the default storage view.
+/// @invariant Always redirects to /storage/backups.
+/// @}
+void StorageIndexPage(void);
+
+/// @defgroup BackupsRedirectPage "BackupsRedirectPage"
+/// @{
+/// @brief Temporary switch to legacy storage browser for backup UX validation.
+/// @invariant Always redirects to /tools/storage.
+/// @}
+void BackupsRedirectPage(void);
+
+/// @defgroup fetchEnvironments_Function "fetchEnvironments:Function"
+/// @{
+/// @brief Fetches the list of available environments.
+/// @post environments array is populated, selectedEnvId is set to first env if available.
+/// @pre None.
+/// @}
+void fetchEnvironments_Function(void);
+
+/// @defgroup fetchDashboards_Function "fetchDashboards:Function"
+/// @{
+/// @brief Fetches dashboards for a specific environment.
+/// @post dashboards array is populated with metadata for the selected environment.
+/// @pre envId is a valid environment ID.
+/// @}
+void fetchDashboards_Function(void);
+
+/// @defgroup filterDashboardsWithRepositories_Function "filterDashboardsWithRepositories:Function"
+/// @{
+/// @brief Keep only dashboards that already have initialized Git repositories.
+/// @post Returns dashboards with status != NO_REPO.
+/// @pre dashboards list is loaded for selected environment.
+/// @}
+void filterDashboardsWithRepositories_Function(void);
+
+/// @defgroup BackupsPage "BackupsPage"
+/// @{
+/// @brief Entry point for the Backup Management interface.
+/// @}
+void BackupsPage(void);
+
+/// @defgroup DebugToolPage "DebugToolPage"
+/// @{
+/// @brief Page for system diagnostics and debugging.
+/// @}
+void DebugToolPage(void);
+
+/// @defgroup MapperToolPage "MapperToolPage"
+/// @{
+/// @brief Page for the dataset column mapper tool.
+/// @}
+void MapperToolPage(void);
+
+/// @defgroup loadFiles_Function "loadFiles:Function"
+/// @{
+/// @brief Fetches the list of files from the server.
+/// @post Updates the `files` array with the latest data.
+/// @pre currentPath is a valid storage path or empty for root.
+/// @}
+void loadFiles_Function(void);
+
+/// @defgroup resolveStorageQueryFromPath_Function "resolveStorageQueryFromPath:Function"
+/// @{
+/// @brief Splits UI path into storage API category and category-local subpath.
+/// @post Returns {category, subpath} compatible with /api/storage/files.
+/// @pre uiPath may be empty or start with backups/repositorys.
+/// @}
+void resolveStorageQueryFromPath_Function(void);
+
+/// @defgroup handleDelete_Function "handleDelete:Function"
+/// @{
+/// @brief Handles the file deletion process.
+/// @param {CustomEvent} event - The delete event containing category and path.
+/// @post File is deleted and file list is refreshed.
+/// @pre The event contains valid category and path.
+/// @}
+void handleDelete_Function(void);
+
+/// @defgroup handleNavigate_Function "handleNavigate:Function"
+/// @{
+/// @brief Updates the current path and reloads files when navigating into a directory.
+/// @param {CustomEvent} event - The navigation event containing the new path.
+/// @post currentPath is updated and files are reloaded.
+/// @pre The event contains a valid path string.
+/// @}
+void handleNavigate_Function(void);
+
+/// @defgroup navigateUp_Function "navigateUp:Function"
+/// @{
+/// @brief Navigates one level up in the directory structure.
+/// @post currentPath is moved up one directory level.
+/// @pre currentPath is not root.
+/// @}
+void navigateUp_Function(void);
+
+/// @defgroup updateUploadCategory_Function "updateUploadCategory:Function"
+/// @{
+/// @brief Keeps upload category aligned with the currently viewed top-level folder.
+/// @post uploadCategory is either backups or repositorys.
+/// @pre currentPath can be empty or a slash-delimited path.
+/// @}
+void updateUploadCategory_Function(void);
+
+/// @defgroup TranslateJobList "TranslateJobList"
+/// @{
+/// @}
+void TranslateJobList(void);
+
+/// @defgroup TranslationJobConfig "TranslationJobConfig"
+/// @{
+/// @brief Translation job configuration page - orchestrates form state, datasource loading, LLM settings, run/schedule tabs.
+/// @deprecated N/A — active page.
+/// @}
+void TranslationJobConfig(void);
+
+/// @defgroup DictionariesPage "DictionariesPage"
+/// @{
+/// @}
+void DictionariesPage(void);
+
+/// @defgroup DictionaryDetailPage "DictionaryDetailPage"
+/// @{
+/// @}
+void DictionaryDetailPage(void);
+
+/// @defgroup TranslateHistoryPage "TranslateHistoryPage"
+/// @{
+/// @}
+void TranslateHistoryPage(void);
+
+/// @defgroup ValidationTaskList "ValidationTaskList"
+/// @{
+/// @brief Validation task list page with status filter, task cards, and create/duplicate/delete actions.
+/// @param {string} status
+/// @}
+void ValidationTaskList(void);
+
+/// @defgroup ValidationTaskConfig "ValidationTaskConfig"
+/// @{
+/// @brief Validation task configuration page with Config and History tabs. Handles new and edit modes.
+/// @}
+void ValidationTaskConfig(void);
+
+/// @defgroup ValidationHistory "ValidationHistory"
+/// @{
+/// @brief Validation run history page with filters, metrics summary, and run cards.
+/// @}
+void ValidationHistory(void);
+
+/// @defgroup GitServiceContractTests "GitServiceContractTests"
+/// @{
+/// @brief API client tests ensuring correct endpoints are called per contract for Git service operations.
+/// @}
+void GitServiceContractTests(void);
+
+/// @defgroup gitServiceContractTests_Module "gitServiceContractTests:Module"
+/// @{
+/// @brief API client tests ensuring correct endpoints are called per contract
+/// @post Returns promotion metadata
+/// @pre Repo initialized
+/// @}
+void gitServiceContractTests_Module(void);
+
+/// @defgroup AdminService "AdminService"
+/// @{
+/// @brief Service for Admin-related API calls including User and Role management, AD group mappings, and logging configuration.
+/// @}
+void AdminService(void);
+
+/// @defgroup adminService_Module "adminService:Module"
+/// @{
+/// @brief Service for Admin-related API calls (User and Role management).
+/// @invariant All requests must include valid Admin JWT token (handled by api client).
+/// @}
+void adminService_Module(void);
+
+/// @defgroup getUsers_Function "getUsers:Function"
+/// @{
+/// @brief Fetches all registered users from the backend.
+/// @post Returns an array of user objects.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void getUsers_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__getUsers "frontend/src/services/adminService.js::getUsers"
+/// @{
+/// @post Returns an array of user objects.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__getUsers(void);
+
+/// @defgroup createUser_Function "createUser:Function"
+/// @{
+/// @brief Creates a new local user.
+/// @param {Object} userData - User details (username, email, password, roles, is_active).
+/// @post New user record created in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void createUser_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__createUser "frontend/src/services/adminService.js::createUser"
+/// @{
+/// @post New user record created in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__createUser(void);
+
+/// @defgroup getRoles_Function "getRoles:Function"
+/// @{
+/// @brief Fetches all available system roles.
+/// @post Returns an array of role objects.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void getRoles_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__getRoles "frontend/src/services/adminService.js::getRoles"
+/// @{
+/// @post Returns an array of role objects.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__getRoles(void);
+
+/// @defgroup getADGroupMappings_Function "getADGroupMappings:Function"
+/// @{
+/// @brief Fetches mappings between AD groups and local roles.
+/// @post Returns an array of AD group mapping objects.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void getADGroupMappings_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__getADGroupMappings "frontend/src/services/adminService.js::getADGroupMappings"
+/// @{
+/// @post Returns an array of AD group mapping objects.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__getADGroupMappings(void);
+
+/// @defgroup createADGroupMapping_Function "createADGroupMapping:Function"
+/// @{
+/// @brief Creates or updates an AD group to Role mapping.
+/// @param {Object} mappingData - Mapping details (ad_group, role_id).
+/// @post New or updated mapping created in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void createADGroupMapping_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__createADGroupMapping "frontend/src/services/adminService.js::createADGroupMapping"
+/// @{
+/// @post New or updated mapping created in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__createADGroupMapping(void);
+
+/// @defgroup updateUser_Function "updateUser:Function"
+/// @{
+/// @brief Updates an existing user.
+/// @param {Object} userData - Updated user data.
+/// @post User record updated in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void updateUser_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__updateUser "frontend/src/services/adminService.js::updateUser"
+/// @{
+/// @post User record updated in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__updateUser(void);
+
+/// @defgroup deleteUser_Function "deleteUser:Function"
+/// @{
+/// @brief Deletes a user.
+/// @param {string} userId - Target user ID.
+/// @post User record removed from auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void deleteUser_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__deleteUser "frontend/src/services/adminService.js::deleteUser"
+/// @{
+/// @post User record removed from auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__deleteUser(void);
+
+/// @defgroup createRole_Function "createRole:Function"
+/// @{
+/// @brief Creates a new role.
+/// @param {Object} roleData - Role details (name, description, permissions).
+/// @post New role created in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @return {Promise}
+/// @}
+void createRole_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__createRole "frontend/src/services/adminService.js::createRole"
+/// @{
+/// @post New role created in auth.db.
+/// @pre User must be authenticated with Admin privileges.
+/// @}
+void frontend_src_services_adminService_js__createRole(void);
+
+/// @defgroup updateRole_Function "updateRole:Function"
+/// @{
+/// @brief Updates an existing role.
+/// @param {Object} roleData - Updated role data.
+/// @return {Promise}
+/// @}
+void updateRole_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__updateRole "frontend/src/services/adminService.js::updateRole"
+/// @{
+/// @}
+void frontend_src_services_adminService_js__updateRole(void);
+
+/// @defgroup deleteRole_Function "deleteRole:Function"
+/// @{
+/// @brief Deletes a role.
+/// @param {string} roleId - Target role ID.
+/// @return {Promise}
+/// @}
+void deleteRole_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__deleteRole "frontend/src/services/adminService.js::deleteRole"
+/// @{
+/// @}
+void frontend_src_services_adminService_js__deleteRole(void);
+
+/// @defgroup getPermissions_Function "getPermissions:Function"
+/// @{
+/// @brief Fetches all available permissions.
+/// @return {Promise}
+/// @}
+void getPermissions_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__getPermissions "frontend/src/services/adminService.js::getPermissions"
+/// @{
+/// @}
+void frontend_src_services_adminService_js__getPermissions(void);
+
+/// @defgroup getLoggingConfig_Function "getLoggingConfig:Function"
+/// @{
+/// @brief Fetches current logging configuration.
+/// @return {Promise} - Logging config with level, task_log_level, enable_belief_state.
+/// @}
+void getLoggingConfig_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__getLoggingConfig "frontend/src/services/adminService.js::getLoggingConfig"
+/// @{
+/// @}
+void frontend_src_services_adminService_js__getLoggingConfig(void);
+
+/// @defgroup updateLoggingConfig_Function "updateLoggingConfig:Function"
+/// @{
+/// @brief Updates logging configuration.
+/// @param {Object} configData - Logging config (level, task_log_level, enable_belief_state).
+/// @return {Promise}
+/// @}
+void updateLoggingConfig_Function(void);
+
+/// @defgroup frontend_src_services_adminService_js__updateLoggingConfig "frontend/src/services/adminService.js::updateLoggingConfig"
+/// @{
+/// @}
+void frontend_src_services_adminService_js__updateLoggingConfig(void);
+
+/// @defgroup GitUtils "GitUtils"
+/// @{
+/// @brief Shared utility functions extracted from GitManager.svelte.
+/// @}
+void GitUtils(void);
+
+/// @defgroup frontend_src_services_git_utils_js__normalizeEnvStage "frontend/src/services/git-utils.js::normalizeEnvStage"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__normalizeEnvStage(void);
+
+/// @defgroup frontend_src_services_git_utils_js__stageBadgeClass "frontend/src/services/git-utils.js::stageBadgeClass"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__stageBadgeClass(void);
+
+/// @defgroup frontend_src_services_git_utils_js__resolveCurrentEnvironmentId "frontend/src/services/git-utils.js::resolveCurrentEnvironmentId"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__resolveCurrentEnvironmentId(void);
+
+/// @defgroup frontend_src_services_git_utils_js__applyGitflowStageDefaults "frontend/src/services/git-utils.js::applyGitflowStageDefaults"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__applyGitflowStageDefaults(void);
+
+/// @defgroup frontend_src_services_git_utils_js__isNumericDashboardRef "frontend/src/services/git-utils.js::isNumericDashboardRef"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__isNumericDashboardRef(void);
+
+/// @defgroup frontend_src_services_git_utils_js__getSelectedConfig "frontend/src/services/git-utils.js::getSelectedConfig"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__getSelectedConfig(void);
+
+/// @defgroup frontend_src_services_git_utils_js__resolveDefaultConfig "frontend/src/services/git-utils.js::resolveDefaultConfig"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__resolveDefaultConfig(void);
+
+/// @defgroup frontend_src_services_git_utils_js__resolvePushProviderLabel "frontend/src/services/git-utils.js::resolvePushProviderLabel"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__resolvePushProviderLabel(void);
+
+/// @defgroup frontend_src_services_git_utils_js__extractHttpHost "frontend/src/services/git-utils.js::extractHttpHost"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__extractHttpHost(void);
+
+/// @defgroup frontend_src_services_git_utils_js__buildSuggestedRepoName "frontend/src/services/git-utils.js::buildSuggestedRepoName"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__buildSuggestedRepoName(void);
+
+/// @defgroup frontend_src_services_git_utils_js__tryParseJsonObject "frontend/src/services/git-utils.js::tryParseJsonObject"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__tryParseJsonObject(void);
+
+/// @defgroup frontend_src_services_git_utils_js__extractUnfinishedMergeContext "frontend/src/services/git-utils.js::extractUnfinishedMergeContext"
+/// @{
+/// @}
+void frontend_src_services_git_utils_js__extractUnfinishedMergeContext(void);
+
+/// @defgroup StorageService "StorageService"
+/// @{
+/// @brief Frontend API client for file storage management including list, upload, download, and delete operations.
+/// @}
+void StorageService(void);
+
+/// @defgroup storageService_Module "storageService:Module"
+/// @{
+/// @brief Frontend API client for file storage management.
+/// @}
+void storageService_Module(void);
+
+/// @defgroup getStorageAuthHeaders_Function "getStorageAuthHeaders:Function"
+/// @{
+/// @brief Returns headers with Authorization for storage API calls.
+/// @note Unlike api.js getAuthHeaders, this doesn't set Content-Type
+/// @return {Object} Headers object with Authorization if token exists.
+/// @}
+void getStorageAuthHeaders_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__getStorageAuthHeaders "frontend/src/services/storageService.js::getStorageAuthHeaders"
+/// @{
+/// @}
+void frontend_src_services_storageService_js__getStorageAuthHeaders(void);
+
+/// @defgroup encodeStoragePath_Function "encodeStoragePath:Function"
+/// @{
+/// @brief Encodes a storage-relative path preserving slash separators.
+/// @param {string} path - Relative storage path.
+/// @return {string} Encoded path safe for URL segments.
+/// @}
+void encodeStoragePath_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__encodeStoragePath "frontend/src/services/storageService.js::encodeStoragePath"
+/// @{
+/// @}
+void frontend_src_services_storageService_js__encodeStoragePath(void);
+
+/// @defgroup listFiles_Function "listFiles:Function"
+/// @{
+/// @brief Fetches the list of files for a given category and subpath.
+/// @param {string} [path] - Optional subpath filter.
+/// @post Returns a promise resolving to an array of StoredFile objects.
+/// @pre category and path should be valid strings if provided.
+/// @return {Promise}
+/// @}
+void listFiles_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__listFiles "frontend/src/services/storageService.js::listFiles"
+/// @{
+/// @post Returns a promise resolving to an array of StoredFile objects.
+/// @pre category and path should be valid strings if provided.
+/// @}
+void frontend_src_services_storageService_js__listFiles(void);
+
+/// @defgroup uploadFile_Function "uploadFile:Function"
+/// @{
+/// @brief Uploads a file to the storage system.
+/// @param {string} [path] - Target subpath.
+/// @post Returns a promise resolving to the metadata of the uploaded file.
+/// @pre file must be a valid File object; category must be specified.
+/// @return {Promise}
+/// @}
+void uploadFile_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__uploadFile "frontend/src/services/storageService.js::uploadFile"
+/// @{
+/// @post Returns a promise resolving to the metadata of the uploaded file.
+/// @pre file must be a valid File object; category must be specified.
+/// @}
+void frontend_src_services_storageService_js__uploadFile(void);
+
+/// @defgroup deleteFile_Function "deleteFile:Function"
+/// @{
+/// @brief Deletes a file or directory from storage.
+/// @param {string} path - Relative path of the item.
+/// @post The specified file or directory is removed from storage.
+/// @pre category and path must identify an existing file or directory.
+/// @return {Promise}
+/// @}
+void deleteFile_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__deleteFile "frontend/src/services/storageService.js::deleteFile"
+/// @{
+/// @post The specified file or directory is removed from storage.
+/// @pre category and path must identify an existing file or directory.
+/// @}
+void frontend_src_services_storageService_js__deleteFile(void);
+
+/// @defgroup downloadFileUrl_Function "downloadFileUrl:Function"
+/// @{
+/// @brief Returns the URL for downloading a file.
+/// @note Downloads use browser navigation, so auth is handled via cookies
+/// @param {string} path - Relative path of the file.
+/// @post Returns a valid API URL for file download.
+/// @pre category and path must identify an existing file.
+/// @return {string}
+/// @}
+void downloadFileUrl_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__downloadFileUrl "frontend/src/services/storageService.js::downloadFileUrl"
+/// @{
+/// @post Returns a valid API URL for file download.
+/// @pre category and path must identify an existing file.
+/// @}
+void frontend_src_services_storageService_js__downloadFileUrl(void);
+
+/// @defgroup downloadFile_Function "downloadFile:Function"
+/// @{
+/// @brief Downloads a file using authenticated fetch and saves it in browser.
+/// @param {string} [filename] - Optional preferred filename.
+/// @post Browser download is triggered or an Error is thrown.
+/// @pre category/path identify an existing file and user has READ permission.
+/// @return {Promise}
+/// @}
+void downloadFile_Function(void);
+
+/// @defgroup frontend_src_services_storageService_js__downloadFile "frontend/src/services/storageService.js::downloadFile"
+/// @{
+/// @post Browser download is triggered or an Error is thrown.
+/// @pre category/path identify an existing file and user has READ permission.
+/// @}
+void frontend_src_services_storageService_js__downloadFile(void);
+
+/// @defgroup TaskService "TaskService"
+/// @{
+/// @brief Service for Task Management API interactions: listing, fetching details, resuming, resolving, and clearing tasks.
+/// @}
+void TaskService(void);
+
+/// @defgroup getTasks_Function "getTasks:Function"
+/// @{
+/// @brief Fetch a list of tasks with pagination and optional status filter.
+/// @post Returns a promise resolving to a list of tasks.
+/// @pre limit and offset are numbers.
+/// @}
+void getTasks_Function(void);
+
+/// @defgroup frontend_src_services_taskService_js__getTasks "frontend/src/services/taskService.js::getTasks"
+/// @{
+/// @}
+void frontend_src_services_taskService_js__getTasks(void);
+
+/// @defgroup getTask_Function "getTask:Function"
+/// @{
+/// @brief Fetch details for a specific task.
+/// @post Returns a promise resolving to task details.
+/// @pre taskId must be provided.
+/// @}
+void getTask_Function(void);
+
+/// @defgroup frontend_src_services_taskService_js__getTask "frontend/src/services/taskService.js::getTask"
+/// @{
+/// @}
+void frontend_src_services_taskService_js__getTask(void);
+
+/// @defgroup getTaskLogs_Function "getTaskLogs:Function"
+/// @{
+/// @brief Fetch logs for a specific task.
+/// @post Returns a promise resolving to a list of log entries.
+/// @pre taskId must be provided.
+/// @}
+void getTaskLogs_Function(void);
+
+/// @defgroup frontend_src_services_taskService_js__getTaskLogs "frontend/src/services/taskService.js::getTaskLogs"
+/// @{
+/// @}
+void frontend_src_services_taskService_js__getTaskLogs(void);
+
+/// @defgroup resumeTask_Function "resumeTask:Function"
+/// @{
+/// @brief Resume a task that is awaiting input (e.g., passwords).
+/// @post Returns a promise resolving to the updated task object.
+/// @pre taskId and passwords must be provided.
+/// @}
+void resumeTask_Function(void);
+
+/// @defgroup frontend_src_services_taskService_js__resumeTask "frontend/src/services/taskService.js::resumeTask"
+/// @{
+/// @}
+void frontend_src_services_taskService_js__resumeTask(void);
+
+/// @defgroup resolveTask_Function "resolveTask:Function"
+/// @{
+/// @brief Resolve a task that is awaiting mapping.
+/// @post Returns a promise resolving to the updated task object.
+/// @pre taskId and resolutionParams must be provided.
+/// @}
+void resolveTask_Function(void);
+
+/// @defgroup frontend_src_services_taskService_js__resolveTask "frontend/src/services/taskService.js::resolveTask"
+/// @{
+/// @}
+void frontend_src_services_taskService_js__resolveTask(void);
+
+/// @defgroup clearTasks_Function "clearTasks:Function"
+/// @{
+/// @brief Clear tasks based on status.
+/// @post Returns a promise that resolves when tasks are cleared.
+/// @pre status is a string or null.
+/// @}
+void clearTasks_Function(void);
+
+/// @defgroup frontend_src_services_taskService_js__clearTasks "frontend/src/services/taskService.js::clearTasks"
+/// @{
+/// @}
+void frontend_src_services_taskService_js__clearTasks(void);
+
+/// @defgroup ToolsService "ToolsService"
+/// @{
+/// @brief Service for generic Task API communication used by Tools — run tasks and poll status.
+/// @}
+void ToolsService(void);
+
+/// @defgroup runTask_Function "runTask:Function"
+/// @{
+/// @brief Start a new task for a given plugin.
+/// @post Returns a promise resolving to the task instance.
+/// @pre pluginId and params must be provided.
+/// @}
+void runTask_Function(void);
+
+/// @defgroup frontend_src_services_toolsService_js__runTask "frontend/src/services/toolsService.js::runTask"
+/// @{
+/// @}
+void frontend_src_services_toolsService_js__runTask(void);
+
+/// @defgroup getTaskStatus_Function "getTaskStatus:Function"
+/// @{
+/// @brief Fetch details for a specific task (to poll status or get result).
+/// @post Returns a promise resolving to task details.
+/// @pre taskId must be provided.
+/// @}
+void getTaskStatus_Function(void);
+
+/// @defgroup frontend_src_services_toolsService_js__getTaskStatus "frontend/src/services/toolsService.js::getTaskStatus"
+/// @{
+/// @}
+void frontend_src_services_toolsService_js__getTaskStatus(void);
+
+/// @defgroup BackupTypes "BackupTypes"
+/// @{
+/// @}
+void BackupTypes(void);
+
+/// @defgroup frontend_src_types_backup_ts__Backup "frontend/src/types/backup.ts::Backup"
+/// @{
+/// @}
+void frontend_src_types_backup_ts__Backup(void);
+
+/// @defgroup BackupTypes_Module "BackupTypes:Module"
+/// @{
+/// @}
+void BackupTypes_Module(void);
+
+/// @defgroup DashboardTypes "DashboardTypes"
+/// @{
+/// @}
+void DashboardTypes(void);
+
+/// @defgroup DashboardTypes_Module "DashboardTypes:Module"
+/// @{
+/// @brief TypeScript interfaces for Dashboard entities
+/// @}
+void DashboardTypes_Module(void);
+
+/// @defgroup frontend_src_types_dashboard_ts__DashboardMetadata "frontend/src/types/dashboard.ts::DashboardMetadata"
+/// @{
+/// @}
+void frontend_src_types_dashboard_ts__DashboardMetadata(void);
+
+/// @defgroup MaintenanceStoreTests "MaintenanceStoreTests"
+/// @{
+/// @brief Unit tests for MaintenanceStore runes-based store.
+/// @}
+void MaintenanceStoreTests(void);
+
+/// @defgroup MaintenanceComponentTests "MaintenanceComponentTests"
+/// @{
+/// @brief Component tests for MaintenanceEventsTable and DashboardMaintenanceBadge.
+/// @}
+void MaintenanceComponentTests(void);
+
+/// @defgroup MergeSpec "MergeSpec"
+/// @{
+/// @}
+void MergeSpec(void);
+
+/// @defgroup merge_spec "merge_spec"
+/// @{
+/// @}
+void merge_spec(void);
+
+/// @defgroup BuildOfflineDockerBundle "BuildOfflineDockerBundle"
+/// @{
+/// @brief Thin wrapper — delegates to ./build.sh bundle (.tar.xz output)
+/// @}
+void BuildOfflineDockerBundle(void);
+
+/// @defgroup venv_lib_python3_13_site_packages_greenlet_TThreadState_hpp__ThreadState "venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp::ThreadState"
+/// @{
+/// @}
+void venv_lib_python3_13_site_packages_greenlet_TThreadState_hpp__ThreadState(void);
diff --git a/docs/api/doxygen_grace.txt b/docs/api/doxygen_grace.txt
new file mode 100644
index 00000000..02e7fc61
--- /dev/null
+++ b/docs/api/doxygen_grace.txt
@@ -0,0 +1,21577 @@
+// AXIOM Doc Generator — Generated docs
+// Format: doxygen Mode: grace Contracts: 3195
+// Usage: run through `jsdoc --pedantic` or `doxygen -W` for validation
+
+// --- SrcRoot (backend/src/__init__.py)
+/**!
+ * @brief Canonical backend package root for application, scripts, and tests.
+ */
+
+// --- src.api (backend/src/api/__init__.py)
+/**!
+ * @brief Backend API package root.
+ */
+
+// --- AuthApi (backend/src/api/auth.py)
+/**!
+ * @brief Authentication API endpoints.
+ * @complexity 5
+ * @data_contract Input -> OAuth2PasswordRequestForm -> Token, User
+ * @invariant All auth endpoints must return consistent error codes.
+ * @layer API
+ * @post FastAPI app instance with auth routes registered.
+ * @pre Python environment and dependencies installed; database available.
+ * @side_effect Registers API routes; configures OAuth and CORS middleware.
+ */
+
+// --- login_for_access_token (backend/src/api/auth.py)
+/**!
+ * @brief Authenticates a user and returns a JWT access token.
+ * @complexity 4
+ * @post Returns a Token object on success.
+ * @pre form_data contains username and password.
+ * @side_effect DB read/write for auth session; writes security event log.
+ */
+
+// --- read_users_me (backend/src/api/auth.py)
+/**!
+ * @brief Retrieves the profile of the currently authenticated user.
+ * @complexity 4
+ * @post Returns the current user's data.
+ * @pre Valid JWT token provided.
+ * @side_effect Reads current user from DB via auth middleware; writes security event log.
+ */
+
+// --- logout (backend/src/api/auth.py)
+/**!
+ * @brief Logs out the current user (placeholder for session revocation).
+ * @complexity 4
+ * @post Returns success message.
+ * @pre Valid JWT token provided.
+ * @side_effect Writes security event LOGOUT event.
+ */
+
+// --- login_adfs (backend/src/api/auth.py)
+/**!
+ * @brief Initiates the ADFS OIDC login flow.
+ * @complexity 4
+ * @post Redirects the user to ADFS.
+ * @side_effect Redirects user to ADFS external OIDC provider.
+ */
+
+// --- auth_callback_adfs (backend/src/api/auth.py)
+/**!
+ * @brief Handles the callback from ADFS after successful authentication.
+ * @complexity 4
+ * @post Provisions user JIT and returns session token.
+ * @side_effect Provisions user in DB, creates auth session, writes security event log.
+ */
+
+// --- ApiRoutesModule (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Provide lazy route module loading to avoid heavyweight imports during tests.
+ * @complexity 5
+ * @invariant Only names listed in __all__ are importable via __getattr__.
+ * @layer API
+ * @post Route modules are lazily loadable via __getattr__
+ * @pre FastAPI app initialized, route modules available in package
+ */
+
+// --- Route_Group_Contracts (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Declare the canonical route-module registry used by lazy imports and app router inclusion.
+ * @complexity 3
+ * @data_contract Package -> RouterModule mapping
+ * @side_effect Registers route group imports via __getattr__
+ */
+
+// --- ApiRoutesGetAttr (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Lazily import route module by attribute name.
+ * @complexity 3
+ * @post Returns imported submodule or raises AttributeError.
+ * @pre name is module candidate exposed in __all__.
+ */
+
+// --- RoutesTestsConftest (backend/src/api/routes/__tests__/conftest.py)
+/**!
+ * @brief Shared low-fidelity test doubles for API route test modules.
+ * @complexity 1
+ */
+
+// --- AssistantApiTests (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Validate assistant API endpoint logic via direct async handler invocation.
+ * @complexity 3
+ * @invariant Every test clears assistant in-memory state before execution.
+ */
+
+// --- _dataset_review_session (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Build minimal owned dataset-review session fixture for assistant scoped routing tests.
+ * @complexity 1
+ */
+
+// --- _await_none (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Async helper returning None for planner fallback tests.
+ * @complexity 1
+ */
+
+// --- test_unknown_command_returns_needs_clarification (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Unknown command should return clarification state and unknown intent.
+ */
+
+// --- test_capabilities_question_returns_successful_help (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Capability query should return deterministic help response.
+ */
+
+// --- test_assistant_message_request_accepts_dataset_review_session_binding (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Assistant request schema should accept active dataset review session binding for scoped orchestration.
+ */
+
+// --- test_dataset_review_scoped_message_uses_masked_filter_context (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant context should mask imported-filter raw values before assistant-visible metadata is persisted.
+ */
+
+// --- test_dataset_review_scoped_command_returns_confirmation_for_mapping_approval (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant commands should route dataset-review mapping approvals into confirmation workflow with bound session metadata.
+ */
+
+// --- test_dataset_review_scoped_command_routes_field_semantics_update (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant commands should route semantic field updates through explicit confirmation metadata.
+ */
+
+// --- TestAssistantAuthz (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Verify assistant confirmation ownership, expiration, and deny behavior for restricted users.
+ * @complexity 3
+ * @invariant Security-sensitive flows fail closed for unauthorized actors.
+ * @layer API
+ */
+
+// --- _run_async (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Execute async endpoint handler in synchronous test context.
+ * @complexity 1
+ * @post Returns coroutine result or raises propagated exception.
+ * @pre coroutine is awaitable endpoint invocation.
+ */
+
+// --- _FakeTask (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Lightweight task model used for assistant authz tests.
+ * @complexity 1
+ * @post Returns task with provided id, status, and user_id accessible as attributes.
+ * @pre task_id is non-empty string.
+ */
+
+// --- _FakeConfigManager (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Provide deterministic environment aliases required by intent parsing.
+ * @complexity 1
+ * @invariant get_config() is absent; only get_environments() is emulated. Safe only for routes that do not invoke get_config() on the injected ConfigManager — verify against assistant.py route handler code before adding new test cases that use this fake.
+ * @post get_environments() returns two deterministic SimpleNamespace stubs with id/name.
+ * @pre No external config or DB state is required.
+ */
+
+// --- _other_admin_user (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Build second admin principal fixture for ownership tests.
+ * @complexity 1
+ * @post Returns alternate admin-like user stub.
+ * @pre Ownership mismatch scenario needs distinct authenticated actor.
+ */
+
+// --- _limited_user (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Build limited principal without required assistant execution privileges.
+ * @complexity 1
+ * @post Returns restricted user stub.
+ * @pre Permission denial scenario needs non-admin actor.
+ */
+
+// --- _FakeDb (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief In-memory DB session double constrained to assistant message/confirmation/audit persistence paths.
+ * @complexity 2
+ * @invariant query/add/merge are intentionally narrow and must not claim full SQLAlchemy Session semantics.
+ */
+
+// --- _clear_assistant_state (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Reset assistant process-local state between test cases.
+ * @complexity 1
+ * @post Assistant in-memory state dictionaries are cleared.
+ * @pre Assistant globals may contain state from prior tests.
+ */
+
+// --- test_confirmation_owner_mismatch_returns_403 (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Confirm endpoint should reject requests from user that does not own the confirmation token.
+ * @post Second actor receives 403 on confirm operation.
+ * @pre Confirmation token is created by first admin actor.
+ */
+
+// --- test_expired_confirmation_cannot_be_confirmed (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Expired confirmation token should be rejected and not create task.
+ * @post Confirm endpoint raises 400 and no task is created.
+ * @pre Confirmation token exists and is manually expired before confirm request.
+ */
+
+// --- test_limited_user_cannot_launch_restricted_operation (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Limited user should receive denied state for privileged operation.
+ * @post Assistant returns denied state and does not execute operation.
+ * @pre Restricted user attempts dangerous deploy command.
+ */
+
+// --- TestCleanReleaseApi (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Contract tests for clean release checks and reports endpoints.
+ * @complexity 3
+ * @invariant API returns deterministic payload shapes for checks and reports.
+ * @layer Domain
+ */
+
+// --- test_start_check_and_get_status_contract (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate checks start endpoint returns expected identifiers and status endpoint reflects the same run.
+ */
+
+// --- test_get_report_not_found_returns_404 (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate reports endpoint returns 404 for an unknown report identifier.
+ */
+
+// --- test_get_report_success (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate reports endpoint returns persisted report payload for an existing report identifier.
+ */
+
+// --- test_prepare_candidate_api_success (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate candidate preparation endpoint returns prepared status and manifest identifier on valid input.
+ */
+
+// --- TestCleanReleaseLegacyCompat (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Compatibility tests for legacy clean-release API paths retained during v2 migration.
+ * @complexity 3
+ * @layer Tests
+ */
+
+// --- _seed_legacy_repo (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Seed in-memory repository with minimum trusted data for legacy endpoint contracts.
+ * @post Candidate, policy, registry and manifest are available for legacy checks flow.
+ * @pre Repository is empty.
+ */
+
+// --- test_legacy_prepare_endpoint_still_available (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Verify legacy prepare endpoint remains reachable and returns a status payload.
+ */
+
+// --- test_legacy_checks_endpoints_still_available (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Verify legacy checks start/status endpoints remain available during v2 transition.
+ */
+
+// --- TestCleanReleaseSourcePolicy (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Validate API behavior for source isolation violations in clean release preparation.
+ * @complexity 3
+ * @invariant External endpoints must produce blocking violation entries.
+ * @layer Domain
+ */
+
+// --- _repo_with_seed_data (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Seed repository with candidate, registry, and active policy for source isolation test flow.
+ */
+
+// --- test_prepare_candidate_blocks_external_source (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Verify candidate preparation is blocked when at least one source host is external to the trusted registry.
+ */
+
+// --- CleanReleaseV2ApiTests (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief API contract tests for redesigned clean release endpoints.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- test_candidate_registration_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate candidate registration endpoint creates a draft candidate with expected identifier contract.
+ */
+
+// --- test_artifact_import_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate artifact import endpoint accepts candidate artifacts and returns success status payload.
+ */
+
+// --- test_manifest_build_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate manifest build endpoint produces manifest payload linked to the target candidate.
+ */
+
+// --- CleanReleaseV2ReleaseApiTests (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief API contract test scaffolding for clean release approval and publication endpoints.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- _seed_candidate_and_passed_report (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Seed repository with approvable candidate and passed report for release endpoint contracts.
+ */
+
+// --- test_release_approve_and_publish_revoke_contract (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Verify approve, publish, and revoke endpoints preserve expected release lifecycle contract.
+ */
+
+// --- test_release_reject_contract (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Verify reject endpoint returns successful rejection decision payload.
+ */
+
+// --- DashboardsApiTests (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Unit tests for dashboards API endpoints.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- test_get_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns a populated response that satisfies the schema contract.
+ * @post Response matches DashboardsResponse schema
+ * @pre env_id exists
+ * @test GET /api/dashboards returns 200 and valid schema
+ * @test_fixture dashboard_list_happy -> {"id": 1, "title": "Main Revenue"}
+ */
+
+// --- test_get_dashboards_with_search (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing applies the search filter and returns only matching rows.
+ * @post Filtered result count must match search
+ * @pre search parameter provided
+ * @test GET /api/dashboards filters by search term
+ */
+
+// --- test_get_dashboards_empty (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns an empty payload for an environment without dashboards.
+ * @test_edge empty_dashboards -> {env_id: 'empty_env', expected_total: 0}
+ */
+
+// --- test_get_dashboards_superset_failure (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing surfaces a 503 contract when Superset access fails.
+ * @test_edge external_superset_failure -> {env_id: 'bad_conn', status: 503}
+ */
+
+// --- test_get_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns 404 when the requested environment does not exist.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test GET /api/dashboards returns 404 if env_id missing
+ */
+
+// --- test_get_dashboards_invalid_pagination (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing rejects invalid pagination parameters with 400 responses.
+ * @post Returns 400 error
+ * @pre page < 1 or page_size > 100
+ * @test GET /api/dashboards returns 400 for invalid page/page_size
+ */
+
+// --- test_get_dashboard_detail_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard detail returns charts and datasets for an existing dashboard.
+ * @test GET /api/dashboards/{id} returns dashboard detail with charts and datasets
+ */
+
+// --- test_get_dashboard_detail_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard detail returns 404 when the requested environment is missing.
+ * @test GET /api/dashboards/{id} returns 404 for missing environment
+ */
+
+// --- test_migrate_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard migration request creates an async task and returns its identifier.
+ * @post Returns task_id and create_task was called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@POST/@SIDE_EFFECT: create_task was called
+ * @pre Valid source_env_id, target_env_id, dashboard_ids
+ * @test POST /api/dashboards/migrate creates migration task
+ */
+
+// --- test_migrate_dashboards_no_ids (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard migration rejects empty dashboard identifier lists.
+ * @post Returns 400 error
+ * @pre dashboard_ids is empty
+ * @test POST /api/dashboards/migrate returns 400 for empty dashboard_ids
+ */
+
+// --- test_migrate_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate migration creation returns 404 when the source environment cannot be resolved.
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- test_backup_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard backup request creates an async backup task and returns its identifier.
+ * @post Returns task_id and create_task was called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@POST/@SIDE_EFFECT: create_task was called
+ * @pre Valid env_id, dashboard_ids
+ * @test POST /api/dashboards/backup creates backup task
+ */
+
+// --- test_backup_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate backup task creation returns 404 when the target environment is missing.
+ * @pre env_id is a valid environment ID
+ */
+
+// --- test_get_database_mappings_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate database mapping suggestions are returned for valid source and target environments.
+ * @post Returns list of database mappings
+ * @pre Valid source_env_id, target_env_id
+ * @test GET /api/dashboards/db-mappings returns mapping suggestions
+ */
+
+// --- test_get_database_mappings_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate database mapping suggestions return 404 when either environment is missing.
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- test_get_dashboard_tasks_history_filters_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard task history returns only related backup and LLM tasks.
+ * @test GET /api/dashboards/{id}/tasks returns backup and llm tasks for dashboard
+ */
+
+// --- test_get_dashboard_thumbnail_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard thumbnail endpoint proxies image bytes and content type from Superset.
+ * @test GET /api/dashboards/{id}/thumbnail proxies image bytes from Superset
+ */
+
+// --- _build_profile_preference_stub (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Creates profile preference payload stub for dashboards filter contract tests.
+ * @post Returns object compatible with ProfileService.get_my_preference contract.
+ * @pre username can be empty; enabled indicates profile-default toggle state.
+ */
+
+// --- _matches_actor_case_insensitive (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Applies trim + case-insensitive owners OR modified_by matching used by route contract tests.
+ * @post Returns True when bound username matches any owner or modified_by.
+ * @pre owners can be None or list-like values.
+ */
+
+// --- test_get_dashboards_profile_filter_contract_owners_or_modified_by (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering matches owner and modifier aliases using normalized Superset actor values.
+ * @post Response includes only matching dashboards and effective_profile_filter metadata.
+ * @pre Current user has enabled profile-default preference and bound username.
+ * @test GET /api/dashboards applies profile-default filter with owners OR modified_by trim+case-insensitive semantics.
+ */
+
+// --- test_get_dashboards_override_show_all_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate override_show_all bypasses profile-default filtering without changing dashboard list semantics.
+ * @post Response remains unfiltered and effective_profile_filter.applied is false.
+ * @pre Profile-default preference exists but override_show_all=true query is provided.
+ * @test GET /api/dashboards honors override_show_all and disables profile-default filter for current page.
+ */
+
+// --- test_get_dashboards_profile_filter_no_match_results_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering returns an empty dashboard page when no actor aliases match the bound user.
+ * @post Response total is 0 with deterministic pagination and active effective_profile_filter metadata.
+ * @pre Profile-default preference is enabled with bound username and all dashboards are non-matching.
+ * @test GET /api/dashboards returns empty result set when profile-default filter is active and no dashboard actors match.
+ */
+
+// --- test_get_dashboards_page_context_other_disables_profile_default (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate non-dashboard page contexts suppress profile-default filtering and preserve unfiltered results.
+ * @post Response remains unfiltered and metadata reflects source_page=other.
+ * @pre Profile-default preference exists but page_context=other query is provided.
+ * @test GET /api/dashboards does not auto-apply profile-default filter outside dashboards_main page context.
+ */
+
+// --- test_get_dashboards_profile_filter_matches_display_alias_without_detail_fanout (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering reuses resolved Superset display aliases without triggering per-dashboard detail fanout.
+ * @post Route matches by alias (`Superset Admin`) and does not call `SupersetClient.get_dashboard` in list filter path.
+ * @pre Profile-default filter is active, bound username is `admin`, dashboard actors contain display labels.
+ * @test GET /api/dashboards resolves Superset display-name alias once and filters without per-dashboard detail calls.
+ */
+
+// --- test_get_dashboards_profile_filter_matches_owner_object_payload_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering accepts owner object payloads once aliases resolve to the bound Superset username.
+ * @post Response keeps dashboards where owner object resolves to bound username alias.
+ * @pre Profile-default preference is enabled and owners list contains dict payloads.
+ * @test GET /api/dashboards profile-default filter matches Superset owner object payloads.
+ */
+
+// --- DatasetReviewApiTests (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify backend US1 dataset review lifecycle, export, parsing, and dictionary-resolution contracts.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- _make_user (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_config_manager (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_us2_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_us3_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_preview_ready_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- dataset_review_api_dependencies (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- test_parse_superset_link_dashboard_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard links recover dataset context and preserve explicit partial-recovery markers.
+ */
+
+// --- test_parse_superset_link_dashboard_slug_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard slug links resolve through dashboard detail endpoints and recover dataset context.
+ */
+
+// --- test_parse_superset_link_dashboard_permalink_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard permalink links no longer fail parsing and preserve permalink filter state for partial recovery.
+ */
+
+// --- test_parse_superset_link_dashboard_permalink_recovers_dataset_from_nested_dashboard_state (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify permalink state with nested dashboard id recovers dataset binding and keeps imported filters.
+ */
+
+// --- test_resolve_from_dictionary_prefers_exact_match (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify trusted dictionary exact matches outrank fuzzy candidates and unresolved fields stay explicit.
+ */
+
+// --- test_orchestrator_start_session_preserves_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify session start persists usable recovery-required state when Superset intake is partial.
+ */
+
+// --- test_orchestrator_start_session_bootstraps_recovery_state (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify session start persists recovered filters, template variables, and initial execution mappings for review workspace bootstrap.
+ */
+
+// --- test_start_session_endpoint_returns_created_summary (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify POST session lifecycle endpoint returns a persisted ownership-scoped summary.
+ */
+
+// --- test_get_session_detail_export_and_lifecycle_endpoints (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify lifecycle get/patch/delete plus documentation and validation exports remain ownership-scoped and usable.
+ */
+
+// --- test_get_clarification_state_returns_empty_payload_when_session_has_no_record (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Clarification state endpoint should return a non-blocking empty payload when the session has no clarification aggregate yet.
+ */
+
+// --- test_us2_clarification_endpoints_persist_answer_and_feedback (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Clarification endpoints should expose one current question, persist the answer before advancement, and store feedback on the answer audit record.
+ */
+
+// --- test_us2_field_semantic_override_lock_unlock_and_feedback (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Semantic field endpoints should apply manual overrides with lock/provenance invariants and persist feedback independently.
+ */
+
+// --- test_us3_mapping_patch_approval_preview_and_launch_endpoints (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief US3 execution endpoints should persist manual overrides, preserve explicit approval semantics, return contract-shaped preview truth, and expose audited launch handoff.
+ */
+
+// --- test_us3_preview_response_propagates_refreshed_session_version_for_launch_follow_up (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Preview response should expose the refreshed session version so the normal preview-then-launch UI flow can satisfy optimistic locking without a forced full reload.
+ */
+
+// --- test_us3_preview_endpoint_returns_failed_preview_without_false_dashboard_not_found_contract_drift (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Preview endpoint should preserve API contract and surface generic upstream preview failures without fabricating dashboard-not-found semantics for non-dashboard 404s.
+ */
+
+// --- test_mutation_endpoints_surface_session_version_conflict_payload (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Dataset review mutation endpoints should return deterministic 409 conflict semantics when optimistic-lock versions are stale.
+ */
+
+// --- test_update_session_surfaces_commit_time_session_version_conflict_payload (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Session lifecycle mutation should return deterministic 409 conflict semantics when commit-time optimistic locking rejects a stale write.
+ */
+
+// --- test_execution_snapshot_includes_recovered_imported_filters_without_template_mapping (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Recovered imported filters with values should flow into preview filter context even when no template variable mapping exists.
+ */
+
+// --- test_execution_snapshot_preserves_mapped_template_variables_and_filter_context (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Mapped template variables should still populate template params while contributing their effective filter context.
+ */
+
+// --- test_execution_snapshot_skips_partial_imported_filters_without_values (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Partial imported filters without raw or normalized values must not emit bogus active preview filters.
+ */
+
+// --- test_us3_launch_endpoint_requires_launch_permission (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Launch endpoint should enforce the contract RBAC permission instead of the generic session-manage permission.
+ */
+
+// --- test_semantic_source_version_propagation_preserves_locked_fields (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Updated semantic source versions should mark unlocked fields reviewable while preserving locked manual values.
+ */
+
+// --- DatasetsApiTests (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Unit tests for datasets API endpoints.
+ * @complexity 3
+ * @invariant Endpoint contracts remain stable for success and validation failure paths.
+ * @layer API
+ */
+
+// --- test_get_datasets_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate successful datasets listing contract for an existing environment.
+ * @post Response matches DatasetsResponse schema
+ * @pre env_id exists
+ * @test GET /api/datasets returns 200 and valid schema
+ */
+
+// --- test_get_datasets_env_not_found (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing returns 404 when the requested environment does not exist.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test GET /api/datasets returns 404 if env_id missing
+ */
+
+// --- test_get_datasets_invalid_pagination (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing rejects invalid pagination parameters with 400 responses.
+ * @post Returns 400 error
+ * @pre page < 1 or page_size > 100
+ * @test GET /api/datasets returns 400 for invalid page/page_size
+ */
+
+// --- test_map_columns_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns request creates an async mapping task and returns its identifier.
+ * @post Returns task_id
+ * @pre Valid env_id, dataset_ids, source_type (sqllab)
+ * @test POST /api/datasets/map-columns creates mapping task
+ */
+
+// --- test_map_columns_invalid_source_type (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects unsupported source types with a 400 contract response.
+ * @post Returns 400 error
+ * @pre source_type is not 'sqllab' or 'xlsx'
+ * @test POST /api/datasets/map-columns returns 400 for invalid source_type
+ */
+
+// --- test_generate_docs_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs request creates an async documentation task and returns its identifier.
+ * @post Returns task_id
+ * @pre Valid env_id, dataset_ids, llm_provider
+ * @test POST /api/datasets/generate-docs creates doc generation task
+ */
+
+// --- test_map_columns_empty_ids (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects empty dataset identifier lists.
+ * @post Returns 400 error
+ * @pre dataset_ids is empty
+ * @test POST /api/datasets/map-columns returns 400 for empty dataset_ids
+ */
+
+// --- test_map_columns_missing_database_id (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects sqllab source without database_id.
+ * @post Returns 400 error
+ * @test POST /api/datasets/map-columns returns 400 for sqllab without database_id
+ */
+
+// --- test_generate_docs_empty_ids (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs rejects empty dataset identifier lists.
+ * @post Returns 400 error
+ * @pre dataset_ids is empty
+ * @test POST /api/datasets/generate-docs returns 400 for empty dataset_ids
+ */
+
+// --- test_generate_docs_env_not_found (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs returns 404 when the requested environment cannot be resolved.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test POST /api/datasets/generate-docs returns 404 for missing env
+ */
+
+// --- test_get_datasets_superset_failure (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing surfaces a 503 contract when Superset access fails.
+ * @post Returns 503 with stable error detail when upstream dataset fetch fails.
+ * @test_edge external_superset_failure -> {status: 503}
+ */
+
+// --- TestGitApi (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief API tests for Git configurations and repository operations.
+ * @complexity 3
+ */
+
+// --- DbMock (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief In-memory session double for git route tests with minimal query/filter persistence semantics.
+ * @complexity 2
+ * @invariant Supports only the SQLAlchemy-like operations exercised by this test module.
+ */
+
+// --- test_get_git_configs_masks_pat (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate listing git configs masks stored PAT values in API-facing responses.
+ */
+
+// --- test_create_git_config_persists_config (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate creating git config persists supplied server attributes in backing session.
+ */
+
+// --- test_update_git_config_modifies_record (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate updating git config modifies mutable fields while preserving masked PAT semantics.
+ */
+
+// --- SingleConfigDbMock (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ */
+
+// --- test_update_git_config_raises_404_if_not_found (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate updating non-existent git config raises HTTP 404 contract response.
+ */
+
+// --- test_delete_git_config_removes_record (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate deleting existing git config removes record and returns success payload.
+ */
+
+// --- test_test_git_config_validates_connection_successfully (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate test-connection endpoint returns success when provider connectivity check passes.
+ */
+
+// --- MockGitService (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ */
+
+// --- test_test_git_config_fails_validation (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate test-connection endpoint raises HTTP 400 when provider connectivity check fails.
+ */
+
+// --- test_list_gitea_repositories_returns_payload (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate gitea repositories endpoint returns normalized list for GITEA provider configs.
+ */
+
+// --- test_list_gitea_repositories_rejects_non_gitea (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate gitea repositories endpoint rejects non-GITEA providers with HTTP 400.
+ */
+
+// --- test_create_remote_repository_creates_provider_repo (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate remote repository creation endpoint maps provider response into normalized payload.
+ */
+
+// --- test_init_repository_initializes_and_saves_binding (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate repository initialization endpoint creates local repo and persists dashboard binding.
+ */
+
+// --- TestGitStatusRoute (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Validate status endpoint behavior for missing and error repository states.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- test_get_repository_status_returns_no_repo_payload_for_missing_repo (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure missing local repository is represented as NO_REPO payload instead of an API error.
+ * @post Route returns a deterministic NO_REPO status payload.
+ * @pre GitService.get_status raises HTTPException(404).
+ */
+
+// --- test_get_repository_status_propagates_non_404_http_exception (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure HTTP exceptions other than 404 are not masked.
+ * @post Raised exception preserves original status and detail.
+ * @pre GitService.get_status raises HTTPException with non-404 status.
+ */
+
+// --- test_get_repository_diff_propagates_http_exception (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure diff endpoint preserves domain HTTP errors from GitService.
+ * @post Endpoint raises same HTTPException values.
+ * @pre GitService.get_diff raises HTTPException.
+ */
+
+// --- test_get_history_wraps_unexpected_error_as_500 (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure non-HTTP exceptions in history endpoint become deterministic 500 errors.
+ * @post Endpoint returns HTTPException with status 500 and route context.
+ * @pre GitService.get_commit_history raises ValueError.
+ */
+
+// --- test_commit_changes_wraps_unexpected_error_as_500 (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure commit endpoint does not leak unexpected errors as 400.
+ * @post Endpoint raises HTTPException(500) with route context.
+ * @pre GitService.commit_changes raises RuntimeError.
+ */
+
+// --- test_get_repository_status_batch_returns_mixed_statuses (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint returns per-dashboard statuses in one response.
+ * @post Returned map includes resolved status for each requested dashboard ID.
+ * @pre Some repositories are missing and some are initialized.
+ */
+
+// --- test_get_repository_status_batch_marks_item_as_error_on_service_failure (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint marks failed items as ERROR without failing entire request.
+ * @post Failed dashboard status is marked as ERROR.
+ * @pre GitService raises non-HTTP exception for one dashboard.
+ */
+
+// --- test_get_repository_status_batch_deduplicates_and_truncates_ids (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint protects server from oversized payloads.
+ * @post Result contains unique IDs up to configured cap.
+ * @pre request includes duplicate IDs and more than MAX_REPOSITORY_STATUS_BATCH entries.
+ */
+
+// --- test_commit_changes_applies_profile_identity_before_commit (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure commit route configures repository identity from profile preferences before commit call.
+ * @post git_service.configure_identity receives resolved identity and commit proceeds.
+ * @pre Profile preference contains git_username/git_email for current user.
+ */
+
+// --- test_pull_changes_applies_profile_identity_before_pull (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure pull route configures repository identity from profile preferences before pull call.
+ * @post git_service.configure_identity receives resolved identity and pull proceeds.
+ * @pre Profile preference contains git_username/git_email for current user.
+ */
+
+// --- test_get_merge_status_returns_service_payload (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure merge status route returns service payload as-is.
+ * @post Route response contains has_unfinished_merge=True.
+ * @pre git_service.get_merge_status returns unfinished merge payload.
+ */
+
+// --- test_resolve_merge_conflicts_passes_resolution_items_to_service (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure merge resolve route forwards parsed resolutions to service.
+ * @post Service receives normalized list and route returns resolved files.
+ * @pre resolve_data has one file strategy.
+ */
+
+// --- test_abort_merge_calls_service_and_returns_result (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure abort route delegates to service.
+ * @post Route returns aborted status.
+ * @pre Service abort_merge returns aborted status.
+ */
+
+// --- test_continue_merge_passes_message_and_returns_commit (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure continue route passes commit message to service.
+ * @post Route returns committed status and hash.
+ * @pre continue_data.message is provided.
+ */
+
+// --- TestMigrationRoutes (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ * @brief Unit tests for migration API route handlers.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- _mock_env (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ */
+
+// --- _make_sync_config_manager (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ */
+
+// --- TestProfileApi (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies profile API route contracts for preference read/update and Superset account lookup.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- mock_profile_route_dependencies (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Provides deterministic dependency overrides for profile route tests.
+ * @post Dependencies are overridden for current test and restored afterward.
+ * @pre App instance is initialized.
+ */
+
+// --- profile_route_deps_fixture (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Pytest fixture wrapper for profile route dependency overrides.
+ * @post Yields overridden dependencies and clears overrides after test.
+ * @pre None.
+ */
+
+// --- _build_preference_response (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Builds stable profile preference response payload for route tests.
+ * @post Returns ProfilePreferenceResponse object with deterministic timestamps.
+ * @pre user_id is provided.
+ */
+
+// --- test_get_profile_preferences_returns_self_payload (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies GET /api/profile/preferences returns stable self-scoped payload.
+ * @post Response status is 200 and payload contains current user preference.
+ * @pre Authenticated user context is available.
+ */
+
+// --- test_patch_profile_preferences_success (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies PATCH /api/profile/preferences persists valid payload through route mapping.
+ * @post Response status is 200 with saved preference payload.
+ * @pre Valid request payload and authenticated user.
+ */
+
+// --- test_patch_profile_preferences_validation_error (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies route maps domain validation failure to HTTP 422 with actionable details.
+ * @post Response status is 422 and includes validation messages.
+ * @pre Service raises ProfileValidationError.
+ */
+
+// --- test_patch_profile_preferences_cross_user_denied (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies route maps domain authorization guard failure to HTTP 403.
+ * @post Response status is 403 with denial message.
+ * @pre Service raises ProfileAuthorizationError.
+ */
+
+// --- test_lookup_superset_accounts_success (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies lookup route returns success payload with normalized candidates.
+ * @post Response status is 200 and items list is returned.
+ * @pre Valid environment_id and service success response.
+ */
+
+// --- test_lookup_superset_accounts_env_not_found (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies lookup route maps missing environment to HTTP 404.
+ * @post Response status is 404 with explicit message.
+ * @pre Service raises EnvironmentNotFoundError.
+ */
+
+// --- TestReportsApi (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Contract tests for GET /api/reports defaults, pagination, and filtering behavior.
+ * @complexity 3
+ * @debt Divergent _FakeTaskManager definition. Canonical version should be in conftest.py. Authz variant is missing get_all_tasks().
+ * @invariant API response contract contains {items,total,page,page_size,has_next,applied_filters}.
+ * @layer Domain
+ */
+
+// --- _make_task (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Build Task fixture with controlled timestamps/status for reports list/detail normalization.
+ */
+
+// --- test_get_reports_default_pagination_contract (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint default pagination and contract keys for mixed task statuses.
+ */
+
+// --- test_get_reports_filter_and_pagination (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint applies task-type/status filters and pagination boundaries.
+ */
+
+// --- test_get_reports_handles_mixed_naive_and_aware_datetimes (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports sorting remains stable when task timestamps mix naive and timezone-aware datetimes.
+ */
+
+// --- test_get_reports_invalid_filter_returns_400 (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint rejects unsupported task type filters with HTTP 400.
+ */
+
+// --- TestReportsDetailApi (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Contract tests for GET /api/reports/{report_id} detail endpoint behavior.
+ * @complexity 3
+ * @debt Divergent _FakeTaskManager definition. Canonical version should be in conftest.py. Authz variant is missing get_all_tasks().
+ * @invariant Detail endpoint tests must keep deterministic assertions for success and not-found contracts.
+ * @layer Domain
+ */
+
+// --- test_get_report_detail_success (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Validate report detail endpoint returns report body with diagnostics and next actions for existing task.
+ */
+
+// --- test_get_report_detail_not_found (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Validate report detail endpoint returns 404 when requested report identifier is absent.
+ */
+
+// --- TestReportsOpenapiConformance (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Validate implemented reports payload shape against OpenAPI-required top-level contract fields.
+ * @complexity 3
+ * @invariant List and detail payloads include required contract keys.
+ * @layer Domain
+ */
+
+// --- _FakeTaskManager (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Minimal task-manager fake exposing static task list for OpenAPI conformance checks.
+ * @complexity 1
+ * @invariant get_all_tasks returns seeded tasks unchanged.
+ */
+
+// --- _admin_user (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Provide admin principal fixture required by reports routes in conformance tests.
+ */
+
+// --- _task (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Construct deterministic task fixture consumed by reports list/detail payload assertions.
+ */
+
+// --- test_reports_list_openapi_required_keys (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Verify reports list endpoint includes all required OpenAPI top-level keys.
+ */
+
+// --- test_reports_detail_openapi_required_keys (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Verify reports detail endpoint returns payload containing the report object key.
+ */
+
+// --- test_tasks_logs_module (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Contract testing for task logs API endpoints.
+ * @complexity 2
+ * @layer Domain
+ * @test_fixture mock_app
+ */
+
+// --- test_get_task_logs_success (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint returns filtered logs for an existing task.
+ */
+
+// --- test_get_task_logs_not_found (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint returns 404 when the task identifier is missing.
+ * @test_edge invalid_limit
+ */
+
+// --- test_get_task_logs_invalid_limit (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint enforces query validation for limit lower bound.
+ */
+
+// --- test_get_task_log_stats_success (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate log stats endpoint returns success payload for an existing task.
+ */
+
+// --- AdminApi (backend/src/api/routes/admin.py)
+/**!
+ * @brief Admin API endpoints for user and role management.
+ * @complexity 5
+ * @invariant All endpoints in this module require 'Admin' role or 'admin' scope.
+ * @layer API
+ */
+
+// --- list_users (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all registered users.
+ * @complexity 3
+ * @post Returns a list of UserSchema objects.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- create_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new local user.
+ * @complexity 3
+ * @post New user is created in the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- update_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Updates an existing user.
+ * @complexity 3
+ * @post User record is updated in the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- delete_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Deletes a user.
+ * @complexity 3
+ * @post User record is removed from the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- list_roles (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all available roles.
+ * @complexity 3
+ */
+
+// --- create_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new system role with associated permissions.
+ * @complexity 3
+ * @post New Role record is created in auth.db.
+ * @pre Role name must be unique.
+ * @side_effect Commits new role and associations to auth.db.
+ */
+
+// --- update_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Updates an existing role's metadata and permissions.
+ * @complexity 3
+ * @post Role record is updated in auth.db.
+ * @pre role_id must be a valid existing role UUID.
+ * @side_effect Commits updates to auth.db.
+ */
+
+// --- delete_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Removes a role from the system.
+ * @complexity 3
+ * @post Role record is removed from auth.db.
+ * @pre role_id must be a valid existing role UUID.
+ * @side_effect Deletes record from auth.db and commits.
+ */
+
+// --- list_ad_mappings (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all AD Group to Role mappings.
+ * @complexity 3
+ */
+
+// --- create_ad_mapping (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new AD Group mapping.
+ * @complexity 2
+ */
+
+// --- AdminApiKeyRoutes (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Admin API endpoints for API key management — list, generate (one-time reveal), and revoke.
+ * @complexity 3
+ * @invariant DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.
+ * @layer API
+ */
+
+// --- ApiKeyCreateRequest (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @complexity 1
+ */
+
+// --- ApiKeyCreateResponse (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @complexity 1
+ */
+
+// --- ApiKeyListItem (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @complexity 1
+ */
+
+// --- ApiKeyRevokeResponse (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @complexity 1
+ */
+
+// --- list_api_keys (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief List all API keys — NEVER returns key_hash or raw_key.
+ * @complexity 2
+ * @post Returns list of ApiKeyListItem without sensitive fields.
+ * @pre Requires admin:settings WRITE permission.
+ */
+
+// --- create_api_key (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Generate a new API key — returns raw key ONCE, never stored or retrievable again.
+ * @complexity 3
+ * @post Creates APIKey row with SHA-256 hash. Returns raw key in response.
+ * @pre Requires admin:settings WRITE permission. name is required, at least one permission.
+ * @side_effect Generates cryptographically random key, stores hash in DB.
+ */
+
+// --- revoke_api_key (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Revoke an API key by setting active=False. Preserves row for audit.
+ * @complexity 2
+ * @post Sets active=False on the key. Returns 404 if already revoked or not found.
+ * @pre Requires admin:settings WRITE permission.
+ */
+
+// --- AssistantAdminRoutes (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief FastAPI route handlers for assistant admin operations — conversation listing, deletion, history, audit.
+ * @complexity 5
+ * @invariant Audit endpoint requires tasks:READ permission.
+ * @layer API
+ */
+
+// --- list_conversations (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Return paginated conversation list for current user with archived flag and last message preview.
+ * @complexity 2
+ * @post Conversations are grouped by conversation_id sorted by latest activity descending.
+ * @pre Authenticated user context and valid pagination params.
+ */
+
+// --- delete_conversation (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Soft-delete or hard-delete a conversation and clear its in-memory trace.
+ * @complexity 2
+ * @post Conversation records are removed from DB and CONVERSATIONS cache.
+ * @pre conversation_id belongs to current_user.
+ */
+
+// --- get_history (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Retrieve paginated assistant conversation history for current user.
+ * @post Returns persistent messages and mirrored in-memory snapshot for diagnostics.
+ * @pre Authenticated user is available and page params are valid.
+ */
+
+// --- get_assistant_audit (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Return assistant audit decisions for current user from persistent and in-memory stores.
+ * @post Audit payload is returned in reverse chronological order from DB.
+ * @pre User has tasks:READ permission.
+ */
+
+// --- AssistantCommandParser (backend/src/api/routes/assistant/_command_parser.py)
+/**!
+ * @brief Deterministic RU/EN command text parser that converts user messages into intent payloads.
+ * @complexity 4
+ * @invariant Every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+ * @layer API
+ */
+
+// --- _parse_command (backend/src/api/routes/assistant/_command_parser.py)
+/**!
+ * @brief Deterministically parse RU/EN command text into intent payload.
+ * @complexity 4
+ * @data_contract Input[message:str, config_manager:ConfigManager] -> Output[Dict[str,Any]{domain,operation,entities,confidence,risk_level,requires_confirmation}]
+ * @invariant every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+ * @post Returns intent dict with domain/operation/entities/confidence/risk fields.
+ * @pre message contains raw user text and config manager resolves environments.
+ * @side_effect None (pure parsing logic).
+ */
+
+// --- AssistantDatasetReview (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Dataset review context loading and intent planning for the assistant API.
+ * @complexity 4
+ * @invariant Dataset review operations are always scoped to the owner's session.
+ * @layer API
+ */
+
+// --- _serialize_dataset_review_context (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Build assistant-safe dataset-review context snapshot with masked imported-filter payloads for session-scoped assistant routing.
+ * @complexity 4
+ * @post Returns a serializable dictionary containing the complete review context.
+ * @pre session_id is a valid active review session identifier.
+ * @side_effect Reads session data from the database.
+ */
+
+// --- _load_dataset_review_context (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Load owner-scoped dataset-review context for assistant planning and grounded response generation.
+ * @complexity 4
+ * @post Returns a loaded context object with session data and findings.
+ * @pre session_id is a valid active review session identifier.
+ * @side_effect Reads session data from the database.
+ */
+
+// --- _extract_dataset_review_target (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Extract structured dataset-review focus target hints embedded in assistant prompts.
+ * @complexity 2
+ */
+
+// --- _match_dataset_review_field (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Resolve one semantic field from assistant-visible context by id or user-visible label.
+ * @complexity 2
+ */
+
+// --- _extract_quoted_segment (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Extract one quoted assistant command segment after a label token.
+ * @complexity 2
+ */
+
+// --- _plan_dataset_review_intent (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Parse session-scoped dataset-review assistant commands before falling back to generic assistant tool routing.
+ * @complexity 3
+ */
+
+// --- AssistantDatasetReviewDispatch (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Dispatch and confirmation handling for dataset-review assistant intents.
+ * @complexity 4
+ * @invariant Dataset review dispatch requires valid session version for write operations.
+ * @layer API
+ */
+
+// --- _dataset_review_conflict_http_exception (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Convert dataset-review optimistic-lock conflicts into shared 409 assistant semantics.
+ * @complexity 2
+ */
+
+// --- _dispatch_dataset_review_intent (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Route confirmed dataset-review assistant intents through existing backend dataset-review APIs and orchestration boundaries.
+ * @complexity 4
+ * @post Returns a structured response with planned actions and confirmations.
+ * @pre context contains valid session data and user intent.
+ * @side_effect May update session state and enqueue tasks.
+ */
+
+// --- AssistantDispatch (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Intent dispatch engine, confirmation summary, and clarification text for the assistant API.
+ * @complexity 5
+ * @invariant Unsupported operations are rejected via HTTPException(400).
+ * @layer API
+ */
+
+// --- _clarification_text_for_intent (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Convert technical missing-parameter errors into user-facing clarification prompts.
+ * @complexity 2
+ * @post Returned text is human-readable and actionable for target operation.
+ * @pre state was classified as needs_clarification for current intent/error combination.
+ */
+
+// --- _async_confirmation_summary (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Build human-readable confirmation prompt for an intent before execution.
+ * @complexity 4
+ * @post Returns a formatted summary string suitable for display to the user.
+ * @pre actions is a non-empty list of planned review actions.
+ * @side_effect None - pure formatting function.
+ */
+
+// --- _dispatch_intent (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Execute parsed assistant intent via existing task/plugin/git services.
+ * @complexity 5
+ * @data_contract Input[intent,current_user,task_manager,config_manager,db] -> Output[Tuple[text:str,task_id:Optional[str],actions:List[AssistantAction]]]
+ * @invariant unsupported operations are rejected via HTTPException(400).
+ * @post Returns response text, optional task id, and UI actions for follow-up.
+ * @pre intent operation is known and actor permissions are validated per operation.
+ * @side_effect May enqueue tasks, invoke git operations, and query/update external service state.
+ */
+
+// --- AssistantHistory (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Conversation history, audit trail, and confirmation persistence helpers for the assistant API.
+ * @complexity 2
+ * @invariant Failed persistence attempts always rollback before returning.
+ * @layer API
+ */
+
+// --- _append_history (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Append conversation message to in-memory history buffer.
+ * @complexity 2
+ * @data_contract Input[user_id,conversation_id,role,text,state?,task_id?,confirmation_id?] -> Output[None]
+ * @invariant every appended entry includes generated message_id and created_at timestamp.
+ * @post Message entry is appended to CONVERSATIONS key list.
+ * @pre user_id and conversation_id identify target conversation bucket.
+ * @side_effect Mutates in-memory CONVERSATIONS store for user conversation history.
+ */
+
+// --- _persist_message (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist assistant/user message record to database.
+ * @complexity 2
+ * @data_contract Input[Session,user_id,conversation_id,role,text,state?,task_id?,confirmation_id?,metadata?] -> Output[None]
+ * @invariant failed persistence attempts always rollback before returning.
+ * @post Message row is committed or persistence failure is logged.
+ * @pre db session is writable and message payload is serializable.
+ * @side_effect Writes AssistantMessageRecord rows and commits or rollbacks the DB session.
+ */
+
+// --- _audit (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Append in-memory audit record for assistant decision trace.
+ * @complexity 2
+ * @data_contract Input[user_id,payload:Dict[str,Any]] -> Output[None]
+ * @invariant persisted in-memory audit entry always contains created_at in ISO format.
+ * @post ASSISTANT_AUDIT list for user contains new timestamped entry.
+ * @pre payload describes decision/outcome fields.
+ * @side_effect Mutates in-memory ASSISTANT_AUDIT store and emits structured log event.
+ */
+
+// --- _persist_audit (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist structured assistant audit payload in database.
+ * @complexity 2
+ * @post Audit row is committed or failure is logged with rollback.
+ * @pre db session is writable and payload is JSON-serializable.
+ */
+
+// --- _persist_confirmation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist confirmation token record to database.
+ * @complexity 2
+ * @post Confirmation row exists in persistent storage.
+ * @pre record contains id/user/intent/dispatch/expiry fields.
+ */
+
+// --- _update_confirmation_state (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Update persistent confirmation token lifecycle state.
+ * @complexity 2
+ * @post State and consumed_at fields are updated when applicable.
+ * @pre confirmation_id references existing row.
+ */
+
+// --- _load_confirmation_from_db (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Load confirmation token from database into in-memory model.
+ * @complexity 2
+ * @post Returns ConfirmationRecord when found, otherwise None.
+ * @pre confirmation_id may or may not exist in storage.
+ */
+
+// --- _ensure_conversation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Resolve active conversation id in memory or create a new one.
+ * @complexity 2
+ * @post Returns stable conversation id and updates USER_ACTIVE_CONVERSATION.
+ * @pre user_id identifies current actor.
+ */
+
+// --- _resolve_or_create_conversation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Resolve active conversation using explicit id, memory cache, or persisted history.
+ * @complexity 2
+ * @post Returns conversation id and updates USER_ACTIVE_CONVERSATION cache.
+ * @pre user_id and db session are available.
+ */
+
+// --- _cleanup_history_ttl (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Enforce assistant message retention window by deleting expired rows and in-memory records.
+ * @complexity 2
+ * @post Messages older than ASSISTANT_MESSAGE_TTL_DAYS are removed from persistence and memory mirrors.
+ * @pre db session is available and user_id references current actor scope.
+ */
+
+// --- _is_conversation_archived (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Determine archived state for a conversation based on last update timestamp.
+ * @complexity 2
+ * @post Returns True when conversation inactivity exceeds archive threshold.
+ * @pre updated_at can be null for empty conversations.
+ */
+
+// --- _coerce_query_bool (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Normalize bool-like query values for compatibility in direct handler invocations/tests.
+ * @complexity 2
+ * @post Returns deterministic boolean flag.
+ * @pre value may be bool, string, or FastAPI Query metadata object.
+ */
+
+// --- AssistantLlmPlanner (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief LLM-based intent planning, tool catalog construction, and authorization for the assistant API.
+ * @complexity 5
+ * @data_contract UserPermissions -> ToolCatalog
+ * @invariant Tool catalog is filtered by user permissions before being sent to LLM.
+ * @layer API
+ * @post LLM tool catalog filtered and returned
+ * @pre Assistant routes initialized, user authenticated
+ * @side_effect Filters tool catalog by user permissions
+ */
+
+// --- _check_any_permission (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Validate user against alternative permission checks (logical OR).
+ * @complexity 2
+ * @post Returns on first successful permission; raises 403-like HTTPException otherwise.
+ * @pre checks list contains resource-action tuples.
+ */
+
+// --- _has_any_permission (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Check whether user has at least one permission tuple from the provided list.
+ * @complexity 2
+ * @post Returns True when at least one permission check passes.
+ * @pre current_user and checks list are valid.
+ */
+
+// --- _build_tool_catalog (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Build current-user tool catalog for LLM planner with operation contracts and defaults.
+ * @complexity 3
+ * @post Returns list of executable tools filtered by permission and runtime availability.
+ * @pre current_user is authenticated; config/db are available.
+ */
+
+// --- _coerce_intent_entities (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Normalize intent entity value types from LLM output to route-compatible values.
+ * @complexity 2
+ * @post Returned intent has numeric ids coerced where possible and string values stripped.
+ * @pre intent contains entities dict or missing entities.
+ */
+
+// --- AssistantLlmPlannerIntent (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief LLM-based intent planning and authorization for the assistant API — separated from tool catalog.
+ * @complexity 5
+ * @data_contract UserIntent -> PlannedAction
+ * @invariant Production deployments always require confirmation.
+ * @layer API
+ * @post Intent planning registered with confirmation gate
+ * @pre Assistant routes initialized, user authenticated
+ * @side_effect Registers intent planning routes
+ */
+
+// --- _plan_intent_with_llm (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief Use active LLM provider to select best tool/operation from dynamic catalog.
+ * @complexity 2
+ * @post Returns normalized intent dict when planning succeeds; otherwise None.
+ * @pre tools list contains allowed operations for current user.
+ */
+
+// --- _authorize_intent (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief Validate user permissions for parsed intent before confirmation/dispatch.
+ * @complexity 2
+ * @post Returns if authorized; raises HTTPException(403) when denied.
+ * @pre intent.operation is present for known assistant command domains.
+ */
+
+// --- AssistantResolvers (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Environment, dashboard, provider, and task resolution utilities for the assistant API.
+ * @complexity 2
+ * @invariant Resolution functions never raise; they return None on failure.
+ * @layer API
+ */
+
+// --- _extract_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Extract first regex match group from text by ordered pattern list.
+ * @complexity 2
+ * @post Returns first matched token or None.
+ * @pre patterns contain at least one capture group.
+ */
+
+// --- _resolve_env_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve environment identifier/name token to canonical environment id.
+ * @complexity 2
+ * @post Returns matched environment id or None.
+ * @pre config_manager provides environment list.
+ */
+
+// --- _is_production_env (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Determine whether environment token resolves to production-like target.
+ * @complexity 2
+ * @post Returns True for production/prod synonyms, else False.
+ * @pre config_manager provides environments or token text is provided.
+ */
+
+// --- _resolve_provider_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve provider token to provider id with active/default fallback.
+ * @complexity 2
+ * @post Returns provider id or None when no providers configured.
+ * @pre db session can load provider list through LLMProviderService.
+ */
+
+// --- _get_default_environment_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve default environment id from settings or first configured environment.
+ * @complexity 2
+ * @post Returns default environment id or None when environment list is empty.
+ * @pre config_manager returns environments list.
+ */
+
+// --- _resolve_dashboard_id_by_ref (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve dashboard id by title or slug reference in selected environment.
+ * @complexity 2
+ * @post Returns dashboard id when uniquely matched, otherwise None.
+ * @pre dashboard_ref is a non-empty string-like token.
+ */
+
+// --- _resolve_dashboard_id_entity (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve dashboard id from intent entities using numeric id or dashboard_ref fallback.
+ * @complexity 2
+ * @post Returns resolved dashboard id or None when ambiguous/unresolvable.
+ * @pre entities may contain dashboard_id as int/str and optional dashboard_ref.
+ */
+
+// --- _get_environment_name_by_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve human-readable environment name by id.
+ * @complexity 2
+ * @post Returns matching environment name or fallback id.
+ * @pre environment id may be None.
+ */
+
+// --- _extract_result_deep_links (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Build deep-link actions to verify task result from assistant chat.
+ * @complexity 2
+ * @post Returns zero or more assistant actions for dashboard open/diff.
+ * @pre task object is available.
+ */
+
+// --- _build_task_observability_summary (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Build compact textual summary for completed tasks to reduce "black box" effect.
+ * @complexity 2
+ * @post Returns non-empty summary line for known task types or empty string fallback.
+ * @pre task may contain plugin-specific result payload.
+ */
+
+// --- AssistantRoutes (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief FastAPI route handlers for the assistant API — message sending, confirmation, conversation management.
+ * @complexity 5
+ * @invariant Risky operations are never executed without valid confirmation token.
+ * @layer API
+ */
+
+// --- send_message (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Parse assistant command, enforce safety gates, and dispatch executable intent.
+ * @complexity 5
+ * @data_contract Input[AssistantMessageRequest,User,TaskManager,ConfigManager,Session] -> Output[AssistantMessageResponse]
+ * @invariant non-safe operations are gated with confirmation before execution from this endpoint.
+ * @post Response state is one of clarification/confirmation/started/success/denied/failed.
+ * @pre Authenticated user is available and message text is non-empty.
+ * @side_effect Persists chat/audit state, mutates in-memory conversation and confirmation stores, and may create confirmation records.
+ */
+
+// --- confirm_operation (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Execute previously requested risky operation after explicit user confirmation.
+ * @complexity 2
+ * @post Confirmation state becomes consumed and operation result is persisted in history.
+ * @pre confirmation_id exists, belongs to current user, is pending, and not expired.
+ */
+
+// --- cancel_operation (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Cancel pending risky operation and mark confirmation token as cancelled.
+ * @complexity 2
+ * @post Confirmation becomes cancelled and cannot be executed anymore.
+ * @pre confirmation_id exists, belongs to current user, and is still pending.
+ */
+
+// --- AssistantSchemas (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Pydantic models, in-memory stores, and permission mappings for the assistant API.
+ * @complexity 2
+ * @invariant In-memory stores are module-level singletons shared across the assistant package.
+ * @layer API
+ * @rationale In-memory stores documented with NOTE about restart loss. ASSISTANT_ARCHIVE_AFTER_DAYS and ASSISTANT_MESSAGE_TTL_DAYS kept as module-level constants with TODO for config migration — Pydantic schemas module should not depend on ConfigManager for architectural purity.
+ */
+
+// --- AssistantMessageRequest (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Input payload for assistant message endpoint.
+ * @complexity 1
+ * @data_contract Input[conversation_id?:str, message:str(1..4000)] -> Output[AssistantMessageRequest]
+ * @invariant message is always non-empty and no longer than 4000 characters.
+ * @post Request object provides message text and optional conversation binding.
+ * @pre message length is within accepted bounds.
+ * @side_effect None (schema declaration only).
+ */
+
+// --- AssistantAction (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief UI action descriptor returned with assistant responses.
+ * @complexity 1
+ * @data_contract Input[type:str, label:str, target?:str] -> Output[AssistantAction]
+ * @invariant type and label are required for every UI action.
+ * @post Action can be rendered as button on frontend.
+ * @pre type and label are provided by orchestration logic.
+ * @side_effect None (schema declaration only).
+ */
+
+// --- AssistantMessageResponse (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Output payload contract for assistant interaction endpoints.
+ * @complexity 1
+ * @data_contract Input[conversation_id,response_id,state,text,intent?,confirmation_id?,task_id?,actions[],created_at] -> Output[AssistantMessageResponse]
+ * @invariant created_at and state are always present in endpoint responses.
+ * @post Payload may include task_id/confirmation_id/actions for UI follow-up.
+ * @pre Response includes deterministic state and text.
+ * @side_effect None (schema declaration only).
+ */
+
+// --- ConfirmationRecord (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory confirmation token model for risky operation dispatch.
+ * @complexity 1
+ * @data_contract Input[id,user_id,conversation_id,intent,dispatch,expires_at,state?,created_at] -> Output[ConfirmationRecord]
+ * @invariant state defaults to "pending" and expires_at bounds confirmation validity.
+ * @post Record tracks lifecycle state and expiry timestamp.
+ * @pre intent/dispatch/user_id are populated at confirmation request time.
+ * @side_effect None (schema declaration only).
+ */
+
+// --- CONVERSATIONS (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}
+ * @complexity 1
+ */
+
+// --- ASSISTANT_AUDIT (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.
+ * @complexity 1
+ */
+
+// --- CleanReleaseApi (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Expose clean release endpoints for candidate preparation and subsequent compliance flow.
+ * @complexity 4
+ * @invariant API never reports prepared status if preparation errors are present.
+ * @layer API
+ * @post Candidate preparation, manifest, and compliance routes expose deterministic API payloads without reporting prepared state on failed preparation.
+ * @pre Clean release repository and preparation service dependencies are configured for the current request scope.
+ * @side_effect Persists candidate/compliance lifecycle state and triggers clean-release orchestration services.
+ */
+
+// --- PrepareCandidateRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate preparation endpoint.
+ */
+
+// --- StartCheckRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for clean compliance check run startup.
+ */
+
+// --- RegisterCandidateRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate registration endpoint.
+ */
+
+// --- ImportArtifactsRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate artifact import endpoint.
+ */
+
+// --- BuildManifestRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for manifest build endpoint.
+ */
+
+// --- CreateComplianceRunRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for compliance run creation with optional manifest pinning.
+ */
+
+// --- register_candidate_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Register a clean-release candidate for headless lifecycle.
+ * @post Candidate is persisted in DRAFT status.
+ * @pre Candidate identifier is unique.
+ */
+
+// --- import_candidate_artifacts_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Import candidate artifacts in headless flow.
+ * @post Artifacts are persisted and candidate advances to PREPARED if it was DRAFT.
+ * @pre Candidate exists and artifacts array is non-empty.
+ */
+
+// --- build_candidate_manifest_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Build immutable manifest snapshot for prepared candidate.
+ * @post Returns created ManifestDTO with incremented version.
+ * @pre Candidate exists and has imported artifacts.
+ */
+
+// --- get_candidate_overview_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return expanded candidate overview DTO for headless lifecycle visibility.
+ * @post Returns CandidateOverviewDTO built from the same repository state used by headless US1 endpoints.
+ * @pre Candidate exists.
+ */
+
+// --- prepare_candidate_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Prepare candidate with policy evaluation and deterministic manifest generation.
+ * @post Returns preparation result including manifest reference and violations.
+ * @pre Candidate and active policy exist in repository.
+ */
+
+// --- start_check (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Start and finalize a clean compliance check run and persist report artifacts.
+ * @post Returns accepted payload with check_run_id and started_at.
+ * @pre Active policy and candidate exist.
+ */
+
+// --- get_check_status (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return terminal/intermediate status payload for a check run.
+ * @post Deterministic payload shape includes checks and violations arrays.
+ * @pre check_run_id references an existing run.
+ */
+
+// --- get_report (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return persisted compliance report by report_id.
+ * @post Returns serialized report object.
+ * @pre report_id references an existing report.
+ */
+
+// --- CleanReleaseV2Api (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Redesigned clean release API for headless candidate lifecycle.
+ * @complexity 4
+ * @layer API
+ * @post Candidate registration, approval, publication, and revocation routes are registered without behavior changes.
+ * @pre Clean release repository dependency is available for candidate lifecycle endpoints.
+ * @side_effect Persists candidate lifecycle state through clean release services and repository adapters.
+ */
+
+// --- ApprovalRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for approval request payload.
+ * @complexity 1
+ */
+
+// --- PublishRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for publication request payload.
+ * @complexity 1
+ */
+
+// --- RevokeRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for revocation request payload.
+ * @complexity 1
+ */
+
+// --- register_candidate (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Register a new release candidate.
+ * @complexity 3
+ * @post Candidate is saved in repository.
+ * @pre Payload contains required fields (id, version, source_snapshot_ref, created_by).
+ */
+
+// --- import_artifacts (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Associate artifacts with a release candidate.
+ * @complexity 3
+ * @post Artifacts are processed (placeholder).
+ * @pre Candidate exists.
+ */
+
+// --- build_manifest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Generate distribution manifest for a candidate.
+ * @complexity 3
+ * @post Manifest is created and saved.
+ * @pre Candidate exists.
+ */
+
+// --- approve_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to record candidate approval.
+ * @complexity 3
+ */
+
+// --- reject_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to record candidate rejection.
+ * @complexity 3
+ */
+
+// --- publish_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to publish an approved candidate.
+ * @complexity 3
+ */
+
+// --- revoke_publication_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to revoke a previous publication.
+ * @complexity 3
+ */
+
+// --- DashboardsApi (backend/src/api/routes/dashboards/__init__.py)
+/**!
+ * @brief API endpoints for the Dashboard Hub - listing dashboards with Git and task status
+ * @complexity 5
+ * @data_contract Input(env_id, filters) -> Output(DashboardsResponse)
+ * @invariant All dashboard responses include git_status and last_task metadata
+ * @layer API
+ * @post Dashboard responses are projected into DashboardsResponse DTO.
+ * @pre Valid environment configurations exist in ConfigManager.
+ * @side_effect Performs external calls to Superset API and potentially Git providers.
+ * @test_contract DashboardsAPI -> {
+ */
+
+// --- DashboardActionRoutes (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Dashboard action route handlers — migrate, backup.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- migrate_dashboards (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Trigger bulk migration of dashboards from source to target environment
+ * @complexity 2
+ * @post Task is created and queued for execution
+ * @pre dashboard_ids is a non-empty list
+ */
+
+// --- backup_dashboards (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Trigger bulk backup of dashboards with optional cron schedule
+ * @complexity 2
+ * @post If schedule is provided, a scheduled task is created
+ * @pre dashboard_ids is a non-empty list
+ */
+
+// --- DashboardDetailRoutes (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Dashboard detail, db-mappings, task history, thumbnail route handlers.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- get_database_mappings (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Get database mapping suggestions between source and target environments
+ * @complexity 2
+ * @post Returns list of suggested database mappings with confidence scores
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- get_dashboard_detail (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Fetch detailed dashboard info with related charts and datasets
+ * @complexity 2
+ * @post Returns dashboard detail payload for overview page
+ * @pre env_id must be valid and dashboard ref (slug or id) must exist
+ */
+
+// --- get_dashboard_tasks_history (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Returns history of backup and LLM validation tasks for a dashboard.
+ * @complexity 2
+ * @post Response contains sorted task history (newest first).
+ * @pre dashboard ref (slug or id) is valid.
+ */
+
+// --- get_dashboard_thumbnail (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Proxies Superset dashboard thumbnail with cache support.
+ * @complexity 3
+ * @post Returns image bytes or 202 when thumbnail is being prepared by Superset.
+ * @pre env_id must exist.
+ */
+
+// --- DashboardHelpers (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Basic helper functions for dashboard route handlers — slug resolution, filter normalization.
+ * @complexity 2
+ * @layer Infrastructure
+ */
+
+// --- _find_dashboard_id_by_slug (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard numeric ID by slug using Superset list endpoint.
+ * @complexity 2
+ * @post Returns dashboard ID when found, otherwise None.
+ * @pre `dashboard_slug` is non-empty.
+ */
+
+// --- _resolve_dashboard_id_from_ref (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard ID from slug-first reference with numeric fallback.
+ * @complexity 2
+ * @post Returns a valid dashboard ID or raises HTTPException(404).
+ * @pre `dashboard_ref` is provided in route path.
+ */
+
+// --- _find_dashboard_id_by_slug_async (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard numeric ID by slug using async Superset list endpoint.
+ * @complexity 2
+ * @post Returns dashboard ID when found, otherwise None.
+ * @pre dashboard_slug is non-empty.
+ */
+
+// --- _resolve_dashboard_id_from_ref_async (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard ID from slug-first reference using async Superset client.
+ * @complexity 2
+ * @post Returns valid dashboard ID or raises HTTPException(404).
+ * @pre dashboard_ref is provided in route path.
+ */
+
+// --- _normalize_filter_values (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Normalize query filter values to lower-cased non-empty tokens.
+ * @complexity 2
+ * @post Returns trimmed normalized list preserving input order.
+ * @pre values may be None or list of strings.
+ */
+
+// --- _dashboard_git_filter_value (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Build comparable git status token for dashboards filtering.
+ * @complexity 2
+ * @post Returns one of ok|diff|no_repo|error|pending.
+ * @pre dashboard payload may contain git_status or None.
+ */
+
+// --- DashboardListingRoutes (backend/src/api/routes/dashboards/_listing_routes.py)
+/**!
+ * @brief Dashboard listing route handler for Dashboard Hub.
+ * @complexity 4
+ * @layer API
+ */
+
+// --- get_dashboards (backend/src/api/routes/dashboards/_listing_routes.py)
+/**!
+ * @brief Fetch list of dashboards from a specific environment with Git status and last task status
+ * @complexity 3
+ * @post Response includes effective profile filter metadata for main dashboards page context
+ * @pre page_size must be between 1 and 100 if provided
+ */
+
+// --- DashboardProjection (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Dashboard response projection and profile-filter helpers for Dashboard Hub routes.
+ * @complexity 2
+ * @layer Infrastructure
+ */
+
+// --- _normalize_actor_alias_token (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Normalize actor alias token to comparable trim+lower text.
+ * @complexity 2
+ */
+
+// --- _normalize_owner_display_token (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Project owner payload value into stable display string for API response contracts.
+ * @complexity 2
+ */
+
+// --- _normalize_dashboard_owner_values (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Normalize dashboard owners payload to optional list of display strings.
+ * @complexity 2
+ */
+
+// --- _project_dashboard_response_items (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Project dashboard payloads to response-contract-safe shape.
+ * @complexity 2
+ */
+
+// --- _get_profile_filter_binding (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Resolve dashboard profile-filter binding through current or legacy profile service contracts.
+ * @complexity 2
+ */
+
+// --- _resolve_profile_actor_aliases (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Resolve stable actor aliases for profile filtering without per-dashboard detail fan-out.
+ * @complexity 2
+ * @side_effect Performs at most one Superset users-lookup request.
+ */
+
+// --- _matches_dashboard_actor_aliases (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Apply profile actor matching against multiple aliases (username + optional display name).
+ * @complexity 2
+ */
+
+// --- _task_matches_dashboard (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Checks whether task params are tied to a specific dashboard and environment.
+ * @complexity 2
+ */
+
+// --- DashboardsRouter (backend/src/api/routes/dashboards/_router.py)
+/**!
+ * @brief Single APIRouter instance for all dashboard endpoints.
+ * @complexity 1
+ */
+
+// --- DashboardSchemas (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO classes for the Dashboard Hub API.
+ * @complexity 1
+ * @layer Infrastructure
+ */
+
+// --- GitStatus (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard Git synchronization status.
+ * @complexity 1
+ */
+
+// --- DashboardItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO representing a single dashboard with projected metadata.
+ * @complexity 1
+ */
+
+// --- EffectiveProfileFilter (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Metadata about applied profile filters for UI context.
+ * @complexity 1
+ */
+
+// --- DashboardsResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Envelope DTO for paginated dashboards list.
+ * @complexity 1
+ */
+
+// --- DashboardChartItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for a chart linked to a dashboard.
+ * @complexity 1
+ */
+
+// --- DashboardDatasetItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for a dataset associated with a dashboard.
+ * @complexity 1
+ */
+
+// --- DashboardDetailResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Detailed dashboard metadata including children.
+ * @complexity 1
+ */
+
+// --- DashboardTaskHistoryItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Individual history record entry.
+ * @complexity 1
+ */
+
+// --- DashboardTaskHistoryResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Collection DTO for task history.
+ * @complexity 1
+ */
+
+// --- DatabaseMapping (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for cross-environment database ID mapping.
+ * @complexity 2
+ */
+
+// --- DatabaseMappingsResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Wrapper for database mappings.
+ * @complexity 1
+ */
+
+// --- MigrateRequest (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard migration requests.
+ * @complexity 1
+ */
+
+// --- BackupRequest (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard backup requests.
+ * @complexity 1
+ */
+
+// --- DatasetReviewDependencies (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Dependency injection, serialization helpers, and feature-flag guards for dataset review endpoints.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- StartSessionRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for starting one dataset review session.
+ * @complexity 1
+ */
+
+// --- UpdateSessionRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for lifecycle state updates on an existing session.
+ * @complexity 1
+ */
+
+// --- SessionCollectionResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Paginated session collection response.
+ * @complexity 1
+ */
+
+// --- ExportArtifactResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Inline export response for documentation or validation outputs.
+ * @complexity 1
+ */
+
+// --- FieldSemanticUpdateRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for field-level semantic candidate acceptance or manual override.
+ * @complexity 1
+ */
+
+// --- FeedbackRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for thumbs up/down feedback.
+ * @complexity 1
+ */
+
+// --- ClarificationAnswerRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for submitting one clarification answer.
+ * @complexity 1
+ */
+
+// --- ClarificationSessionSummaryResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Summary DTO for current clarification session state.
+ * @complexity 1
+ */
+
+// --- ClarificationStateResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Response DTO for current clarification state and active question payload.
+ * @complexity 1
+ */
+
+// --- ClarificationAnswerResultResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Response DTO for one clarification answer mutation result.
+ * @complexity 1
+ */
+
+// --- FeedbackResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Minimal response DTO for persisted AI feedback actions.
+ * @complexity 1
+ */
+
+// --- ApproveMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Optional request DTO for explicit mapping approval audit notes.
+ * @complexity 1
+ */
+
+// --- BatchApproveSemanticItemRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for one batch semantic-approval item.
+ * @complexity 1
+ */
+
+// --- BatchApproveSemanticRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for explicit batch semantic approvals.
+ * @complexity 1
+ */
+
+// --- BatchApproveMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for explicit batch mapping approvals.
+ * @complexity 1
+ */
+
+// --- PreviewEnqueueResultResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Async preview trigger response exposing only enqueue state.
+ * @complexity 1
+ */
+
+// --- MappingCollectionResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Wrapper for execution mapping list responses.
+ * @complexity 1
+ */
+
+// --- UpdateExecutionMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for one manual execution-mapping override update.
+ * @complexity 1
+ */
+
+// --- LaunchDatasetResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Launch result exposing audited run context and SQL Lab redirect target.
+ * @complexity 1
+ */
+
+// --- _require_auto_review_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard US1 dataset review endpoints behind the configured feature flag.
+ * @complexity 2
+ */
+
+// --- _require_clarification_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard clarification-specific US2 endpoints behind the configured feature flag.
+ * @complexity 2
+ */
+
+// --- _require_execution_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard US3 execution endpoints behind the configured feature flag.
+ * @complexity 2
+ */
+
+// --- _get_repository (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build repository dependency.
+ * @complexity 1
+ */
+
+// --- _get_orchestrator (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build orchestrator dependency.
+ * @complexity 1
+ */
+
+// --- _get_clarification_engine (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build clarification engine dependency.
+ * @complexity 1
+ */
+
+// --- _serialize_session_summary (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map session aggregate into stable API summary DTO.
+ * @complexity 1
+ */
+
+// --- _serialize_session_detail (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map session aggregate into stable API detail DTO.
+ * @complexity 1
+ */
+
+// --- _require_session_version_header (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Read the optimistic-lock session version header.
+ * @complexity 1
+ */
+
+// --- _build_session_version_conflict_http_exception (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Normalize optimistic-lock conflict errors into HTTP 409 responses.
+ * @complexity 1
+ */
+
+// --- _enforce_session_version (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert repository optimistic-lock conflicts into deterministic HTTP 409 responses.
+ * @complexity 3
+ */
+
+// --- _get_owned_session_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve one session for current user or collaborator scope, returning 404 when inaccessible.
+ * @complexity 3
+ */
+
+// --- _require_owner_mutation_scope (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Enforce owner-only mutation scope.
+ * @complexity 2
+ */
+
+// --- _prepare_owned_session_mutation (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve owner-scoped mutation session and enforce optimistic-lock version.
+ * @complexity 3
+ */
+
+// --- _commit_owned_session_mutation (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Centralize session version bumping and commit semantics.
+ * @complexity 3
+ */
+
+// --- _record_session_event (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Persist one explicit audit event for an owned mutation endpoint.
+ * @complexity 1
+ */
+
+// --- _serialize_semantic_field (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one semantic field into stable DTO.
+ * @complexity 1
+ */
+
+// --- _serialize_execution_mapping (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one execution mapping into stable DTO.
+ * @complexity 1
+ */
+
+// --- _serialize_preview (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one preview into stable DTO.
+ * @complexity 1
+ */
+
+// --- _serialize_run_context (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one run context into stable DTO.
+ * @complexity 1
+ */
+
+// --- _serialize_clarification_question_payload (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert clarification engine payload into API DTO.
+ * @complexity 1
+ */
+
+// --- _serialize_clarification_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert clarification engine state into API response.
+ * @complexity 1
+ */
+
+// --- _serialize_empty_clarification_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Return empty clarification payload.
+ * @complexity 1
+ */
+
+// --- _get_latest_clarification_session_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve the latest clarification aggregate or raise.
+ * @complexity 1
+ */
+
+// --- _get_owned_mapping_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve one execution mapping inside one owned session.
+ * @complexity 2
+ */
+
+// --- _get_owned_field_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve a semantic field inside one owned session.
+ * @complexity 2
+ */
+
+// --- _map_candidate_provenance (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Translate accepted semantic candidate type into stable field provenance.
+ * @complexity 1
+ */
+
+// --- _resolve_candidate_source_version (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve the semantic source version for one accepted candidate.
+ * @complexity 1
+ */
+
+// --- _update_semantic_field_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Apply field-level semantic manual override or candidate acceptance.
+ * @complexity 3
+ * @post Manual overrides always set manual provenance plus lock.
+ */
+
+// --- _build_sql_lab_redirect_url (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build SQL Lab redirect URL.
+ * @complexity 1
+ */
+
+// --- _build_documentation_export (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Produce session documentation export content.
+ * @complexity 2
+ */
+
+// --- _build_validation_export (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Produce validation-focused export content.
+ * @complexity 2
+ */
+
+// --- DatasetReviewRoutes (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for clarification question/answer content.
+ * @complexity 3
+ */
+
+// --- list_sessions (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief List resumable dataset review sessions for the current user.
+ * @complexity 3
+ */
+
+// --- start_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Start a new dataset review session from a Superset link or dataset selection.
+ * @complexity 4
+ */
+
+// --- get_session_detail (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the full accessible dataset review session aggregate.
+ * @complexity 3
+ */
+
+// --- update_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Update resumable lifecycle status for an owned session.
+ * @complexity 3
+ */
+
+// --- delete_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Archive or hard-delete a session owned by the current user.
+ * @complexity 3
+ */
+
+// --- export_documentation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Export documentation output for the current session.
+ * @complexity 3
+ */
+
+// --- export_validation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Export validation findings for the current session.
+ * @complexity 3
+ */
+
+// --- get_clarification_state (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the current clarification session summary and active question payload.
+ * @complexity 3
+ */
+
+// --- resume_clarification (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Resume clarification mode on the highest-priority unresolved question.
+ * @complexity 3
+ */
+
+// --- record_clarification_answer (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist one clarification answer before advancing the active pointer.
+ * @complexity 3
+ */
+
+// --- update_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Apply one field-level semantic candidate decision or manual override.
+ * @complexity 3
+ */
+
+// --- lock_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Lock one semantic field against later automatic overwrite.
+ * @complexity 3
+ */
+
+// --- unlock_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Unlock one semantic field so later automated candidate application may replace it.
+ * @complexity 3
+ */
+
+// --- approve_batch_semantic_fields (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Approve multiple semantic candidate decisions in one batch.
+ * @complexity 3
+ */
+
+// --- list_execution_mappings (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the current mapping-review set for one accessible session.
+ * @complexity 3
+ */
+
+// --- update_execution_mapping (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist one owner-authorized execution-mapping effective value override.
+ * @complexity 3
+ */
+
+// --- approve_execution_mapping (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Explicitly approve a warning-sensitive mapping transformation.
+ * @complexity 3
+ */
+
+// --- approve_batch_execution_mappings (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Approve multiple warning-sensitive execution mappings in one batch.
+ * @complexity 3
+ */
+
+// --- trigger_preview_generation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Trigger Superset-side preview compilation for the current owned execution context.
+ * @complexity 3
+ */
+
+// --- launch_dataset (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Execute the current owned session launch handoff and return audited SQL Lab run context.
+ * @complexity 3
+ */
+
+// --- record_field_feedback (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for AI-assisted semantic field content.
+ * @complexity 3
+ */
+
+// --- record_clarification_feedback (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for clarification question/answer content.
+ * @complexity 3
+ */
+
+// --- DatasetsApi (backend/src/api/routes/datasets.py)
+/**!
+ * @brief API endpoints for the Dataset Hub - listing datasets with mapping progress
+ * @complexity 5
+ * @data_contract Input -> DatasetQuery, Output -> DatasetsResponse, DatasetDetailResponse
+ * @invariant All dataset responses include last_task metadata
+ * @layer API
+ * @post Returns dataset metadata with mapping status.
+ * @pre SupersetClient is available; env_id is valid.
+ * @side_effect Reads from Superset API and task manager.
+ */
+
+// --- MappedFields (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for dataset mapping progress statistics
+ * @complexity 1
+ */
+
+// --- LastTask (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for the most recent task associated with a dataset
+ * @complexity 1
+ */
+
+// --- DatasetItem (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Summary DTO for a dataset in the hub listing
+ * @complexity 1
+ */
+
+// --- LinkedDashboard (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for a dashboard linked to a dataset
+ * @complexity 1
+ */
+
+// --- DatasetColumn (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for a single dataset column's metadata
+ * @complexity 1
+ */
+
+// --- MetricItem (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Pydantic DTO for a dataset metric — carries Superset metric metadata.
+ * @complexity 1
+ */
+
+// --- DatasetDetailResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Detailed DTO for a dataset including columns, linked dashboards, and metrics.
+ * @complexity 2
+ */
+
+// --- StatsCounts (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Aggregate statistics for the Stats Bar — computed from full dataset list.
+ * @complexity 1
+ */
+
+// --- DatasetsResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Paginated response DTO for dataset listings with stats.
+ * @complexity 2
+ */
+
+// --- TaskResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Response DTO containing a task ID for tracking
+ * @complexity 1
+ */
+
+// --- ColumnDescriptionUpdate (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for inline-edit of a column description.
+ * @complexity 1
+ */
+
+// --- MetricDescriptionUpdate (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for inline-edit of a metric description.
+ * @complexity 1
+ */
+
+// --- get_dataset_ids (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Fetch list of all dataset IDs from a specific environment (without pagination)
+ * @complexity 4
+ * @post Returns a list of all dataset IDs
+ * @pre env_id must be a valid environment ID
+ */
+
+// --- get_datasets (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Fetch list of datasets from a specific environment with mapping progress and stats.
+ * @complexity 4
+ * @post Response includes pagination metadata (page, page_size, total, total_pages) and stats object.
+ * @pre page_size must be between 1 and 100 if provided
+ * @rationale Stats counts returned in the same response as datasets to avoid an extra API call for the Stats Bar (FR-022).
+ */
+
+// --- MapColumnsRequest (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for initiating column mapping
+ * @complexity 1
+ */
+
+// --- map_columns (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Trigger bulk column mapping for datasets
+ * @complexity 4
+ * @post Task is created and queued for execution
+ * @pre dataset_ids is a non-empty list
+ */
+
+// --- GenerateDocsRequest (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for initiating documentation generation
+ * @complexity 1
+ */
+
+// --- generate_docs (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Trigger bulk documentation generation for datasets
+ * @complexity 4
+ * @post Task is created and queued for execution
+ * @pre dataset_ids is a non-empty list
+ */
+
+// --- get_dataset_detail (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Get detailed dataset information including columns and linked dashboards
+ * @complexity 4
+ * @post Returns detailed dataset info with columns and linked dashboards
+ * @pre dataset_id is a valid dataset ID
+ */
+
+// --- _strip_html_tags (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Detect and strip HTML tags from a text string. Uses simple regex <[^>]*>.
+ * @complexity 2
+ */
+
+// --- update_column_description (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Save description for a single dataset column. Internal: GET full dataset from Superset, modify one column's description, PUT back.
+ * @complexity 4
+ * @error 400 — description exceeds max length or contains non-plaintext content. 404 — dataset_id or column_id not found. 502 — Superset upstream failure (GET or PUT).
+ * @post Column description in Superset is updated. Response confirms success.
+ * @pre dataset_id and column_id must exist in the target environment.
+ * @rationale Must perform GET→modify→PUT because Superset has no PATCH for individual columns — only full object PUT with override_columns=false.
+ * @rejected Direct PUT from frontend — rejected because frontend would need to handle full Superset payload structure.
+ * @side_effect Mutates dataset metadata in upstream Superset instance via PUT.
+ * @validation description — string, max 2000 chars, plain text only (HTML stripped), may be empty string to clear description, no trimming applied. 404 if dataset or column not found. 502 if Superset upstream fails.
+ */
+
+// --- update_metric_description (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Save description for a single dataset metric. Mirror of update_column_description for metrics.
+ * @complexity 4
+ * @error 400 — description exceeds max length or contains non-plaintext content. 404 — dataset_id or metric_id not found. 502 — Superset upstream failure (GET or PUT).
+ * @post Metric description in Superset is updated.
+ * @pre dataset_id and metric_id must exist in the target environment.
+ * @side_effect Mutates dataset metadata in upstream Superset instance via PUT.
+ * @validation description — string, max 2000 chars, plain text only (HTML stripped), may be empty string to clear description, no trimming applied. 404 if dataset or metric not found. 502 if Superset upstream fails.
+ */
+
+// --- EnvironmentsApi (backend/src/api/routes/environments.py)
+/**!
+ * @brief API endpoints for listing environments and their databases.
+ * @complexity 5
+ * @invariant Environment IDs must exist in the configuration.
+ * @layer API
+ */
+
+// --- _normalize_superset_env_url (backend/src/api/routes/environments.py)
+/**!
+ * @brief Canonicalize Superset environment URL to base host/path without trailing /api/v1.
+ * @post Returns normalized base URL.
+ * @pre raw_url can be empty.
+ */
+
+// --- ScheduleSchema (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- EnvironmentResponse (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- DatabaseResponse (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- update_environment_schedule (backend/src/api/routes/environments.py)
+/**!
+ * @brief Update backup schedule for an environment.
+ * @layer API
+ * @post Backup schedule updated and scheduler reloaded.
+ * @pre Environment id exists, schedule is valid ScheduleSchema.
+ */
+
+// --- get_environment_databases (backend/src/api/routes/environments.py)
+/**!
+ * @brief Fetch the list of databases from a specific environment.
+ * @layer API
+ * @post Returns a list of database summaries from the environment.
+ * @pre Environment id exists.
+ */
+
+// --- GitPackage (backend/src/api/routes/git/__init__.py)
+/**!
+ * @brief Package root for decomposed git routes. Re-exports all public symbols from submodules.
+ * @complexity 5
+ * @data_contract GitRequest -> GitResponse
+ * @invariant git_service and os are module-level attributes for test monkeypatch compatibility.
+ * @layer API
+ * @post Git API package exported
+ * @pre Git service initialized
+ * @side_effect Registers git route submodules
+ */
+
+// --- GitConfigRoutes (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git server configuration CRUD and connection testing.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- get_git_configs (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief List all configured Git servers.
+ * @complexity 2
+ */
+
+// --- create_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Register a new Git server configuration.
+ * @complexity 2
+ */
+
+// --- update_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Update an existing Git server configuration.
+ * @complexity 2
+ */
+
+// --- delete_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Remove a Git server configuration.
+ * @complexity 2
+ */
+
+// --- test_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Validate connection to a Git server using provided credentials.
+ * @complexity 2
+ */
+
+// --- GitDeps (backend/src/api/routes/git/_deps.py)
+/**!
+ * @brief Shared dependency wiring for monkeypatch-safe git_service access and constants.
+ * @complexity 1
+ * @invariant get_git_service() resolves from sys.modules at call time so test monkeypatching
+ * @layer API
+ */
+
+// --- GitEnvironmentRoutes (backend/src/api/routes/git/_environment_routes.py)
+/**!
+ * @brief FastAPI endpoint for listing deployment environments.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- GitGiteaRoutes (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief FastAPI endpoints for Gitea-specific repository operations.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- list_gitea_repositories (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief List repositories in Gitea for a saved Gitea config.
+ * @complexity 2
+ */
+
+// --- create_gitea_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Create a repository in Gitea for a saved Gitea config.
+ * @complexity 2
+ */
+
+// --- delete_gitea_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Delete repository in Gitea for a saved Gitea config.
+ * @complexity 2
+ */
+
+// --- create_remote_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Create repository on remote Git server using selected provider config.
+ * @complexity 2
+ */
+
+// --- GitHelpers (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Shared helper functions for Git route modules.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- _build_no_repo_status_payload (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Build a consistent status payload for dashboards without initialized repositories.
+ * @complexity 1
+ * @post Returns a stable payload compatible with frontend repository status parsing.
+ */
+
+// --- _handle_unexpected_git_route_error (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Convert unexpected route-level exceptions to stable 500 API responses.
+ * @complexity 1
+ * @post Raises HTTPException(500) with route-specific context.
+ * @pre `error` is a non-HTTPException instance.
+ */
+
+// --- _resolve_repository_status (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve repository status for one dashboard with graceful NO_REPO semantics.
+ * @complexity 2
+ * @post Returns standard status payload or `NO_REPO` payload when repository path is absent.
+ * @pre `dashboard_id` is a valid integer.
+ */
+
+// --- _get_git_config_or_404 (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve GitServerConfig by id or raise 404.
+ * @complexity 2
+ */
+
+// --- _resolve_repo_key_from_ref (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve repository folder key with slug-first strategy and deterministic fallback.
+ * @complexity 2
+ */
+
+// --- _sanitize_optional_identity_value (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Normalize optional identity value into trimmed string or None.
+ * @complexity 1
+ */
+
+// --- _resolve_current_user_git_identity (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve configured Git username/email from current user's profile preferences.
+ * @complexity 2
+ */
+
+// --- _apply_git_identity_from_profile (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Apply user-scoped Git identity to repository-local config before write/pull operations.
+ * @complexity 2
+ */
+
+// --- GitMergeRoutes (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief FastAPI endpoints for merge operations (status, conflicts, resolve, abort, continue).
+ * @complexity 3
+ * @layer API
+ */
+
+// --- get_merge_status (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Return unfinished-merge status for repository (web-only recovery support).
+ * @complexity 2
+ */
+
+// --- get_merge_conflicts (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Return conflicted files with mine/theirs previews for web conflict resolver.
+ * @complexity 2
+ */
+
+// --- resolve_merge_conflicts (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Apply mine/theirs/manual conflict resolutions from WebUI and stage files.
+ * @complexity 3
+ */
+
+// --- abort_merge (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Abort unfinished merge from WebUI flow.
+ * @complexity 2
+ */
+
+// --- continue_merge (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Finalize unfinished merge from WebUI flow.
+ * @complexity 3
+ */
+
+// --- GitRepoLifecycleRoutes (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git lifecycle operations (sync, promote, deploy).
+ * @complexity 3
+ * @layer API
+ */
+
+// --- sync_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Sync dashboard state from Superset to Git using the GitPlugin.
+ * @complexity 3
+ */
+
+// --- promote_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Promote changes between branches via MR or direct merge.
+ * @complexity 3
+ */
+
+// --- deploy_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Deploy dashboard from Git to a target environment.
+ * @complexity 3
+ */
+
+// --- GitRepoOperationsRoutes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git repository operations (commit, push, pull, status, diff, history).
+ * @complexity 3
+ * @layer API
+ */
+
+// --- commit_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Stage and commit changes in the dashboard's repository.
+ * @complexity 2
+ */
+
+// --- push_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Push local commits to the remote repository.
+ * @complexity 2
+ */
+
+// --- pull_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Pull changes from the remote repository.
+ * @complexity 3
+ */
+
+// --- get_repository_status (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get current Git status for a dashboard repository.
+ * @complexity 2
+ */
+
+// --- get_repository_status_batch (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get Git statuses for multiple dashboard repositories in one request.
+ * @complexity 2
+ */
+
+// --- get_repository_diff (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get Git diff for a dashboard repository.
+ * @complexity 2
+ */
+
+// --- generate_commit_message (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Generate a suggested commit message using LLM.
+ * @complexity 3
+ */
+
+// --- GitRepoRoutes (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief FastAPI endpoints for core Git repository operations (init, binding, branches, checkout).
+ * @complexity 3
+ * @layer API
+ */
+
+// --- init_repository (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Link a dashboard to a Git repository and perform initial clone/init.
+ * @complexity 3
+ */
+
+// --- get_repository_binding (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Return repository binding with provider metadata for selected dashboard.
+ * @complexity 2
+ */
+
+// --- delete_repository (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Delete local repository workspace and DB binding for selected dashboard.
+ * @complexity 2
+ */
+
+// --- get_branches (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief List all branches for a dashboard's repository.
+ * @complexity 2
+ */
+
+// --- create_branch (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Create a new branch in the dashboard's repository.
+ * @complexity 2
+ */
+
+// --- checkout_branch (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Switch the dashboard's repository to a specific branch.
+ * @complexity 2
+ */
+
+// --- GitRouter (backend/src/api/routes/git/_router.py)
+/**!
+ * @brief Shared APIRouter for all Git route modules.
+ * @complexity 1
+ * @layer API
+ */
+
+// --- GitSchemas (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Defines Pydantic models for the Git integration API layer.
+ * @complexity 1
+ * @invariant All schemas must be compatible with the FastAPI router.
+ * @layer API
+ */
+
+// --- GitServerConfigBase (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Base schema for Git server configuration attributes.
+ * @complexity 1
+ */
+
+// --- GitServerConfigUpdate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for updating an existing Git server configuration.
+ */
+
+// --- GitServerConfigCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for creating a new Git server configuration.
+ */
+
+// --- GitServerConfigSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a Git server configuration with metadata.
+ */
+
+// --- GitRepositorySchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for tracking a local Git repository linked to a dashboard.
+ */
+
+// --- BranchSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a Git branch metadata.
+ */
+
+// --- CommitSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing Git commit details.
+ */
+
+// --- BranchCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for branch creation requests.
+ */
+
+// --- BranchCheckout (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for branch checkout requests.
+ */
+
+// --- CommitCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for staging and committing changes.
+ */
+
+// --- ConflictResolution (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for resolving merge conflicts.
+ */
+
+// --- MergeStatusSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema representing unfinished merge status for repository.
+ */
+
+// --- MergeConflictFileSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing one conflicted file with optional side snapshots.
+ */
+
+// --- MergeResolveRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for resolving one or multiple merge conflicts.
+ */
+
+// --- MergeContinueRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for finishing merge with optional explicit commit message.
+ */
+
+// --- DeploymentEnvironmentSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a target deployment environment.
+ */
+
+// --- DeployRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for dashboard deployment requests.
+ */
+
+// --- RepoInitRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for repository initialization requests.
+ */
+
+// --- RepositoryBindingSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing repository-to-config binding and provider metadata.
+ */
+
+// --- RepoStatusBatchRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for requesting repository statuses for multiple dashboards in a single call.
+ */
+
+// --- RepoStatusBatchResponse (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for returning repository statuses keyed by dashboard ID.
+ */
+
+// --- GiteaRepoSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing a Gitea repository.
+ */
+
+// --- GiteaRepoCreateRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for creating a Gitea repository.
+ */
+
+// --- RemoteRepoSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Provider-agnostic remote repository payload.
+ */
+
+// --- RemoteRepoCreateRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Provider-agnostic repository creation request.
+ */
+
+// --- PromoteRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for branch promotion workflow.
+ */
+
+// --- PromoteResponse (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Response schema for promotion operation result.
+ */
+
+// --- health_router (backend/src/api/routes/health.py)
+/**!
+ * @brief API endpoints for dashboard health monitoring and status aggregation.
+ * @complexity 3
+ * @layer UI
+ */
+
+// --- get_health_summary (backend/src/api/routes/health.py)
+/**!
+ * @brief Get aggregated health status for all dashboards.
+ * @post Returns HealthSummaryResponse.
+ * @pre Caller has read permission for dashboard health view.
+ */
+
+// --- delete_health_report (backend/src/api/routes/health.py)
+/**!
+ * @brief Delete one persisted dashboard validation report from health summary.
+ * @post Validation record is removed; linked task/logs are cleaned when available.
+ * @pre Caller has write permission for tasks/report maintenance.
+ */
+
+// --- LlmRoutes (backend/src/api/routes/llm.py)
+/**!
+ * @brief API routes for LLM provider configuration and management.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- FetchModelsRequest (backend/src/api/routes/llm.py)
+/**!
+ * @brief Pydantic request model for the fetch-models endpoint.
+ * @complexity 1
+ */
+
+// --- router (backend/src/api/routes/llm.py)
+/**!
+ * @brief APIRouter instance for LLM routes.
+ * @complexity 1
+ */
+
+// --- _is_valid_runtime_api_key (backend/src/api/routes/llm.py)
+/**!
+ * @brief Validate decrypted runtime API key presence/shape.
+ * @complexity 4
+ * @post Returns True only for non-placeholder key.
+ * @pre value can be None.
+ */
+
+// --- get_providers (backend/src/api/routes/llm.py)
+/**!
+ * @brief Retrieve all LLM provider configurations.
+ * @complexity 4
+ * @post Returns list of LLMProviderConfig.
+ * @pre User is authenticated.
+ */
+
+// --- fetch_models (backend/src/api/routes/llm.py)
+/**!
+ * @brief Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.
+ * @complexity 4
+ * @post Returns a list of available model IDs.
+ * @pre User is authenticated. Either provider_id or base_url+provider_type must be provided.
+ */
+
+// --- get_llm_status (backend/src/api/routes/llm.py)
+/**!
+ * @brief Returns whether LLM runtime is configured for dashboard validation.
+ * @complexity 4
+ * @post configured=true only when an active provider with valid decrypted key exists.
+ * @pre User is authenticated.
+ */
+
+// --- create_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Create a new LLM provider configuration.
+ * @complexity 4
+ * @post Returns the created LLMProviderConfig.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- update_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Update an existing LLM provider configuration.
+ * @complexity 4
+ * @post Returns the updated LLMProviderConfig.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- delete_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Delete an LLM provider configuration.
+ * @complexity 4
+ * @post Returns success status.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- test_connection (backend/src/api/routes/llm.py)
+/**!
+ * @brief Test connection to an LLM provider.
+ * @complexity 4
+ * @post Returns success status and message.
+ * @pre User is authenticated.
+ */
+
+// --- test_provider_config (backend/src/api/routes/llm.py)
+/**!
+ * @brief Test connection with a provided configuration (not yet saved).
+ * @complexity 4
+ * @post Returns success status and message.
+ * @pre User is authenticated.
+ */
+
+// --- MaintenanceRoutesPackage (backend/src/api/routes/maintenance/__init__.py)
+/**!
+ * @brief Maintenance Banner API route package.
+ * @complexity 1
+ * @layer API
+ */
+
+// --- MaintenanceRouter (backend/src/api/routes/maintenance/_router.py)
+/**!
+ * @brief FastAPI APIRouter for the Maintenance Banner endpoints.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- MaintenanceRoutesModule (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Route handler stubs for all 7 Maintenance Banner API endpoints with RBAC guards per FR-015.
+ * @complexity 3
+ * @invariant RBAC enforced per FR-015 matrix via has_permission() dependency.
+ * @layer API
+ */
+
+// --- list_dashboard_banners (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get per-dashboard banner state for the Dashboard Hub indicator.
+ * @complexity 2
+ */
+
+// --- list_events (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get active and completed maintenance event lists with affected dashboard counts.
+ * @complexity 2
+ */
+
+// --- start_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Start a maintenance event. Validates input, creates event, dispatches TaskManager task.
+ * @complexity 3
+ */
+
+// --- end_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief End a specific maintenance event by ID. Removes banners from affected dashboards.
+ * @complexity 3
+ */
+
+// --- end_all_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief End all active maintenance events. Removes all banners from all dashboards.
+ * @complexity 3
+ */
+
+// --- get_maintenance_settings (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get current maintenance settings configuration.
+ * @complexity 2
+ */
+
+// --- update_maintenance_settings (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Update maintenance settings. All fields optional for partial update.
+ * @complexity 2
+ */
+
+// --- MaintenanceSchemasModule (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Pydantic models for Maintenance Banner API: request/response schemas per data-model.md.
+ * @complexity 2
+ * @invariant All response schemas use the standard envelope shape: { status, data, error, meta }
+ * @layer API
+ */
+
+// --- MaintenanceStartRequest (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief POST /api/maintenance/start request body with environment scoping.
+ * @complexity 1
+ */
+
+// --- MaintenanceSettingsUpdate (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief PUT /api/maintenance/settings request body — all fields optional for partial update.
+ * @complexity 1
+ */
+
+// --- MaintenanceStartResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for /api/maintenance/start — always 202 with task_id.
+ * @complexity 1
+ */
+
+// --- MaintenanceDashboardResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Describes a single dashboard affected by a maintenance operation.
+ * @complexity 1
+ */
+
+// --- MaintenanceFailedDashboard (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Describes a dashboard that failed during banner apply/removal.
+ * @complexity 1
+ */
+
+// --- MaintenanceTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed maintenance start task.
+ * @complexity 1
+ */
+
+// --- MaintenanceEndResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for /api/maintenance/{id}/end and /api/maintenance/end-all — always 202 with task_id.
+ * @complexity 1
+ */
+
+// --- MaintenanceEndTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed end maintenance task.
+ * @complexity 1
+ */
+
+// --- MaintenanceEndAllTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed end-all maintenance task.
+ * @complexity 1
+ */
+
+// --- MaintenanceSettingsResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for GET /api/maintenance/settings.
+ * @complexity 1
+ */
+
+// --- MaintenanceEventItem (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Single maintenance event summary for GET /api/maintenance/events.
+ * @complexity 1
+ */
+
+// --- MaintenanceEventListResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for GET /api/maintenance/events.
+ * @complexity 1
+ */
+
+// --- MaintenanceDashboardBannerState (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Per-dashboard banner state for GET /api/maintenance/dashboard-banners.
+ * @complexity 1
+ */
+
+// --- MaintenanceAlreadyActiveResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for duplicate /start call — idempotency hit.
+ * @complexity 1
+ */
+
+// --- MappingsApi (backend/src/api/routes/mappings.py)
+/**!
+ * @brief API endpoints for managing database mappings and getting suggestions.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- MappingCreate (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- MappingResponse (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- SuggestRequest (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- get_mappings (backend/src/api/routes/mappings.py)
+/**!
+ * @brief List all saved database mappings.
+ * @post Returns filtered list of DatabaseMapping records.
+ * @pre db session is injected.
+ */
+
+// --- create_mapping (backend/src/api/routes/mappings.py)
+/**!
+ * @brief Create or update a database mapping.
+ * @post DatabaseMapping created or updated in database.
+ * @pre mapping is valid MappingCreate, db session is injected.
+ */
+
+// --- suggest_mappings_api (backend/src/api/routes/mappings.py)
+/**!
+ * @brief Get suggested mappings based on fuzzy matching.
+ * @post Returns mapping suggestions.
+ * @pre request is valid SuggestRequest, config_manager is injected.
+ */
+
+// --- MigrationApi (backend/src/api/routes/migration.py)
+/**!
+ * @brief HTTP contract layer for migration orchestration, settings, dry-run, and mapping sync endpoints.
+ * @complexity 5
+ * @data_contract [DashboardSelection | QueryParams] -> [TaskResponse | DryRunResult | MappingSummary]
+ * @invariant Migration endpoints never execute with invalid environment references and always return explicit HTTP errors on guard failures.
+ * @layer Infrastructure
+ * @post Migration tasks are enqueued or dry-run results are computed and returned.
+ * @pre Backend core services initialized and Database session available.
+ * @side_effect Enqueues long-running tasks, potentially mutates ResourceMapping table, and performs remote Superset API calls.
+ * @test_contract [DashboardSelection + configured envs] -> [task_id | dry-run result | sync summary]
+ * @test_edge [external_fail] ->[HTTP_500]
+ * @test_invariant [EnvironmentValidationBeforeAction] -> VERIFIED_BY: [invalid_environment, valid_execution]
+ * @test_scenario [valid_execution] -> [success_payload_with_required_fields]
+ */
+
+// --- execute_migration (backend/src/api/routes/migration.py)
+/**!
+ * @brief Validate migration selection and enqueue asynchronous migration task execution.
+ * @complexity 5
+ * @data_contract Input[DashboardSelection] -> Output[Dict[str, str]]
+ * @invariant Migration task dispatch never occurs before source and target environment ids pass guard validation.
+ * @post Returns {"task_id": str, "message": str} when task creation succeeds; emits HTTP_400/HTTP_500 on failure.
+ * @pre DashboardSelection payload is valid and both source/target environments exist.
+ * @side_effect Reads configuration, writes task record through task manager, and writes operational logs.
+ */
+
+// --- dry_run_migration (backend/src/api/routes/migration.py)
+/**!
+ * @brief Build pre-flight migration diff and risk summary without mutating target systems.
+ * @complexity 5
+ * @data_contract Input[DashboardSelection] -> Output[Dict[str, Any]]
+ * @invariant Dry-run flow remains read-only and rejects identical source/target environments before service execution.
+ * @post Returns deterministic dry-run payload; emits HTTP_400 for guard violations and HTTP_500 for orchestrator value errors.
+ * @pre DashboardSelection is valid, source and target environments exist, differ, and selected_ids is non-empty.
+ * @side_effect Reads local mappings from DB and fetches source/target metadata via Superset API.
+ */
+
+// --- get_migration_settings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Read and return configured migration synchronization cron expression.
+ * @complexity 3
+ * @data_contract Input[None] -> Output[Dict[str, str]]
+ * @post Returns {"cron": str} reflecting current persisted settings value.
+ * @pre Configuration store is available and requester has READ permission.
+ * @side_effect Reads configuration from config manager.
+ */
+
+// --- update_migration_settings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Validate and persist migration synchronization cron expression update.
+ * @complexity 3
+ * @data_contract Input[Dict[str, str]] -> Output[Dict[str, str]]
+ * @post Returns {"cron": str, "status": "updated"} and persists updated cron value.
+ * @pre Payload includes "cron" key and requester has WRITE permission.
+ * @side_effect Mutates configuration and writes persisted config through config manager.
+ */
+
+// --- get_resource_mappings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Fetch synchronized resource mappings with optional filters and pagination for migration mappings view.
+ * @complexity 3
+ * @data_contract Input[QueryParams] -> Output[Dict[str, Any]]
+ * @post Returns {"items": [...], "total": int} where items reflect applied filters and pagination.
+ * @pre skip>=0, 1<=limit<=500, DB session is active, requester has READ permission.
+ * @side_effect Executes database read queries against ResourceMapping table.
+ */
+
+// --- trigger_sync_now (backend/src/api/routes/migration.py)
+/**!
+ * @brief Trigger immediate ID synchronization for every configured environment.
+ * @complexity 3
+ * @data_contract Input[None] -> Output[Dict[str, Any]]
+ * @post Returns sync summary with synced/failed counts after attempting all environments.
+ * @pre At least one environment is configured and requester has EXECUTE permission.
+ * @side_effect Upserts Environment rows, commits DB transaction, performs network sync calls, and writes logs.
+ */
+
+// --- PluginsRouter (backend/src/api/routes/plugins.py)
+/**!
+ * @brief Defines the FastAPI router for plugin-related endpoints, allowing clients to list available plugins.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- list_plugins (backend/src/api/routes/plugins.py)
+/**!
+ * @brief Retrieve a list of all available plugins.
+ * @post Returns a list of PluginConfig objects.
+ * @pre plugin_loader is injected via Depends.
+ */
+
+// --- ProfileApiModule (backend/src/api/routes/profile.py)
+/**!
+ * @brief Exposes self-scoped profile preference endpoints and environment-based Superset account lookup.
+ * @complexity 5
+ * @invariant Endpoints are self-scoped and never mutate another user preference.
+ * @layer API
+ * @post Profile endpoints registered
+ * @pre Auth middleware configured, database session available
+ */
+
+// --- _get_profile_service (backend/src/api/routes/profile.py)
+/**!
+ * @brief Build profile service for current request scope.
+ * @post Returns a ready ProfileService instance.
+ * @pre db session and config manager are available.
+ */
+
+// --- get_preferences (backend/src/api/routes/profile.py)
+/**!
+ * @brief Get authenticated user's dashboard filter preference.
+ * @post Returns preference payload for current user only.
+ * @pre Valid JWT and authenticated user context.
+ */
+
+// --- update_preferences (backend/src/api/routes/profile.py)
+/**!
+ * @brief Update authenticated user's dashboard filter preference.
+ * @post Persists normalized preference for current user or raises validation/authorization errors.
+ * @pre Valid JWT and valid request payload.
+ */
+
+// --- lookup_superset_accounts (backend/src/api/routes/profile.py)
+/**!
+ * @brief Lookup Superset account candidates in selected environment.
+ * @post Returns success or degraded lookup payload with stable shape.
+ * @pre Valid JWT, authenticated context, and environment_id query parameter.
+ */
+
+// --- ReportsRouter (backend/src/api/routes/reports.py)
+/**!
+ * @brief FastAPI router for unified task report list and detail retrieval endpoints.
+ * @complexity 5
+ * @data_contract [ReportQuery] -> [ReportCollection | ReportDetailView]
+ * @invariant Endpoints are read-only and do not trigger long-running tasks.
+ * @layer API
+ * @post Router is configured and endpoints are ready for registration.
+ * @pre Reports service and dependencies are initialized.
+ * @side_effect None
+ */
+
+// --- _parse_csv_enum_list (backend/src/api/routes/reports.py)
+/**!
+ * @brief Parse comma-separated query value into enum list.
+ * @complexity 1
+ * @post Returns enum list or raises HTTP 400 with deterministic machine-readable payload.
+ * @pre raw may be None/empty or comma-separated values.
+ */
+
+// --- list_reports (backend/src/api/routes/reports.py)
+/**!
+ * @brief Return paginated unified reports list.
+ * @complexity 2
+ * @post deterministic error payload for invalid filters.
+ * @pre authenticated/authorized request and validated query params.
+ * @test_contract ListReportsApi ->
+ */
+
+// --- get_report_detail (backend/src/api/routes/reports.py)
+/**!
+ * @brief Return one normalized report detail with diagnostics and next actions.
+ * @complexity 2
+ * @post returns normalized detail envelope or 404 when report is not found.
+ * @pre authenticated/authorized request and existing report_id.
+ */
+
+// --- SettingsRouter (backend/src/api/routes/settings.py)
+/**!
+ * @brief Provides API endpoints for managing application settings and Superset environments.
+ * @complexity 5
+ * @data_contract Input -> ConfigUpdateRequest, Output -> AppConfig, LoggingConfigResponse
+ * @invariant All settings changes must be persisted via ConfigManager.
+ * @layer API
+ * @post Settings are read or written via ConfigManager.
+ * @pre ConfigManager is initialized and accessible.
+ * @public_api router
+ * @side_effect Persists config changes to disk via ConfigManager.
+ */
+
+// --- LoggingConfigResponse (backend/src/api/routes/settings.py)
+/**!
+ * @brief Response model for logging configuration with current task log level.
+ * @complexity 1
+ */
+
+// --- _validate_superset_connection_fast (backend/src/api/routes/settings.py)
+/**!
+ * @brief Run lightweight Superset connectivity validation without full pagination scan.
+ * @complexity 2
+ * @post Raises on auth/API failures; returns None on success.
+ * @pre env contains valid URL and credentials.
+ */
+
+// --- get_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves all application settings.
+ * @complexity 2
+ * @post Returns masked AppConfig.
+ * @pre Config manager is available.
+ */
+
+// --- get_features (backend/src/api/routes/settings.py)
+/**!
+ * @brief Public endpoint returning feature flags for frontend sidebar filtering.
+ * @complexity 1
+ * @post Returns dict with dataset_review and health_monitor booleans.
+ * @pre Config manager is available.
+ * @rationale Unauthenticated because sidebar filtering must work for all users, not just admins.
+ */
+
+// --- get_storage_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves storage-specific settings.
+ * @complexity 2
+ */
+
+// --- update_storage_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates storage-specific settings.
+ * @complexity 2
+ * @post Storage settings are updated and saved.
+ */
+
+// --- test_environment_connection (backend/src/api/routes/settings.py)
+/**!
+ * @brief Tests the connection to a Superset environment.
+ * @complexity 2
+ * @post Returns success or error status.
+ * @pre ID is provided.
+ */
+
+// --- get_logging_config (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves current logging configuration.
+ * @complexity 2
+ * @post Returns logging configuration.
+ * @pre Config manager is available.
+ */
+
+// --- update_logging_config (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates logging configuration.
+ * @complexity 2
+ * @post Logging configuration is updated and saved.
+ * @pre New logging config is provided.
+ */
+
+// --- ConsolidatedSettingsResponse (backend/src/api/routes/settings.py)
+/**!
+ * @brief Response model for consolidated application settings.
+ * @complexity 1
+ */
+
+// --- get_consolidated_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves all settings categories in a single call.
+ * @complexity 4
+ * @data_contract Input[ConfigManager] -> Output[ConsolidatedSettingsResponse]
+ * @post Returns consolidated settings, provider metadata, and persisted notification payload in one stable response.
+ * @pre Config manager is available and the caller holds admin settings read permission.
+ * @side_effect Opens one database session to read LLM providers and config-backed notification payload, then closes it.
+ */
+
+// --- update_consolidated_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Bulk update application settings from the consolidated view.
+ * @complexity 2
+ * @post Settings are updated and saved via ConfigManager.
+ * @pre User has admin permissions, config is valid.
+ */
+
+// --- get_validation_policies (backend/src/api/routes/settings.py)
+/**!
+ * @brief Lists all validation policies.
+ * @complexity 2
+ */
+
+// --- create_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Creates a new validation policy.
+ * @complexity 2
+ */
+
+// --- update_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates an existing validation policy.
+ * @complexity 2
+ */
+
+// --- delete_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Deletes a validation policy.
+ * @complexity 2
+ */
+
+// --- get_translation_schedules (backend/src/api/routes/settings.py)
+/**!
+ * @brief Lists all translation schedules joined with translation job names.
+ * @complexity 2
+ */
+
+// --- storage_routes (backend/src/api/routes/storage.py)
+/**!
+ * @brief API endpoints for file storage management (backups and repositories).
+ * @complexity 5
+ * @invariant All paths must be validated against path traversal.
+ * @layer API
+ */
+
+// --- list_files (backend/src/api/routes/storage.py)
+/**!
+ * @brief List all files and directories in the storage system.
+ * @complexity 3
+ * @post Returns a list of StoredFile objects.
+ * @pre None.
+ */
+
+// --- delete_file (backend/src/api/routes/storage.py)
+/**!
+ * @brief Delete a specific file or directory.
+ * @complexity 3
+ * @post Item is removed from storage.
+ * @pre category must be a valid FileCategory.
+ * @side_effect Deletes item from the filesystem.
+ */
+
+// --- download_file (backend/src/api/routes/storage.py)
+/**!
+ * @brief Retrieve a file for download.
+ * @complexity 3
+ * @post Returns a FileResponse.
+ * @pre category must be a valid FileCategory.
+ */
+
+// --- get_file_by_path (backend/src/api/routes/storage.py)
+/**!
+ * @brief Retrieve a file by validated absolute/relative path under storage root.
+ * @complexity 3
+ * @post Returns a FileResponse for existing files.
+ * @pre path must resolve under configured storage root.
+ */
+
+// --- TasksRouter (backend/src/api/routes/tasks.py)
+/**!
+ * @brief Defines the FastAPI router for task-related endpoints, allowing clients to create, list, and get the status of tasks.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- resume_task (backend/src/api/routes/tasks.py)
+/**!
+ * @brief Resume a task that is awaiting input (e.g., passwords).
+ * @complexity 2
+ * @post Task resumes execution with provided input.
+ * @pre task must be in AWAITING_INPUT status.
+ */
+
+// --- TranslateRoutes (backend/src/api/routes/translate/__init__.py)
+/**!
+ * @brief API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.
+ * @complexity 4
+ * @layer API
+ * @post Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed.
+ * @pre API server is running, user is authenticated, database is accessible.
+ * @rationale Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.
+ * @rejected Invalidating in-progress runs on config edit would break scheduled run continuity.
+ * @side_effect Creates/modifies DB rows; triggers background translation runs; queries Superset API.
+ */
+
+// --- TranslateCorrectionRoutesModule (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Term correction submission endpoints.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- submit_correction (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Submit a term correction from a run result review.
+ * @complexity 4
+ * @post Correction applied with conflict detection.
+ * @pre User has translate.dictionary.edit permission.
+ * @side_effect Creates/updates DictionaryEntry row; commits.
+ */
+
+// --- submit_bulk_corrections (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Submit multiple term corrections atomically.
+ * @complexity 4
+ * @post All corrections applied or none with conflict list.
+ * @pre User has translate.dictionary.edit permission.
+ * @side_effect Creates/updates DictionaryEntry rows; commits once.
+ */
+
+// --- TranslateDictionaryRoutesModule (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Terminology Dictionary CRUD, entries management, and import routes.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- list_dictionaries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief List all terminology dictionaries.
+ * @complexity 4
+ * @post Returns list of dictionaries with total count.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- get_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Get a single terminology dictionary by ID.
+ * @complexity 4
+ * @post Returns the dictionary with entry_count.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- create_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Create a new terminology dictionary.
+ * @complexity 4
+ * @post Returns the created dictionary.
+ * @pre User has translate.dictionary.create permission.
+ */
+
+// --- update_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Update an existing terminology dictionary.
+ * @complexity 4
+ * @post Returns the updated dictionary.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- delete_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Delete a terminology dictionary, blocked if attached to active/scheduled jobs.
+ * @complexity 4
+ * @post Dictionary is deleted.
+ * @pre User has translate.dictionary.delete permission.
+ */
+
+// --- list_dictionary_entries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief List entries for a dictionary, optionally filtered by language pair.
+ * @complexity 4
+ * @post Returns paginated list of entries with language pair fields.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- add_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Add a new entry to a dictionary.
+ * @complexity 4
+ * @post Entry is created.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- edit_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Update an existing dictionary entry.
+ * @complexity 4
+ * @post Entry is updated.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- delete_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Delete a dictionary entry.
+ * @complexity 4
+ * @post Entry is deleted.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- import_dictionary_entries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Import entries into a terminology dictionary from CSV/TSV content.
+ * @complexity 4
+ * @post Entries are imported per conflict mode.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- TranslateHelpersModule (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Shared helper functions for translate route handlers.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- _run_to_response (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Convert TranslationRun ORM to response dict.
+ * @complexity 2
+ */
+
+// --- _dict_to_response (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Convert a TerminologyDictionary ORM model to a response dict with computed entry_count.
+ * @complexity 2
+ */
+
+// --- _get_dictionary_entry_counts (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Get entry counts for a list of dictionary IDs.
+ * @complexity 2
+ */
+
+// --- TranslateJobRoutesModule (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Translation Job CRUD and datasource column routes.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- list_jobs (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief List all translation jobs.
+ * @complexity 4
+ * @post Returns list of translation jobs.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- get_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Get a single translation job by ID.
+ * @complexity 4
+ * @post Returns the translation job.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- create_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Create a new translation job.
+ * @complexity 4
+ * @post Returns the created translation job.
+ * @pre User has translate.job.create permission.
+ * @side_effect Validates columns via SupersetClient; caches database_dialect.
+ */
+
+// --- update_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Update an existing translation job.
+ * @complexity 4
+ * @post Returns the updated translation job.
+ * @pre User has translate.job.edit permission.
+ * @side_effect Re-detects database_dialect if datasource changed.
+ */
+
+// --- delete_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Delete a translation job.
+ * @complexity 4
+ * @post Job is deleted.
+ * @pre User has translate.job.delete permission.
+ */
+
+// --- duplicate_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Duplicate a translation job.
+ * @complexity 4
+ * @post Returns the duplicated job with status DRAFT.
+ * @pre User has translate.job.create permission.
+ */
+
+// --- get_datasource_columns (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Get column metadata and database dialect for a Superset datasource.
+ * @complexity 4
+ * @post Returns column list with metadata and database_dialect.
+ * @pre User has translate.job.view permission.
+ * @rationale Dialect detection from Superset connection cached on TranslationJob at save time.
+ * @rejected Hardcoding dialect list per database — would drift from actual Superset config.
+ * @side_effect Queries Superset API for dataset detail and database info.
+ */
+
+// --- check_target_schema (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Проверяет схему целевой таблицы: какие колонки ожидаются, какие есть, каких не хватает.
+ * @complexity 3
+ * @rationale Позволяет UI показать пользователю подсказку о недостающих колонках
+ */
+
+// --- TranslateMetricsRoutesModule (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Translation Metrics endpoints.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- get_metrics (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Get translation metrics, optionally filtered by job.
+ * @complexity 4
+ * @post Returns metrics data.
+ * @pre User has translate.metrics.view permission.
+ */
+
+// --- get_job_metrics (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Get aggregated metrics for a specific job.
+ * @complexity 4
+ * @post Returns metrics dict.
+ * @pre User has translate.metrics.view permission.
+ */
+
+// --- TranslatePreviewRoutesModule (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Translation Preview session management routes.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- preview_translation (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Preview a translation before applying it.
+ * @complexity 4
+ * @post Returns a preview session with records and cost estimation.
+ * @pre User has translate.job.execute permission.
+ * @side_effect Fetches sample data from Superset; calls LLM provider; creates DB rows.
+ */
+
+// --- update_preview_row (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Approve, edit, or reject a preview row (optionally per language).
+ * @complexity 4
+ * @post Preview row status is updated.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- accept_preview_session (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Accept a preview session, marking it as the quality gate for full execution.
+ * @complexity 4
+ * @post Preview session is marked as APPLIED; full execution can proceed.
+ * @pre User has translate.job.execute permission. Job has an ACTIVE preview session.
+ */
+
+// --- apply_preview (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Apply a preview session (alias for accept when accepting at session level).
+ * @complexity 4
+ * @post Preview is applied.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- get_preview_records (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Get records for a preview session.
+ * @complexity 4
+ * @post Returns list of preview records.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- TranslateRouterModule (backend/src/api/routes/translate/_router.py)
+/**!
+ * @brief APIRouter instance for translate routes.
+ * @complexity 1
+ * @layer API
+ */
+
+// --- translate_router (backend/src/api/routes/translate/_router.py)
+/**!
+ * @brief APIRouter instance for all translate sub-routes.
+ */
+
+// --- TranslateRunListRoutesModule (backend/src/api/routes/translate/_run_list_routes.py)
+/**!
+ * @brief Translation Run listing, detail, and CSV download routes (cross-job).
+ * @complexity 3
+ * @layer API
+ */
+
+// --- download_skipped_csv (backend/src/api/routes/translate/_run_list_routes.py)
+/**!
+ * @brief Download a CSV of skipped translation records from a run.
+ * @complexity 4
+ * @post Returns CSV file of skipped records.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- TranslateRunRoutesModule (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Translation Run execution, history, status, records and batches routes.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- run_translation (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Execute a translation job (trigger a run).
+ * @complexity 4
+ * @post Returns the created translation run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- retry_run (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Retry failed batches in a translation run.
+ * @complexity 4
+ * @post Returns the updated translation run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- retry_insert (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Retry the SQL insert phase for a completed run.
+ * @complexity 4
+ * @post Returns the updated run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- cancel_run (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Cancel a running translation.
+ * @complexity 4
+ * @post Run is cancelled.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- get_run_history (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get run history for a translation job.
+ * @complexity 4
+ * @post Returns list of runs.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_run_status (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get status and statistics for a translation run.
+ * @complexity 4
+ * @post Returns run details with statistics.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_run_records (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get paginated records for a translation run.
+ * @complexity 4
+ * @post Returns paginated records.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_batches (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get batches for a translation run.
+ * @complexity 4
+ * @post Returns list of batches.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- override_detected_language (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Manually override the detected source language for a specific translation language entry.
+ * @complexity 4
+ * @post TranslationLanguage.source_language_detected is updated; language_overridden is set to True.
+ * @pre User has translate.job.execute permission. Run, record, and language entry exist.
+ * @side_effect DB write.
+ */
+
+// --- inline_edit_translation (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Apply an inline correction to a translated value on a completed run result.
+ * @complexity 4
+ * @post TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.
+ * @pre User has translate.job.execute permission. Run, record, and language entry exist.
+ */
+
+// --- bulk_find_replace (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Perform bulk find-and-replace on translated values within a run.
+ * @complexity 4
+ * @post If preview=false, matching translations are updated. Optional dictionary submission.
+ * @pre User has translate.job.execute permission. Run exists.
+ */
+
+// --- TranslateScheduleRoutesModule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Translation Schedule management routes.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- get_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Get the schedule for a translation job.
+ * @complexity 4
+ * @post Returns the schedule configuration.
+ * @pre User has translate.schedule.view permission.
+ */
+
+// --- set_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Set or update the schedule for a translation job.
+ * @complexity 4
+ * @post Schedule is created or updated.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- enable_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Enable a schedule for a translation job.
+ * @complexity 4
+ * @post Schedule is enabled.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- disable_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Disable a schedule for a translation job.
+ * @complexity 4
+ * @post Schedule is disabled.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- delete_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Delete the schedule for a translation job.
+ * @complexity 4
+ * @post Schedule is removed.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- get_next_executions (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Preview next N executions for a job's schedule.
+ * @complexity 4
+ * @post Returns next execution times.
+ * @pre User has translate.schedule.view permission.
+ */
+
+// --- ValidationRoutes (backend/src/api/routes/validation.py)
+/**!
+ * @brief API routes for validation task management and run history.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- _get_task_service (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _get_run_service (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 1
+ */
+
+// --- list_tasks (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 4
+ * @rationale Route handler delegates to service with permission check — keeps API layer thin and testable; auth gate happens before any business logic.
+ * @rejected Business logic in route handler rejected — would duplicate validation logic and make permission checks harder to audit.
+ */
+
+// --- update_task (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 4
+ * @rationale PUT semantics for full resource update — consistent with existing API patterns; Pydantic's exclude_unset handles partial updates while keeping PUT as the endpoint verb.
+ * @rejected PATCH semantics rejected — using PUT with exclude_unset provides the same partial-update flexibility without introducing a second HTTP method for the same resource.
+ */
+
+// --- delete_task (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 4
+ * @rationale DELETE returns 204 No Content per REST convention — minimizes response payload for delete operations; supports optional delete_runs query param for cascade control.
+ * @rejected Returning deleted resource in response body rejected — unnecessary data transfer; 204 with no body is the REST standard for delete operations.
+ */
+
+// --- trigger_run (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 4
+ * @rationale Returns spawned task ID so frontend can poll for completion — enables progress tracking without WebSocket. Async spawn is essential since LLM validation can take 30+ seconds.
+ * @rejected Blocking until run completes rejected — LLM-based validation is slow (30-120s); synchronous wait would timeout HTTP requests and create terrible UX.
+ */
+
+// --- list_runs (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 4
+ * @rationale Exposes 6 query parameters for cross-task run filtering — matches the run service's filter capabilities exactly, enabling flexible history exploration.
+ * @rejected Fixed filter set rejected — would limit the history page's debugging use cases; users need to filter by task, status, dashboard, environment, and date range.
+ */
+
+// --- get_run_detail (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 4
+ * @rationale Returns full run detail including issues list and raw response for the report view — single endpoint serves the complete detail page without multiple fetches.
+ * @rejected Paginated issues endpoint rejected — issues per run are typically < 20 items; pagination overhead is unnecessary for such small collections.
+ */
+
+// --- delete_run (backend/src/api/routes/validation.py)
+/**!
+ * @complexity 3
+ * @rationale Returns 404 when run not found — explicit error handling rather than silent success; helps frontend distinguish between successful delete and missing resource.
+ * @rejected Silent success on missing run rejected — would mask bugs in the UI that reference already-deleted runs; explicit 404 helps debugging.
+ */
+
+// --- ValidationApiTests (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Unit tests for validation task CRUD and run history API endpoints.
+ * @complexity 3
+ * @invariant provider_id must reference a multimodal LLM provider for creation
+ * @layer API
+ * @test_contract [ValidationTaskCreate|Update|RunRequest] -> [ValidationTaskResponse|RunResponse|TriggerRunResponse]
+ * @test_edge delete_task_with_runs -> 204 with delete_runs=true flag
+ * @test_scenario delete_run -> 204 on success; 404 for nonexistent
+ */
+
+// --- test_list_tasks_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/tasks returns paginated task list with filters.
+ * @complexity 2
+ */
+
+// --- test_list_tasks_pagination (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Pagination query params are validated: page >= 1, page_size 1-100.
+ * @complexity 2
+ */
+
+// --- test_list_tasks_service_error (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Service ValueError becomes 400 on list_tasks.
+ * @complexity 2
+ */
+
+// --- test_create_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST /validation/tasks with valid payload returns 201.
+ * @complexity 2
+ */
+
+// --- test_create_task_missing_fields (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST with missing required fields returns 422.
+ * @complexity 2
+ */
+
+// --- test_create_task_invalid_provider (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST with non-multimodal provider returns 422.
+ * @complexity 2
+ */
+
+// --- test_get_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/tasks/{id} returns task with recent_runs.
+ * @complexity 2
+ */
+
+// --- test_get_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET for nonexistent task returns 404.
+ * @complexity 2
+ */
+
+// --- test_update_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief PUT /validation/tasks/{id} updates task and returns updated object.
+ * @complexity 2
+ */
+
+// --- test_update_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief PUT for nonexistent task returns 404.
+ * @complexity 2
+ */
+
+// --- test_delete_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE /validation/tasks/{id} returns 204.
+ * @complexity 2
+ */
+
+// --- test_delete_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE for nonexistent task returns 404.
+ * @complexity 2
+ */
+
+// --- test_delete_task_with_runs_flag (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE with delete_runs=true passes query param to service.
+ * @complexity 2
+ */
+
+// --- test_trigger_run_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST /validation/tasks/{id}/run spawns a validation task.
+ * @complexity 2
+ */
+
+// --- test_trigger_run_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST for nonexistent task returns 422.
+ * @complexity 2
+ */
+
+// --- test_trigger_run_no_dashboards (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Trigger fails with 422 when task has no dashboard IDs.
+ * @complexity 2
+ */
+
+// --- test_list_runs_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/runs returns paginated run list.
+ * @complexity 2
+ */
+
+// --- test_list_runs_filters (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief All 6 filter query params are accepted and forwarded to service.
+ * @complexity 2
+ */
+
+// --- test_list_runs_pagination (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Pagination boundary checks on runs list.
+ * @complexity 2
+ */
+
+// --- test_list_runs_invalid_status (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Status is a free string; any value passes through to service.
+ * @complexity 2
+ */
+
+// --- test_get_run_detail_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/runs/{id} returns full detail with issues and raw_response.
+ * @complexity 2
+ */
+
+// --- test_get_run_detail_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET for nonexistent run returns 404.
+ * @complexity 2
+ */
+
+// --- test_delete_run_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE /validation/runs/{id} returns 204.
+ * @complexity 2
+ */
+
+// --- test_delete_run_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE for nonexistent run returns 404.
+ * @complexity 2
+ */
+
+// --- test_endpoints_require_authentication (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Without current_user dependency, all 9 endpoints return 401.
+ * @complexity 2
+ */
+
+// --- test_permission_denied_non_admin (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief A non-admin user without validation.* permissions receives 403.
+ * @complexity 2
+ */
+
+// --- test_permission_denied_all_actions (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Each action (VIEW, CREATE, EDIT, DELETE, EXECUTE) denied for non-admin.
+ * @complexity 2
+ */
+
+// --- test_delete_task_runs_default_false (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief delete_runs query param defaults to False.
+ * @complexity 2
+ */
+
+// --- AppModule (backend/src/app.py)
+/**!
+ * @brief The main entry point for the FastAPI application.
+ * @complexity 5
+ * @data_contract [HTTP Request | WS Message] -> [HTTP Response | JSON Log Stream]
+ * @invariant All WebSocket connections must be properly cleaned up on disconnect.
+ * @layer API
+ * @post FastAPI app instance is created, middleware configured, and routes registered.
+ * @pre Python environment and dependencies installed; configuration database available.
+ * @rationale Duplicate @RELATION and @INVARIANT lines removed from header. Import sorting unified via ruff isort (I) rule across src/ — 139 fixes applied.
+ * @side_effect Starts background scheduler and binds network ports for HTTP/WS traffic.
+ */
+
+// --- FastAPI_App (backend/src/app.py)
+/**!
+ * @brief Canonical FastAPI application instance for route, middleware, and websocket registration.
+ * @complexity 3
+ */
+
+// --- ensure_initial_admin_user (backend/src/app.py)
+/**!
+ * @brief Ensures initial admin user exists when bootstrap env flags are enabled.
+ * @complexity 3
+ */
+
+// --- startup_event (backend/src/app.py)
+/**!
+ * @brief Handles application startup tasks, such as starting the scheduler.
+ * @complexity 3
+ * @post Scheduler is started.
+ * @pre None.
+ */
+
+// --- shutdown_event (backend/src/app.py)
+/**!
+ * @brief Handles application shutdown tasks, such as stopping the scheduler.
+ * @complexity 3
+ * @post Scheduler is stopped.
+ * @pre None.
+ */
+
+// --- app_middleware (backend/src/app.py)
+/**!
+ * @brief Configure application-wide middleware (Session, CORS).
+ * @rationale CORS allow_origins reads from ALLOWED_ORIGINS env var instead of hardcoded "*".
+ */
+
+// --- network_error_handler (backend/src/app.py)
+/**!
+ * @brief Global exception handler for NetworkError.
+ * @complexity 1
+ * @post Returns 503 HTTP Exception.
+ * @pre request is a FastAPI Request object.
+ */
+
+// --- log_requests (backend/src/app.py)
+/**!
+ * @brief Middleware to log incoming HTTP requests and their response status.
+ * @complexity 3
+ * @post Logs request and response details.
+ * @pre request is a FastAPI Request object.
+ */
+
+// --- API_Routes (backend/src/app.py)
+/**!
+ * @brief Register all FastAPI route groups exposed by the application entrypoint.
+ * @complexity 3
+ */
+
+// --- api.include_routers (backend/src/app.py)
+/**!
+ * @brief Registers all API routers with the FastAPI application.
+ * @complexity 1
+ * @layer API
+ */
+
+// --- websocket_endpoint (backend/src/app.py)
+/**!
+ * @brief Provides a WebSocket endpoint for real-time log streaming of a task with server-side filtering.
+ * @complexity 5
+ * @data_contract [task_id: str, source: str, level: str] -> [JSON log entry objects]
+ * @invariant Every accepted WebSocket subscription is unsubscribed exactly once even when streaming fails or the client disconnects.
+ * @post WebSocket connection is managed and logs are streamed until disconnect.
+ * @pre task_id must be a valid task ID.
+ * @side_effect Subscribes to TaskManager log queue and broadcasts messages over network.
+ * @test_contract WebSocketLogStreamApi ->
+ * @ux_state Connecting -> Streaming -> (Disconnected)
+ */
+
+// --- dataset_websocket_endpoint (backend/src/app.py)
+/**!
+ * @brief WebSocket endpoint for dataset.updated events — auto-refresh on task completion.
+ * @complexity 4
+ * @post WebSocket streams dataset.updated events until disconnect.
+ * @pre env_id must reference a known environment.
+ * @side_effect Subscribes to dataset event queue in task manager lifecycle.
+ */
+
+// --- StaticFiles (backend/src/app.py)
+/**!
+ * @brief Mounts the frontend build directory to serve static assets.
+ * @complexity 1
+ */
+
+// --- serve_spa (backend/src/app.py)
+/**!
+ * @brief Serves the SPA frontend for any path not matched by API routes.
+ * @complexity 1
+ * @post Returns the requested file or index.html.
+ * @pre frontend_path exists.
+ */
+
+// --- read_root (backend/src/app.py)
+/**!
+ * @brief A simple root endpoint to confirm that the API is running when frontend is missing.
+ * @complexity 1
+ * @post Returns a JSON message indicating API status.
+ * @pre None.
+ */
+
+// --- src.core (backend/src/core/__init__.py)
+/**!
+ * @brief Backend core services and infrastructure package root.
+ */
+
+// --- TestConfigManagerCompat (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Verifies ConfigManager compatibility wrappers preserve legacy payload sections.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- test_get_payload_preserves_legacy_sections (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure get_payload merges typed config into raw payload without dropping legacy sections.
+ */
+
+// --- test_save_config_accepts_raw_payload_and_keeps_extras (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure save_config accepts raw dict payload, refreshes typed config, and preserves extra sections.
+ */
+
+// --- test_save_config_syncs_environment_records_for_fk_backed_flows (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure saving config mirrors typed environments into relational records required by FK-backed session persistence.
+ */
+
+// --- _FakeQuery (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal query stub returning hardcoded existing environment record list for sync tests.
+ * @complexity 1
+ * @invariant all() always returns [existing_record]; no parameterization or filtering.
+ */
+
+// --- _FakeSession (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal SQLAlchemy session stub that captures add/delete calls for environment sync assertions.
+ * @complexity 1
+ * @invariant query() always returns _FakeQuery; no real DB interaction.
+ */
+
+// --- test_save_config_syncs_deletions_to_persistence (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure stale environment records are deleted during save (in _delete_stale_environment_records)
+ */
+
+// --- _FakeQueryDel (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal query stub for deletion test.
+ * @complexity 1
+ */
+
+// --- _FakeSessionDel (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal session stub that captures add/delete for deletion assertions.
+ * @complexity 1
+ */
+
+// --- test_load_config_syncs_environment_records_from_existing_db_payload (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure loading an existing DB-backed config also mirrors environment rows required by FK-backed runtime flows.
+ */
+
+// --- NativeFilterExtractionTests (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Verify native filter extraction from permalinks and native_filters_key URLs.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- test_extract_native_filters_from_permalink (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Extract native filters from a permalink key.
+ */
+
+// --- test_extract_native_filters_from_permalink_direct_response (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle permalink response without result wrapper.
+ */
+
+// --- test_extract_native_filters_from_key (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Extract native filters from a native_filters_key.
+ */
+
+// --- test_extract_native_filters_from_key_single_filter (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle single filter format in native filter state.
+ */
+
+// --- test_extract_native_filters_from_key_dict_value (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle filter state value as dict instead of JSON string.
+ */
+
+// --- test_parse_dashboard_url_for_filters_permalink (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse permalink URL format.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters_key URL format with numeric dashboard ID.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key_slug (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters_key URL format when dashboard reference is a slug, not a numeric ID.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Gracefully handle slug resolution failure for native_filters_key URL.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_filters_direct (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters direct query param.
+ */
+
+// --- test_parse_dashboard_url_for_filters_no_filters (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Return empty result when no filters present.
+ */
+
+// --- test_extra_form_data_merge (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ExtraFormDataMerge correctly merges dictionaries.
+ */
+
+// --- test_filter_state_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test FilterState Pydantic model.
+ */
+
+// --- test_parsed_native_filters_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ParsedNativeFilters Pydantic model.
+ */
+
+// --- test_parsed_native_filters_empty (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ParsedNativeFilters with no filters.
+ */
+
+// --- test_native_filter_data_mask_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test NativeFilterDataMask model.
+ */
+
+// --- test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Reconcile raw native filter ids from state to canonical metadata filter names.
+ */
+
+// --- test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Collapse raw-id state entries and metadata entries into one canonical filter.
+ */
+
+// --- test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Preserve unmatched raw native filter ids as fallback diagnostics when metadata mapping is unavailable.
+ */
+
+// --- test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Recovered native filter state should preserve exact Superset clause payload and time extras for preview compilation.
+ */
+
+// --- test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Assistant-facing imported-filter payload should redact likely PII while preserving structure metadata.
+ */
+
+// --- SupersetPreviewPipelineTests (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Verify explicit chart-data preview compilation and ensure non-dashboard 404 errors remain generic across sync and async clients.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- _make_environment (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- _make_requests_http_error (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- _make_httpx_status_error (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- test_compile_dataset_preview_prefers_legacy_explore_form_data_strategy (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Superset preview compilation should prefer the legacy form_data transport inferred from browser traffic before falling back to chart-data.
+ */
+
+// --- test_compile_dataset_preview_falls_back_to_chart_data_after_legacy_failures (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Superset preview compilation should fall back to chart-data when legacy form_data strategies are rejected.
+ */
+
+// --- test_build_dataset_preview_query_context_places_recovered_filters_in_chart_style_form_data (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should mirror chart-style filter transport so recovered native filters reach Superset compilation.
+ */
+
+// --- test_build_dataset_preview_query_context_merges_dataset_template_params_and_preserves_user_values (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should merge dataset template params for parity with real dataset definitions while preserving explicit session overrides.
+ */
+
+// --- test_build_dataset_preview_query_context_preserves_time_range_from_native_filter_payload (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should preserve time-range native filter extras even when dataset defaults differ.
+ */
+
+// --- test_build_dataset_preview_legacy_form_data_preserves_native_filter_clauses (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Legacy preview form_data should preserve recovered native filter clauses in browser-style fields without duplicating datasource for QueryObjectFactory.
+ */
+
+// --- test_sync_network_404_mapping_keeps_non_dashboard_endpoints_generic (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Sync network client should reserve dashboard-not-found translation for dashboard endpoints only.
+ */
+
+// --- test_sync_network_404_mapping_translates_dashboard_endpoints (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Sync network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+ */
+
+// --- test_async_network_404_mapping_keeps_non_dashboard_endpoints_generic (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Async network client should reserve dashboard-not-found translation for dashboard endpoints only.
+ */
+
+// --- test_async_network_404_mapping_translates_dashboard_endpoints (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Async network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+ */
+
+// --- TestSupersetProfileLookup (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Verifies Superset profile lookup adapter payload normalization and fallback error precedence.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- _RecordingNetworkClient (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Records request payloads and returns scripted responses for deterministic adapter tests.
+ * @complexity 2
+ * @invariant Each request consumes one scripted response in call order and persists call metadata.
+ */
+
+// --- test_get_users_page_sends_lowercase_order_direction (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Ensures adapter sends lowercase order_direction compatible with Superset rison schema.
+ * @post First request query payload contains order_direction='asc' for asc sort.
+ * @pre Adapter is initialized with recording network client.
+ */
+
+// --- test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Ensures fallback auth error does not mask primary schema/query failure.
+ * @post Raised exception remains primary SupersetAPIError (non-auth) to preserve root cause.
+ * @pre Primary endpoint fails with SupersetAPIError and fallback fails with AuthenticationError.
+ */
+
+// --- test_get_users_page_uses_fallback_endpoint_when_primary_fails (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Verifies adapter retries second users endpoint and succeeds when fallback is healthy.
+ * @post Result status is success and both endpoints were attempted in order.
+ * @pre Primary endpoint fails; fallback returns valid users payload.
+ */
+
+// --- test_throttled_scheduler (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Unit tests for ThrottledSchedulerConfigurator distribution logic.
+ * @complexity 3
+ */
+
+// --- test_calculate_schedule_even_distribution (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate even spacing across a two-hour scheduling window for three tasks.
+ */
+
+// --- test_calculate_schedule_midnight_crossing (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate scheduler correctly rolls timestamps into the next day across midnight.
+ */
+
+// --- test_calculate_schedule_single_task (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate single-task schedule returns only the window start timestamp.
+ */
+
+// --- test_calculate_schedule_empty_list (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate empty dashboard list produces an empty schedule.
+ */
+
+// --- test_calculate_schedule_zero_window (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate zero-length window schedules all tasks at identical start timestamp.
+ */
+
+// --- test_calculate_schedule_very_small_window (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate sub-second interpolation when task count exceeds near-zero window granularity.
+ */
+
+// --- AsyncSupersetClientModule (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+ * @complexity 3
+ * @layer Core
+ */
+
+// --- AsyncSupersetClient (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Async sibling of SupersetClient for dashboard read paths.
+ * @complexity 3
+ */
+
+// --- AsyncSupersetClientInit (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Initialize async Superset client with AsyncAPIClient transport.
+ * @complexity 3
+ * @data_contract Input[Environment] -> self.network[AsyncAPIClient]
+ * @post Client uses async network transport and inherited projection helpers.
+ * @pre env is valid Environment instance.
+ */
+
+// --- AsyncSupersetClientClose (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Close async transport resources.
+ * @complexity 3
+ * @post Underlying AsyncAPIClient is closed.
+ * @side_effect Closes network sockets.
+ */
+
+// --- get_dashboards_page_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one dashboards page asynchronously.
+ * @complexity 3
+ * @data_contract Input[query: Optional[Dict]] -> Output[Tuple[int, List[Dict]]]
+ * @post Returns total count and page result list.
+ */
+
+// --- get_dashboard_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one dashboard payload asynchronously.
+ * @complexity 3
+ * @data_contract Input[dashboard_id: int] -> Output[Dict]
+ * @post Returns raw dashboard payload from Superset API.
+ */
+
+// --- get_chart_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one chart payload asynchronously.
+ * @complexity 3
+ * @data_contract Input[chart_id: int] -> Output[Dict]
+ * @post Returns raw chart payload from Superset API.
+ */
+
+// --- get_dashboard_detail_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch dashboard detail asynchronously with concurrent charts/datasets requests.
+ * @complexity 3
+ * @data_contract Input[dashboard_id: int] -> Output[Dict]
+ * @post Returns dashboard detail payload for overview page.
+ */
+
+// --- get_dashboard_permalink_state_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch stored dashboard permalink state asynchronously.
+ * @complexity 2
+ * @data_contract Input[permalink_key: str] -> Output[Dict]
+ * @post Returns dashboard permalink state payload from Superset API.
+ */
+
+// --- get_native_filter_state_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch stored native filter state asynchronously.
+ * @complexity 2
+ * @data_contract Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]
+ * @post Returns native filter state payload from Superset API.
+ */
+
+// --- extract_native_filters_from_permalink_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Extract native filters dataMask from a permalink key asynchronously.
+ * @complexity 3
+ * @data_contract Input[permalink_key: str] -> Output[Dict]
+ * @post Returns extracted dataMask with filter states.
+ */
+
+// --- extract_native_filters_from_key_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Extract native filters from a native_filters_key URL parameter asynchronously.
+ * @complexity 3
+ * @data_contract Input[dashboard_id: Union[int, str], filter_state_key: str] -> Output[Dict]
+ * @post Returns extracted filter state with extraFormData.
+ */
+
+// --- parse_dashboard_url_for_filters_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+ * @complexity 3
+ * @data_contract Input[url: str] -> Output[Dict]
+ * @post Returns extracted filter state or empty dict if no filters found.
+ */
+
+// --- AuthPackage (backend/src/core/auth/__init__.py)
+/**!
+ * @brief Authentication and authorization package root.
+ */
+
+// --- test_auth (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Unit tests for authentication module
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- test_create_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies that a persisted user can be retrieved with intact credential hash.
+ */
+
+// --- test_authenticate_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Validates authentication outcomes for valid, wrong-password, and unknown-user cases.
+ */
+
+// --- test_create_session (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Ensures session creation returns bearer token payload fields.
+ */
+
+// --- test_role_permission_association (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Confirms role-permission many-to-many assignments persist and reload correctly.
+ */
+
+// --- test_user_role_association (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Confirms user-role assignment persists and is queryable from repository reads.
+ */
+
+// --- test_ad_group_mapping (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies AD group mapping rows persist and reference the expected role.
+ */
+
+// --- test_authenticate_user_updates_last_login (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies successful authentication updates last_login audit field.
+ */
+
+// --- test_authenticate_inactive_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies inactive accounts are rejected during password authentication.
+ */
+
+// --- test_verify_password_empty_hash (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies password verification safely rejects empty or null password hashes.
+ */
+
+// --- test_provision_adfs_user_new (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies JIT provisioning creates a new ADFS user and maps group-derived roles.
+ */
+
+// --- test_provision_adfs_user_existing (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.
+ */
+
+// --- APIKeyUtilities (backend/src/core/auth/api_key.py)
+/**!
+ * @brief API key generation and hashing utilities for service-to-service authentication.
+ * @complexity 2
+ * @invariant hash_api_key() produces SHA-256 hex digest for lookup and storage.
+ * @layer Core
+ */
+
+// --- generate_api_key (backend/src/core/auth/api_key.py)
+/**!
+ * @brief Generate a new API key in ssk_ format with SHA-256 hash.
+ * @complexity 2
+ * @post Returns (raw_key, prefix, key_hash) — raw_key shown ONCE to caller, never stored.
+ * @side_effect Uses secrets.token_urlsafe(32) for cryptographic randomness.
+ */
+
+// --- hash_api_key (backend/src/core/auth/api_key.py)
+/**!
+ * @brief Hash an API key string to SHA-256 hex digest for lookup.
+ * @complexity 1
+ * @post Returns 64-character hex digest.
+ * @pre raw_key is a non-empty string.
+ */
+
+// --- AuthConfigModule (backend/src/core/auth/config.py)
+/**!
+ * @brief Centralized configuration for authentication and authorization.
+ * @complexity 2
+ * @invariant All sensitive configuration must be loaded from environment; no hardcoded secrets.
+ * @layer Core
+ * @rationale SECRET_KEY and AUTH_DATABASE_URL now crash-early if env vars are missing.
+ */
+
+// --- AuthConfig (backend/src/core/auth/config.py)
+/**!
+ * @brief Holds authentication-related settings.
+ * @post Returns a configuration object with validated settings.
+ * @pre Environment variables may be provided via .env file.
+ */
+
+// --- auth_config (backend/src/core/auth/config.py)
+/**!
+ * @brief Singleton instance of AuthConfig.
+ */
+
+// --- AuthJwtModule (backend/src/core/auth/jwt.py)
+/**!
+ * @brief JWT token generation and validation logic.
+ * @complexity 5
+ * @data_contract TokenPayload -> JWT string
+ * @invariant Tokens must include expiration time and user identifier.
+ * @layer Core
+ * @post Token encode/decode functions exported
+ * @pre JWT secret configured in environment
+ * @side_effect None
+ */
+
+// --- create_access_token (backend/src/core/auth/jwt.py)
+/**!
+ * @brief Generates a new JWT access token.
+ * @post Returns a signed JWT string.
+ * @pre data dict contains 'sub' (user_id) and optional 'scopes' (roles).
+ */
+
+// --- decode_token (backend/src/core/auth/jwt.py)
+/**!
+ * @brief Decodes and validates a JWT token.
+ * @post Returns the decoded payload if valid.
+ * @pre token is a signed JWT string.
+ */
+
+// --- AuthLoggerModule (backend/src/core/auth/logger.py)
+/**!
+ * @brief Structured auth logging module for audit trail generation.
+ * @complexity 5
+ * @data_contract AuthEvent -> LogEntry
+ * @invariant Must not log sensitive data like passwords or full tokens.
+ * @layer Core
+ * @post Audit logging functions exported
+ * @pre Auth module initialized
+ * @side_effect Writes auth audit log entries
+ */
+
+// --- log_security_event (backend/src/core/auth/logger.py)
+/**!
+ * @brief Logs a security-related event for audit trails.
+ * @post Security event is written to the application log.
+ * @pre event_type and username are strings.
+ */
+
+// --- AuthOauthModule (backend/src/core/auth/oauth.py)
+/**!
+ * @brief ADFS OIDC configuration and client using Authlib.
+ * @complexity 2
+ * @invariant Must use secure OIDC flows.
+ * @layer Core
+ */
+
+// --- oauth (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Global Authlib OAuth registry.
+ */
+
+// --- register_adfs (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Registers the ADFS OIDC client.
+ * @post ADFS client is registered in oauth registry.
+ * @pre ADFS configuration is provided in auth_config.
+ */
+
+// --- is_adfs_configured (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Checks if ADFS is properly configured.
+ * @post Returns True if ADFS client is registered, False otherwise.
+ * @pre None.
+ */
+
+// --- AuthRepositoryModule (backend/src/core/auth/repository.py)
+/**!
+ * @brief Data access layer for authentication and user preference entities.
+ * @complexity 5
+ * @data_contract Input[EXT:Library:sqlalchemy.orm.Session] -> Output[User|Role|Permission|UserDashboardPreference access]
+ * @invariant All database read/write operations must execute via the injected SQLAlchemy session boundary.
+ * @layer Domain
+ * @post Provides valid access to identity data.
+ * @pre Database connection is active.
+ * @side_effect Executes database read queries through the injected SQLAlchemy session boundary.
+ */
+
+// --- AuthRepository (backend/src/core/auth/repository.py)
+/**!
+ * @brief Provides low-level CRUD operations for identity and authorization records.
+ * @post Entity instances returned safely.
+ * @pre Database session is bound.
+ * @side_effect Performs database reads.
+ */
+
+// --- get_user_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve user by UUID.
+ * @post Returns User object if found, else None.
+ * @pre user_id is a valid UUID string.
+ */
+
+// --- get_user_by_username (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve user by username.
+ * @post Returns User object if found, else None.
+ * @pre username is a non-empty string.
+ */
+
+// --- get_role_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve role by UUID with permissions preloaded.
+ */
+
+// --- get_role_by_name (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve role by unique name.
+ */
+
+// --- get_permission_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve permission by UUID.
+ */
+
+// --- get_permission_by_resource_action (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve permission by resource and action tuple.
+ */
+
+// --- list_permissions (backend/src/core/auth/repository.py)
+/**!
+ * @brief List all system permissions.
+ */
+
+// --- get_user_dashboard_preference (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve dashboard filters/preferences for a user.
+ */
+
+// --- get_roles_by_ad_groups (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve roles that match a list of AD group names.
+ * @post Returns a list of Role objects mapped to the provided AD groups.
+ * @pre groups is a list of strings representing AD group identifiers.
+ */
+
+// --- AuthSecurityModule (backend/src/core/auth/security.py)
+/**!
+ * @brief Utility for password hashing and verification using Passlib.
+ * @complexity 2
+ * @invariant Uses bcrypt for hashing with standard work factor.
+ * @layer Core
+ */
+
+// --- verify_password (backend/src/core/auth/security.py)
+/**!
+ * @brief Verifies a plain password against a hashed password.
+ * @post Returns True if password matches, False otherwise.
+ * @pre plain_password is a string, hashed_password is a bcrypt hash.
+ */
+
+// --- get_password_hash (backend/src/core/auth/security.py)
+/**!
+ * @brief Generates a bcrypt hash for a plain password.
+ * @post Returns a secure bcrypt hash string.
+ * @pre password is a string.
+ */
+
+// --- ConfigManager (backend/src/core/config_manager.py)
+/**!
+ * @brief Manages application configuration persistence in DB with one-time migration from legacy JSON.
+ * @complexity 5
+ * @data_contract Input[json, record] -> Model[AppConfig]
+ * @invariant Configuration must always be representable by AppConfig and persisted under global record id.
+ * @layer Domain
+ * @post Configuration is loaded into memory and logger is configured.
+ * @pre Database schema for AppConfigRecord must be initialized.
+ * @side_effect Performs DB I/O and may update global logging level.
+ */
+
+// --- _apply_features_from_env (backend/src/core/config_manager.py)
+/**!
+ * @brief Read FEATURES__* env vars and apply them to a GlobalSettings features config.
+ * @rationale Env vars seed the initial defaults. After first bootstrap, DB is source of truth.
+ * @side_effect Reads os.environ; mutates settings.features in-place.
+ */
+
+// --- _default_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Build default application configuration fallback.
+ */
+
+// --- _sync_raw_payload_from_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Merge typed AppConfig state into raw payload while preserving unsupported legacy sections.
+ */
+
+// --- _load_from_legacy_file (backend/src/core/config_manager.py)
+/**!
+ * @brief Load legacy JSON configuration for migration fallback path.
+ */
+
+// --- _get_record (backend/src/core/config_manager.py)
+/**!
+ * @brief Resolve global configuration record from DB.
+ */
+
+// --- _load_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Load configuration from DB or perform one-time migration from legacy JSON.
+ */
+
+// --- _sync_environment_records (backend/src/core/config_manager.py)
+/**!
+ * @brief Mirror configured environments into the relational environments table used by FK-backed domain models.
+ */
+
+// --- _delete_stale_environment_records (backend/src/core/config_manager.py)
+/**!
+ * @brief Remove persisted environment records that are no longer in the configured environments.
+ * @post Stale Environment rows are deleted via the session (caller must commit).
+ * @pre _sync_environment_records must already have run so the query returns a current view.
+ * @side_effect Only safe to call during explicit save (_save_config_to_db), NOT during _load_config,
+ */
+
+// --- _save_config_to_db (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist provided AppConfig into the global DB configuration record.
+ */
+
+// --- save (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist current in-memory configuration state.
+ */
+
+// --- get_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Return current in-memory configuration snapshot.
+ */
+
+// --- get_payload (backend/src/core/config_manager.py)
+/**!
+ * @brief Return full persisted payload including sections outside typed AppConfig schema.
+ */
+
+// --- save_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist configuration provided either as typed AppConfig or raw payload dict.
+ */
+
+// --- update_global_settings (backend/src/core/config_manager.py)
+/**!
+ * @brief Replace global settings and persist the resulting configuration.
+ */
+
+// --- validate_path (backend/src/core/config_manager.py)
+/**!
+ * @brief Validate that path exists and is writable, creating it when absent.
+ */
+
+// --- get_environments (backend/src/core/config_manager.py)
+/**!
+ * @brief Return all configured environments.
+ */
+
+// --- has_environments (backend/src/core/config_manager.py)
+/**!
+ * @brief Check whether at least one environment exists in configuration.
+ */
+
+// --- get_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Resolve a configured environment by identifier.
+ */
+
+// --- add_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Upsert environment by id into configuration and persist.
+ */
+
+// --- update_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Update existing environment by id and preserve masked password placeholder behavior.
+ */
+
+// --- delete_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Delete environment by id and persist when deletion occurs.
+ */
+
+// --- ConfigModels (backend/src/core/config_models.py)
+/**!
+ * @brief Defines the data models for application configuration using Pydantic.
+ * @complexity 3
+ * @layer Core
+ */
+
+// --- CoreContracts (backend/src/core/config_models.py)
+/**!
+ * @brief Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.
+ * @complexity 2
+ */
+
+// --- ConnectionContracts (backend/src/core/config_models.py)
+/**!
+ * @brief Contract for database/environment connection configuration models.
+ * @complexity 2
+ */
+
+// --- Schedule (backend/src/core/config_models.py)
+/**!
+ * @brief Represents a backup schedule configuration.
+ */
+
+// --- Environment (backend/src/core/config_models.py)
+/**!
+ * @brief Represents a Superset environment configuration.
+ */
+
+// --- LoggingConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Defines the configuration for the application's logging system.
+ */
+
+// --- CleanReleaseConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Configuration for clean release compliance subsystem.
+ */
+
+// --- FeaturesConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Top-level feature flags that toggle entire project features on/off.
+ * @complexity 1
+ * @rationale Features are read from environment variables on bootstrap and persisted in DB.
+ */
+
+// --- GlobalSettings (backend/src/core/config_models.py)
+/**!
+ * @brief Represents global application settings.
+ */
+
+// --- AppConfig (backend/src/core/config_models.py)
+/**!
+ * @brief The root configuration model containing all application settings.
+ */
+
+// --- CotLoggerModule (backend/src/core/cot_logger.py)
+/**!
+ * @brief Structured JSON logger implementing the molecular CoT (Chain-of-Thought) logging protocol.
+ * @complexity 4
+ */
+
+// --- cot_trace_context (backend/src/core/cot_logger.py)
+/**!
+ * @brief ContextVars for trace ID and span ID propagation across async boundaries.
+ * @complexity 1
+ */
+
+// --- cot_logger_instance (backend/src/core/cot_logger.py)
+/**!
+ * @brief Dedicated Python logger for all CoT (molecular) log output.
+ * @complexity 1
+ */
+
+// --- seed_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Generate a new UUID4 trace_id, set it in ContextVar, and return it.
+ * @complexity 1
+ */
+
+// --- set_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Set an explicit trace_id into the ContextVar (e.g. from an incoming header).
+ * @complexity 1
+ */
+
+// --- get_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Get the current trace_id from ContextVar.
+ * @complexity 1
+ */
+
+// --- push_span (backend/src/core/cot_logger.py)
+/**!
+ * @brief Set a new span_id in ContextVar and return the previous span_id for later restoration.
+ * @complexity 1
+ */
+
+// --- pop_span (backend/src/core/cot_logger.py)
+/**!
+ * @brief Restore a previous span_id into the ContextVar.
+ * @complexity 1
+ */
+
+// --- cot_log_function (backend/src/core/cot_logger.py)
+/**!
+ * @brief Core structured logging function that emits a single-line JSON record.
+ * @complexity 2
+ */
+
+// --- MarkerLogger (backend/src/core/cot_logger.py)
+/**!
+ * @brief Thin proxy class providing .reason(), .reflect(), .explore() convenience methods.
+ * @complexity 2
+ */
+
+// --- MarkerLogger.__init__ (backend/src/core/cot_logger.py)
+/**!
+ * @brief Store the module/component name used as the 'src' field in all log calls.
+ */
+
+// --- MarkerLogger.reason (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log a REASON marker — strict deduction, core logic.
+ */
+
+// --- MarkerLogger.reflect (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log a REFLECT marker — self-check, structural validation.
+ */
+
+// --- MarkerLogger.explore (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log an EXPLORE marker — searching, alternatives, violated assumptions.
+ */
+
+// --- DatabaseModule (backend/src/core/database.py)
+/**!
+ * @brief Configures database connection and session management (PostgreSQL-first).
+ * @complexity 3
+ * @invariant A single engine instance is used for the entire application.
+ * @layer Infrastructure
+ */
+
+// --- BASE_DIR (backend/src/core/database.py)
+/**!
+ * @brief Base directory for the backend.
+ * @complexity 1
+ */
+
+// --- DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the main application database. Read from env; dev fallback only.
+ * @complexity 1
+ * @rationale DATABASE_URL reads from env (DATABASE_URL or POSTGRES_URL).
+ */
+
+// --- TASKS_DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the tasks execution database.
+ * @complexity 1
+ */
+
+// --- AUTH_DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the authentication database.
+ * @complexity 1
+ */
+
+// --- engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for mappings database.
+ * @complexity 1
+ * @side_effect Creates database engine and manages connection pool.
+ */
+
+// --- tasks_engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for tasks database.
+ * @complexity 1
+ */
+
+// --- auth_engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for authentication database.
+ * @complexity 1
+ */
+
+// --- SessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the main mappings database.
+ * @complexity 1
+ * @pre engine is initialized.
+ */
+
+// --- TasksSessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the tasks execution database.
+ * @complexity 1
+ * @pre tasks_engine is initialized.
+ */
+
+// --- AuthSessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the authentication database.
+ * @complexity 1
+ * @pre auth_engine is initialized.
+ */
+
+// --- _ensure_user_dashboard_preferences_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for user_dashboard_preferences table.
+ * @complexity 3
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database where profile table is stored.
+ */
+
+// --- _ensure_user_dashboard_preferences_health_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for user_dashboard_preferences table (health fields).
+ * @complexity 3
+ */
+
+// --- _ensure_llm_validation_results_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for llm_validation_results table.
+ * @complexity 3
+ */
+
+// --- _ensure_git_server_configs_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for git_server_configs table.
+ * @complexity 3
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database.
+ */
+
+// --- _ensure_auth_users_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for auth users table.
+ * @complexity 3
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to authentication database.
+ */
+
+// --- _ensure_filter_source_enum_values (backend/src/core/database.py)
+/**!
+ * @brief Adds missing FilterSource enum values to the PostgreSQL native filtersource type.
+ * @complexity 3
+ * @post New enum values are available without data loss.
+ * @pre bind_engine points to application database with imported_filters table.
+ */
+
+// --- _ensure_dataset_review_session_columns (backend/src/core/database.py)
+/**!
+ * @brief Apply additive schema upgrades for dataset review persistence required by optimistic-lock and recovery metadata semantics.
+ * @complexity 4
+ * @post Missing additive columns across legacy dataset review tables are created without removing existing data.
+ * @pre bind_engine points to the application database where dataset review tables are stored.
+ * @side_effect Executes ALTER TABLE statements against dataset review tables in the application database.
+ */
+
+// --- _ensure_translation_schedules_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for translation_schedules table.
+ * @complexity 3
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database.
+ */
+
+// --- _ensure_dictionary_entries_columns (backend/src/core/database.py)
+/**!
+ * @brief Additive migration for dictionary_entries origin tracking columns.
+ * @complexity 3
+ */
+
+// --- init_db (backend/src/core/database.py)
+/**!
+ * @brief Initializes the database by creating all tables.
+ * @complexity 3
+ * @post Database tables created in all databases.
+ * @pre engine, tasks_engine and auth_engine are initialized.
+ * @side_effect Creates physical database files if they don't exist.
+ */
+
+// --- get_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting a database session.
+ * @complexity 3
+ * @post Session is closed after use.
+ * @pre SessionLocal is initialized.
+ */
+
+// --- get_tasks_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting a tasks database session.
+ * @complexity 3
+ * @post Session is closed after use.
+ * @pre TasksSessionLocal is initialized.
+ */
+
+// --- get_auth_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting an authentication database session.
+ * @complexity 3
+ * @data_contract None -> Output[EXT:Library:sqlalchemy.orm.Session]
+ * @post Session is closed after use.
+ * @pre AuthSessionLocal is initialized.
+ */
+
+// --- EncryptionKeyModule (backend/src/core/encryption_key.py)
+/**!
+ * @brief Resolve and persist the Fernet encryption key required by runtime services.
+ * @complexity 5
+ * @data_contract Input[env_file_path] -> Output[encryption_key]
+ * @invariant Runtime key resolution never falls back to an ephemeral secret.
+ * @layer Infrastructure
+ * @post A valid Fernet key is available to runtime services via ENCRYPTION_KEY.
+ * @pre Runtime environment can read process variables and target .env path is writable when key generation is required.
+ * @rationale Replaced Path(__file__).parents[2] with BASE_DIR import from database.py — same result, avoids recomputing path traversal.
+ * @side_effect May append ENCRYPTION_KEY entry into backend .env file and set process environment variable.
+ */
+
+// --- ensure_encryption_key (backend/src/core/encryption_key.py)
+/**!
+ * @brief Ensure backend runtime has a persistent valid Fernet key.
+ * @post Returns a valid Fernet key and guarantees it is present in process environment.
+ * @pre env_file_path points to a writable backend .env file or ENCRYPTION_KEY exists in process environment.
+ * @side_effect May create or append backend/.env when key is missing.
+ */
+
+// --- LoggerModule (backend/src/core/logger.py)
+/**!
+ * @brief Application logging system with CotJsonFormatter producing molecular CoT JSON output.
+ * @complexity 5
+ * @data_contract All log records conform to molecular CoT JSON schema: {ts, level, trace_id, src, marker, intent, span_id?, payload?, error?}
+ * @invariant CotJsonFormatter.format() always returns valid single-line JSON string.
+ * @layer Core
+ * @post All log output is single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+ * @pre Python 3.7+ with cot_logger ContextVars available.
+ * @rationale Replaced BeliefFormatter text-based [Entry]/[Exit]/[Action] logging with CotJsonFormatter JSON output. Old format was not machine-parseable and mixed presentation with intent. CotJsonFormatter produces structured JSON consistent with cot_logger.py MarkerLogger protocol.
+ * @rejected Keeping both formatters side-by-side was rejected (two inconsistent output formats would confuse log consumers).
+ * @side_effect Configures global logger handlers and formatters; seeds global _enable_belief_state and _task_log_level; writes JSON to console/files.
+ */
+
+// --- CotJsonFormatter (backend/src/core/logger.py)
+/**!
+ * @brief JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+ * @complexity 3
+ */
+
+// --- CotJsonFormatter.format (backend/src/core/logger.py)
+/**!
+ * @brief Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.
+ * @complexity 2
+ * @invariant Output is always valid single-line JSON.
+ */
+
+// --- BeliefFormatter (backend/src/core/logger.py)
+/**!
+ * @brief Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.
+ * @complexity 2
+ * @rationale Kept for backward compatibility; may be used by external consumers of this module.
+ */
+
+// --- LogEntry (backend/src/core/logger.py)
+/**!
+ * @brief A Pydantic model representing a single, structured log entry.
+ * @complexity 1
+ */
+
+// --- belief_scope (backend/src/core/logger.py)
+/**!
+ * @brief Context manager for Molecular CoT structured logging. Uses cot_logger.log() for JSON output.
+ * @complexity 3
+ * @post Thread-local belief state is updated; REASON/REFLECT/EXPLORE markers emitted via structured JSON logger.
+ * @pre anchor_id must be provided.
+ */
+
+// --- configure_logger (backend/src/core/logger.py)
+/**!
+ * @brief Configures the main logger and the CoT logger with CotJsonFormatter, file handlers, and global flags.
+ * @complexity 4
+ * @post Logger levels, handlers, formatters, belief state flag, and task log level are updated.
+ * @pre config is a valid LoggingConfig instance.
+ * @side_effect Mutates global _enable_belief_state, _task_log_level; adds/removes handlers on both logger and cot_logger; creates file directories.
+ */
+
+// --- get_task_log_level (backend/src/core/logger.py)
+/**!
+ * @brief Returns the current task log level filter.
+ * @complexity 1
+ */
+
+// --- should_log_task_level (backend/src/core/logger.py)
+/**!
+ * @brief Checks if a log level should be recorded based on task_log_level setting.
+ * @complexity 1
+ */
+
+// --- Logger (backend/src/core/logger.py)
+/**!
+ * @brief The global application logger instance configured with CotJsonFormatter, console handler, and WebSocketLogHandler.
+ * @complexity 2
+ */
+
+// --- believed (backend/src/core/logger.py)
+/**!
+ * @brief A decorator that wraps a function in a belief scope.
+ * @complexity 2
+ */
+
+// --- explore (backend/src/core/logger.py)
+/**!
+ * @brief Logs an EXPLORE marker (WARNING level) with structured extra data for CotJsonFormatter.
+ * @complexity 2
+ */
+
+// --- reason (backend/src/core/logger.py)
+/**!
+ * @brief Logs a REASON marker (DEBUG level) with structured extra data for CotJsonFormatter.
+ * @complexity 2
+ */
+
+// --- reflect (backend/src/core/logger.py)
+/**!
+ * @brief Logs a REFLECT marker (DEBUG level) with structured extra data for CotJsonFormatter.
+ * @complexity 2
+ */
+
+// --- test_logger (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Unit tests for logger module
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- test_belief_scope_logs_reason_reflect_at_debug (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.
+ * @post Logs are verified to contain REASON and REFLECT markers at DEBUG level.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_error_handling (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs EXPLORE on exception.
+ * @post Logs are verified to contain EXPLORE marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_success_reflect (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs REFLECT on success.
+ * @post Logs are verified to contain REFLECT marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_not_visible_at_info (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope REFLECT logs are NOT visible at INFO level.
+ * @post REASON is visible at INFO (uses info()); REFLECT is not (uses debug()).
+ * @pre belief_scope is available. caplog fixture is used.
+ */
+
+// --- test_task_log_level_default (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that default task log level is INFO.
+ * @post Default level is INFO.
+ * @pre None.
+ */
+
+// --- test_should_log_task_level (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that should_log_task_level correctly filters log levels.
+ * @post Filtering works correctly for all level combinations.
+ * @pre None.
+ */
+
+// --- test_configure_logger_task_log_level (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that configure_logger updates task_log_level.
+ * @post task_log_level is updated correctly.
+ * @pre LoggingConfig is available.
+ */
+
+// --- test_enable_belief_state_flag (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that enable_belief_state flag controls belief_scope logging.
+ * @post belief_scope explicit REASON logs are controlled by the flag; REFLECT always logged.
+ * @pre LoggingConfig is available. caplog fixture is used.
+ */
+
+// --- test_belief_scope_missing_anchor (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test @PRE condition: anchor_id must be provided
+ */
+
+// --- test_configure_logger_post_conditions (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test @POST condition: Logger level, handlers, belief state flag, and task log level are updated.
+ */
+
+// --- IdMappingServiceModule (backend/src/core/mapping_service.py)
+/**!
+ * @brief Service for tracking and synchronizing Superset Resource IDs (UUID <-> Integer ID)
+ * @complexity 5
+ * @data_contract Input[environment_id, resource_type, uuid] -> Output[remote_integer_id|None]
+ * @invariant sync_environment must handle remote API failures gracefully.
+ * @layer Core
+ * @post Mapping synchronization and lookup APIs are available for environment-scoped UUID-to-integer resolution.
+ * @pre Database session is valid and Superset client factory returns authenticated clients for requested environments.
+ * @side_effect Reads/writes ResourceMapping rows, emits logs, and schedules periodic sync jobs.
+ * @test_data mock_superset_resources -> {'chart': [{'id': 42, 'uuid': '1234', 'slice_name': 'test'}], 'dataset': [{'id': 99, 'uuid': '5678', 'table_name': 'data'}]}
+ */
+
+// --- IdMappingService (backend/src/core/mapping_service.py)
+/**!
+ * @brief Service handling the cataloging and retrieval of remote Superset Integer IDs.
+ * @complexity 5
+ * @data_contract Input[db_session] -> Output[IdMappingService]
+ * @invariant self.db remains the authoritative session for all mapping operations.
+ * @post Service instance provides scheduler control and environment-scoped mapping synchronization APIs.
+ * @pre db_session is an active SQLAlchemy Session bound to mapping tables.
+ * @side_effect Instantiates an in-process scheduler and performs database writes during sync cycles.
+ * @test_contract IdMappingServiceModel ->
+ */
+
+// --- start_scheduler (backend/src/core/mapping_service.py)
+/**!
+ * @brief Starts the background scheduler with a given cron string.
+ * @param superset_client_factory - Function to get a client for an environment.
+ */
+
+// --- sync_environment (backend/src/core/mapping_service.py)
+/**!
+ * @brief Fully synchronizes mapping for a specific environment.
+ * @param superset_client - Instance capable of hitting the Superset API.
+ * @post ResourceMapping records for the environment are created or updated.
+ * @pre environment_id exists in the database.
+ */
+
+// --- get_remote_id (backend/src/core/mapping_service.py)
+/**!
+ * @brief Retrieves the remote integer ID for a given universal UUID.
+ * @param uuid (str)
+ * @return Optional[int]
+ */
+
+// --- get_remote_ids_batch (backend/src/core/mapping_service.py)
+/**!
+ * @brief Retrieves remote integer IDs for a list of universal UUIDs efficiently.
+ * @param uuids (List[str])
+ * @return Dict[str, int] - Mapping of UUID -> Integer ID
+ */
+
+// --- middleware_package (backend/src/core/middleware/__init__.py)
+/**!
+ * @brief FastAPI/Starlette middleware package for request-level context and tracing.
+ * @complexity 1
+ */
+
+// --- TraceContextMiddlewareModule (backend/src/core/middleware/trace.py)
+/**!
+ * @brief FastAPI/Starlette middleware that seeds a trace_id for every incoming HTTP request.
+ * @complexity 3
+ */
+
+// --- TraceContextMiddleware (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Starlette BaseHTTPMiddleware that seeds a trace_id per request.
+ * @complexity 2
+ */
+
+// --- TraceContextMiddleware.__init__ (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Standard BaseHTTPMiddleware initialiser.
+ */
+
+// --- TraceContextMiddleware.dispatch (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Dispatch handler that seeds trace_id before passing to the next middleware.
+ * @complexity 2
+ */
+
+// --- MigrationPackage (backend/src/core/migration/__init__.py)
+/**!
+ */
+
+// --- MigrationArchiveParserModule (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Parse Superset export ZIP archives into normalized object catalogs for diffing.
+ * @complexity 5
+ * @data_contract ArchivePath -> ParsedMigration
+ * @invariant Parsing is read-only and never mutates archive files.
+ * @layer Domain
+ * @post Parsed migration archive returned
+ * @pre Archive file path is valid and readable
+ * @side_effect Reads archive file (read-only)
+ */
+
+// --- MigrationArchiveParser (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Extract normalized dashboards/charts/datasets metadata from ZIP archives.
+ */
+
+// --- extract_objects_from_zip (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Extract object catalogs from Superset archive.
+ * @post Returns object lists grouped by resource type.
+ * @pre zip_path points to a valid readable ZIP.
+ * @return Dict[str, List[Dict[str, Any]]]
+ */
+
+// --- _collect_yaml_objects (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Read and normalize YAML manifests for one object type.
+ * @post Returns only valid normalized objects.
+ * @pre object_type is one of dashboards/charts/datasets.
+ */
+
+// --- _normalize_object_payload (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Convert raw YAML payload to stable diff signature shape.
+ * @post Returns normalized descriptor with `uuid`, `title`, and `signature`.
+ * @pre payload is parsed YAML mapping.
+ */
+
+// --- MigrationDryRunOrchestratorModule (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Compute pre-flight migration diff and risk scoring without apply.
+ * @complexity 5
+ * @data_contract EnvironmentConfig -> MigrationDiffReport
+ * @invariant Dry run is informative only and must not mutate target environment.
+ * @layer Domain
+ * @post Dry-run diff returned without mutation
+ * @pre Source and target environments configured
+ * @side_effect Reads source environment (read-only)
+ */
+
+// --- MigrationDryRunService (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build deterministic diff/risk payload for migration pre-flight.
+ */
+
+// --- run (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Execute full dry-run computation for selected dashboards.
+ * @post Returns JSON-serializable pre-flight payload with summary, diff and risk.
+ * @pre source/target clients are authenticated and selection validated by caller.
+ * @side_effect Reads source export archives and target metadata via network.
+ */
+
+// --- _load_db_mapping (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Resolve UUID mapping for optional DB config replacement.
+ */
+
+// --- _accumulate_objects (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Merge extracted resources by UUID to avoid duplicates.
+ */
+
+// --- _index_by_uuid (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build UUID-index map for normalized resources.
+ */
+
+// --- _build_object_diff (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Compute create/update/delete buckets by UUID+signature.
+ */
+
+// --- _build_target_signatures (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Pull target metadata and normalize it into comparable signatures.
+ */
+
+// --- _build_risks (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build risk items for missing datasource, broken refs, overwrite, owner mismatch.
+ */
+
+// --- RiskAssessorModule (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Compute deterministic migration risk items and aggregate score for dry-run reporting.
+ * @complexity 5
+ * @data_contract Module[build_risks, score_risks]
+ * @invariant Risk scoring must remain bounded to [0,100] and preserve severity-to-weight mapping.
+ * @layer Domain
+ * @post Risk scoring output preserves item list and provides bounded score with derived level.
+ * @pre Risk assessor functions receive normalized migration object collections from dry-run orchestration.
+ * @side_effect Emits diagnostic logs and performs read-only metadata requests via Superset client.
+ * @test_contract [source_objects,target_objects,diff,target_client] -> [List[RiskItem]]
+ * @test_edge [external_fail] -> [target_client get_databases exception propagates to caller]
+ * @test_invariant [score_upper_bound_100] -> VERIFIED_BY: [severity_weight_aggregation]
+ * @test_scenario [owner_mismatch_dashboard] -> [low owner_mismatch risk is emitted]
+ * @ux_feedback [N/A] -> [No direct UI side effects in this module]
+ * @ux_reactivity [N/A] -> [Backend synchronous function contracts]
+ * @ux_recovery [N/A] -> [Caller-level retry/recovery]
+ * @ux_state [Idle] -> [N/A backend domain module]
+ */
+
+// --- index_by_uuid (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Build UUID-index from normalized objects.
+ * @data_contract List[Dict[str, Any]] -> Dict[str, Dict[str, Any]]
+ * @post Returns mapping keyed by string uuid; only truthy uuid values are included.
+ * @pre Input list items are dict-like payloads potentially containing "uuid".
+ * @side_effect Emits reasoning/reflective logs only.
+ */
+
+// --- extract_owner_identifiers (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Normalize owner payloads for stable comparison.
+ * @data_contract Any -> List[str]
+ * @post Returns sorted unique owner identifiers as strings.
+ * @pre Owners may be list payload, scalar values, or None.
+ * @side_effect Emits reasoning/reflective logs only.
+ */
+
+// --- build_risks (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Build risk list from computed diffs and target catalog state.
+ * @data_contract ) -> List[Dict[str, Any]]
+ * @post Returns list of deterministic risk items derived from overwrite, missing datasource, reference, and owner mismatch checks.
+ * @pre target_client is authenticated/usable for database list retrieval.
+ * @side_effect Calls target Superset API for databases metadata and emits logs.
+ */
+
+// --- score_risks (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Aggregate risk list into score and level.
+ * @data_contract List[Dict[str, Any]] -> Dict[str, Any]
+ * @post Returns dict with score in [0,100], derived level, and original items.
+ * @pre risk_items contains optional severity fields expected in {high,medium,low} or defaults to low weight.
+ * @side_effect Emits reasoning/reflective logs only.
+ */
+
+// --- MigrationEngineModule (backend/src/core/migration_engine.py)
+/**!
+ * @brief Transforms Superset export ZIP archives while preserving archive integrity and patching mapped identifiers.
+ * @complexity 5
+ * @data_contract Input[zip_path, output_path, db_mapping, target_env_id?, fix_cross_filters?] -> Output[Transformed Superset archive]
+ * @invariant ZIP structure and non-targeted metadata must remain valid after transformation.
+ * @layer Domain
+ * @post Migration engine contracts preserve ZIP integrity while exposing transformation entrypoints for import pipelines.
+ * @pre Input archives are readable Superset exports and optional mapping collaborators expose remote id lookup APIs.
+ * @side_effect Reads and writes temporary archive contents during transformation workflows and emits structured belief-state logs.
+ */
+
+// --- MigrationEngine (backend/src/core/migration_engine.py)
+/**!
+ * @brief Engine for transforming Superset export ZIPs.
+ */
+
+// --- transform_zip (backend/src/core/migration_engine.py)
+/**!
+ * @brief Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.
+ * @data_contract Input[(str zip_path, str output_path, Dict[str,str] db_mapping, bool strip_databases, Optional[str] target_env_id, bool fix_cross_filters)] -> Output[bool]
+ * @param fix_cross_filters (bool) - Whether to patch dashboard json_metadata.
+ * @post Returns True only when extraction, transformation, and packaging complete without exception.
+ * @pre zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.
+ * @return bool - True if successful.
+ * @side_effect Reads/writes filesystem archives, creates temporary directory, emits structured logs.
+ */
+
+// --- _transform_yaml (backend/src/core/migration_engine.py)
+/**!
+ * @brief Replaces database_uuid in a single YAML file.
+ * @data_contract Input[(Path file_path, Dict[str,str] db_mapping)] -> Output[None]
+ * @param db_mapping (Dict[str, str]) - UUID mapping dictionary.
+ * @post database_uuid is replaced in-place only when source UUID is present in db_mapping.
+ * @pre file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.
+ * @side_effect Reads and conditionally rewrites YAML file on disk.
+ */
+
+// --- _extract_chart_uuids_from_archive (backend/src/core/migration_engine.py)
+/**!
+ * @brief Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.
+ * @data_contract Input[Path] -> Output[Dict[int,str]]
+ * @param temp_dir (Path) - Root dir of unpacked archive.
+ * @post Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.
+ * @pre temp_dir exists and points to extracted archive root with optional chart YAML resources.
+ * @return Dict[int, str] - Mapping of source Integer ID to UUID.
+ * @side_effect Reads chart YAML files from filesystem; suppresses per-file parsing failures.
+ */
+
+// --- _patch_dashboard_metadata (backend/src/core/migration_engine.py)
+/**!
+ * @brief Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.
+ * @data_contract Input[(Path file_path, str target_env_id, Dict[int,str] source_map)] -> Output[None]
+ * @param source_map (Dict[int, str])
+ * @post json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.
+ * @pre file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.
+ * @side_effect Reads/writes YAML file, performs mapping lookup via mapping_service, emits logs for recoverable/terminal failures.
+ */
+
+// --- PluginBase (backend/src/core/plugin_base.py)
+/**!
+ * @brief PluginLoader scans for subclasses of PluginBase.
+ * @invariant All plugins MUST inherit from this class.
+ * @layer Core
+ */
+
+// --- id (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the unique identifier for the plugin.
+ * @post Returns string ID.
+ * @pre Plugin instance exists.
+ * @return str - Plugin ID.
+ */
+
+// --- name (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the human-readable name of the plugin.
+ * @post Returns string name.
+ * @pre Plugin instance exists.
+ * @return str - Plugin name.
+ */
+
+// --- description (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns a brief description of the plugin.
+ * @post Returns string description.
+ * @pre Plugin instance exists.
+ * @return str - Plugin description.
+ */
+
+// --- version (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the version of the plugin.
+ * @post Returns string version.
+ * @pre Plugin instance exists.
+ * @return str - Plugin version.
+ */
+
+// --- required_permission (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the required permission string to execute this plugin.
+ * @post Returns string permission.
+ * @pre Plugin instance exists.
+ * @return str - Required permission (e.g., "plugin:backup:execute").
+ */
+
+// --- ui_route (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the frontend route for the plugin's UI, if applicable.
+ * @post Returns string route or None.
+ * @pre Plugin instance exists.
+ * @return Optional[str] - Frontend route.
+ */
+
+// --- get_schema (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the JSON schema for the plugin's input parameters.
+ * @post Returns dict schema.
+ * @pre Plugin instance exists.
+ * @return Dict[str, Any] - JSON schema.
+ */
+
+// --- execute (backend/src/core/plugin_base.py)
+/**!
+ * @brief Executes the plugin's core logic.
+ * @param params (Dict[str, Any]) - Validated input parameters.
+ * @post Plugin execution is completed.
+ * @pre params must be a dictionary.
+ */
+
+// --- PluginConfig (backend/src/core/plugin_base.py)
+/**!
+ * @brief Validated PluginConfig exposed to API layer.
+ * @layer Core
+ */
+
+// --- PluginLoader (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Discovers and manages available PluginBase implementations.
+ * @complexity 3
+ * @layer Core
+ * @rationale Replaced print() with _logger calls to eliminate silent failures. Added top-level logger import, removed late imports.
+ * @rejected Keeping print() statements with "Replace with proper logging" comments was rejected — they produce no structured output and cannot be filtered by log level.
+ */
+
+// --- _load_plugins (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Scans the plugin directory and loads all valid plugins.
+ * @post _load_module is called for each .py file.
+ * @pre plugin_dir exists or can be created.
+ */
+
+// --- _load_module (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Loads a single Python module and discovers PluginBase implementations.
+ * @param file_path (str) - The path to the module file.
+ * @post Plugin classes are instantiated and registered.
+ * @pre module_name and file_path are valid.
+ */
+
+// --- _register_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Registers a PluginBase instance and its configuration.
+ * @param plugin_instance (PluginBase) - The plugin instance to register.
+ * @post Plugin is added to _plugins and _plugin_configs.
+ * @pre plugin_instance is a valid implementation of PluginBase.
+ */
+
+// --- get_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Retrieves a loaded plugin instance by its ID.
+ * @param plugin_id (str) - The unique identifier of the plugin.
+ * @post Returns plugin instance or None.
+ * @pre plugin_id is a string.
+ * @return Optional[PluginBase] - The plugin instance if found, otherwise None.
+ */
+
+// --- get_all_plugin_configs (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Returns a list of all registered plugin configurations.
+ * @post Returns list of all PluginConfig objects.
+ * @pre None.
+ * @return List[PluginConfig] - A list of plugin configurations.
+ */
+
+// --- has_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Checks if a plugin with the given ID is registered.
+ * @param plugin_id (str) - The unique identifier of the plugin.
+ * @post Returns True if plugin exists.
+ * @pre plugin_id is a string.
+ * @return bool - True if the plugin is registered, False otherwise.
+ */
+
+// --- SchedulerModule (backend/src/core/scheduler.py)
+/**!
+ * @brief Manages scheduled tasks using APScheduler.
+ * @complexity 3
+ * @layer Core
+ */
+
+// --- SchedulerService (backend/src/core/scheduler.py)
+/**!
+ * @brief Provides a service to manage scheduled backup tasks.
+ * @complexity 3
+ */
+
+// --- start (backend/src/core/scheduler.py)
+/**!
+ * @brief Starts the background scheduler and loads initial schedules.
+ * @post Scheduler is running and schedules are loaded.
+ * @pre Scheduler should be initialized.
+ */
+
+// --- stop (backend/src/core/scheduler.py)
+/**!
+ * @brief Stops the background scheduler.
+ * @post Scheduler is shut down.
+ * @pre Scheduler should be running.
+ */
+
+// --- load_schedules (backend/src/core/scheduler.py)
+/**!
+ * @brief Load backup and active translation schedules from config and DB, re-registering all jobs.
+ * @complexity 4
+ * @post All enabled backup jobs and active translation schedules are re-registered in APScheduler.
+ * @pre config_manager must have valid configuration; database is accessible.
+ * @side_effect Removes all existing APScheduler jobs; queries translation_schedules table; registers APScheduler jobs for translation.
+ */
+
+// --- add_backup_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Adds a scheduled backup job for an environment.
+ * @param cron_expression (str) - The cron expression for the schedule.
+ * @post A new job is added to the scheduler or replaced if it already exists.
+ * @pre env_id and cron_expression must be valid strings.
+ */
+
+// --- add_translation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Register a translation schedule with APScheduler.
+ * @complexity 4
+ * @post A new APScheduler job is registered or replaced if it already exists.
+ * @pre schedule_id, job_id, and cron_expression are valid strings.
+ * @side_effect Mutates APScheduler state; calls execute_scheduled_translation on trigger.
+ */
+
+// --- remove_translation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Remove a translation schedule from APScheduler.
+ * @complexity 4
+ * @post The APScheduler job is removed if it exists; silently ignored otherwise.
+ * @pre schedule_id is a valid string.
+ * @side_effect Mutates APScheduler state.
+ */
+
+// --- _trigger_backup (backend/src/core/scheduler.py)
+/**!
+ * @brief Triggered by the scheduler to start a backup task.
+ * @param env_id (str) - The ID of the environment.
+ * @post A new backup task is created in the task manager if not already running.
+ * @pre env_id must be a valid environment ID.
+ */
+
+// --- add_validation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Register a validation policy schedule with APScheduler.
+ * @complexity 3
+ * @post A new APScheduler job is registered or replaced if it already exists.
+ * @pre policy_id and cron_expression are valid strings.
+ * @side_effect Mutates APScheduler state; calls _trigger_validation on trigger.
+ */
+
+// --- remove_validation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Remove a validation policy schedule from APScheduler.
+ * @complexity 2
+ * @post The APScheduler job is removed if it exists; silently ignored otherwise.
+ * @pre policy_id is a valid string.
+ * @side_effect Mutates APScheduler state.
+ */
+
+// --- reload_validation_policy (backend/src/core/scheduler.py)
+/**!
+ * @brief Reload a single validation policy schedule — calls remove then add.
+ * @complexity 2
+ * @post Old job is removed; new job is registered if policy is active and has schedule_days.
+ * @pre policy_id is a valid ValidationPolicy id with schedule data in DB.
+ * @side_effect Mutates APScheduler state; queries ValidationPolicy from DB.
+ */
+
+// --- _trigger_validation (backend/src/core/scheduler.py)
+/**!
+ * @brief APScheduler job handler — triggers validation runs for a policy.
+ * @complexity 3
+ * @post A validation task is spawned via TaskManager for each dashboard in the policy.
+ * @pre policy_id is a valid ValidationPolicy id with dashboard_ids.
+ * @side_effect Creates TaskRecord entries for validation runs; logs progress.
+ */
+
+// --- ThrottledSchedulerConfigurator (backend/src/core/scheduler.py)
+/**!
+ * @brief Distributes validation tasks evenly within an execution window.
+ * @complexity 5
+ * @data_contract Input[window_start, window_end, dashboard_ids, current_date] -> Output[List[EXT:Python:datetime]]
+ * @invariant Returned schedule size always matches number of dashboard IDs.
+ * @post Produces deterministic per-dashboard run timestamps within the configured window.
+ * @pre Validation policies provide a finite dashboard list and a valid execution window.
+ * @side_effect Emits warning logs for degenerate or near-zero scheduling windows.
+ */
+
+// --- calculate_schedule (backend/src/core/scheduler.py)
+/**!
+ * @brief Calculates execution times for N tasks within a window.
+ * @invariant Tasks are distributed with near-even spacing.
+ * @post Returns List[EXT:Python:datetime] of scheduled times.
+ * @pre window_start, window_end (time), dashboard_ids (List), current_date (date).
+ */
+
+// --- SupersetClientModule (backend/src/core/superset_client/__init__.py)
+/**!
+ * @brief Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
+ * @complexity 5
+ * @invariant All network operations must use the internal APIClient instance.
+ * @layer Service
+ * @public_api SupersetClient
+ * @rationale Decomposed from monolithic superset_client.py (2145 lines) into
+ */
+
+// --- SupersetClient (backend/src/core/superset_client/__init__.py)
+/**!
+ * @brief Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
+ * @complexity 3
+ */
+
+// --- SupersetClientBase (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Base class for SupersetClient providing initialization, authentication, pagination, and import/export helpers.
+ * @complexity 3
+ * @layer Infrastructure
+ * @rationale Extracted magic number 100 into DEFAULT_PAGE_SIZE constant at module level. Value unchanged — Superset API caps page_size at 100.
+ */
+
+// --- SupersetClientInit (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
+ * @complexity 3
+ */
+
+// --- SupersetClientAuthenticate (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Authenticates the client using the configured credentials.
+ * @complexity 3
+ */
+
+// --- SupersetClientHeaders (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
+ * @complexity 1
+ */
+
+// --- SupersetClientValidateQueryParams (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Ensures query parameters have default page and page_size.
+ * @complexity 1
+ */
+
+// --- SupersetClientFetchTotalObjectCount (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Fetches the total number of items for a given endpoint.
+ * @complexity 1
+ */
+
+// --- SupersetClientFetchAllPages (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Iterates through all pages to collect all data items.
+ * @complexity 1
+ */
+
+// --- SupersetClientDoImport (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Performs the actual multipart upload for import.
+ * @complexity 1
+ */
+
+// --- SupersetClientValidateExportResponse (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Validates that the export response is a non-empty ZIP archive.
+ * @complexity 1
+ */
+
+// --- SupersetClientResolveExportFilename (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Determines the filename for an exported dashboard.
+ * @complexity 1
+ */
+
+// --- SupersetClientValidateImportFile (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Validates that the file to be imported is a valid ZIP with metadata.yaml.
+ * @complexity 1
+ */
+
+// --- SupersetClientResolveTargetIdForDelete (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Resolves a dashboard ID from either an ID or a slug.
+ * @complexity 1
+ */
+
+// --- SupersetClientGetAllResources (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Fetches all resources of a given type with id, uuid, and name columns.
+ * @complexity 3
+ */
+
+// --- SupersetChartsMixin (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Chart domain mixin for SupersetClient — list, get, extract IDs from layout.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientGetChart (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Fetches a single chart by ID.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetCharts (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Fetches all charts with pagination support.
+ * @complexity 3
+ */
+
+// --- SupersetClientExtractChartIdsFromLayout (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Traverses dashboard layout metadata and extracts chart IDs from common keys.
+ * @complexity 1
+ */
+
+// --- SupersetDashboardsCrudMixin (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Dashboard CRUD mixin for SupersetClient — detail, export, import, delete.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientGetDashboardDetail (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Fetches detailed dashboard information including related charts and datasets.
+ * @complexity 3
+ */
+
+// --- extract_dataset_id_from_form_data (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ */
+
+// --- SupersetClientExportDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Экспортирует дашборд в виде ZIP-архива.
+ * @complexity 3
+ * @side_effect Performs network I/O to download archive.
+ */
+
+// --- SupersetClientImportDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Импортирует дашборд из ZIP-файла.
+ * @complexity 3
+ * @side_effect Performs network I/O to upload archive.
+ */
+
+// --- SupersetClientDeleteDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Удаляет дашборд по его ID или slug.
+ * @complexity 3
+ * @side_effect Deletes resource from upstream Superset environment.
+ */
+
+// --- SupersetDashboardsFiltersMixin (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Dashboard native filter extraction mixin for SupersetClient.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientGetDashboard (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches a single dashboard by ID or slug.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDashboardPermalinkState (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches stored dashboard permalink state by permalink key.
+ * @complexity 2
+ */
+
+// --- SupersetClientGetNativeFilterState (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches stored native filter state by filter state key.
+ * @complexity 2
+ */
+
+// --- SupersetClientExtractNativeFiltersFromPermalink (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Extract native filters dataMask from a permalink key.
+ * @complexity 3
+ */
+
+// --- SupersetClientExtractNativeFiltersFromKey (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Extract native filters from a native_filters_key URL parameter.
+ * @complexity 3
+ */
+
+// --- SupersetClientParseDashboardUrlForFilters (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state if present.
+ * @complexity 3
+ */
+
+// --- SupersetDashboardsListMixin (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Dashboard listing mixin for SupersetClient — paginated list, summary projection.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientGetDashboards (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Получает полный список дашбордов, автоматически обрабатывая пагинацию.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDashboardsPage (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches a single dashboards page from Superset without iterating all pages.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDashboardsSummary (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches dashboard metadata optimized for the grid.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDashboardsSummaryPage (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches one page of dashboard metadata optimized for the grid.
+ * @complexity 3
+ */
+
+// --- SupersetDashboardsWriteMixin (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Dashboard write mixin for SupersetClient — markdown chart CRUD and layout manipulation for maintenance banners.
+ * @complexity 4
+ * @data_contract Input: dashboard_id / chart_id / markdown_text → Output: API response dict or chart_id int
+ * @invariant All network operations use self.network.request()
+ * @layer Infrastructure
+ * @rationale Extracted from monolithic superset_client to satisfy INV_7.
+ * @side_effect Creates, updates, deletes markdown charts & modifies dashboard layout via Superset API.
+ */
+
+// --- create_markdown_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Create a markdown chart and return the new chart ID.
+ * @complexity 3
+ * @post Returns chart_id (int). Chart is NOT yet placed in dashboard layout.
+ * @pre dashboard_id exists in Superset. markdown_text not empty.
+ * @side_effect Creates a new chart resource in Superset.
+ */
+
+// --- update_markdown_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Update the markdown text of an existing markdown chart.
+ * @complexity 3
+ * @post Chart markdown content updated.
+ * @pre chart_id exists and is a markdown chart.
+ * @side_effect Modifies a chart resource in Superset.
+ */
+
+// --- update_dashboard_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Insert a native MARKDOWN element at (0,0) with full width (12 cols),
+ * @complexity 4
+ */
+
+// --- remove_chart_from_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Remove banner markdown element from dashboard layout without deleting the chart.
+ * @complexity 3
+ * @post MARKDOWN element removed from position_json; items shifted up.
+ * @pre dashboard_id exists. chart_id exists in layout as MARKDOWN-banner-{chart_id}.
+ * @side_effect Modifies dashboard layout JSON.
+ */
+
+// --- delete_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Delete a chart from Superset by ID.
+ * @complexity 3
+ * @post Chart permanently deleted from Superset.
+ * @pre chart_id exists.
+ * @side_effect Destroys chart resource.
+ */
+
+// --- update_banner_on_dashboard (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Update the content of a native MARKDOWN banner element on a dashboard.
+ * @complexity 3
+ * @post MARKDOWN element content updated on dashboard.
+ * @pre dashboard_id exists. chart_id used for key lookup.
+ * @side_effect Modifies dashboard layout JSON in Superset.
+ */
+
+// --- get_dashboard_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Fetch the position_json layout of a dashboard.
+ * @complexity 3
+ * @post Returns the dashboard layout dict.
+ * @pre dashboard_id exists.
+ */
+
+// --- _resolve_markdown_datasource (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Find a valid datasource_id for markdown chart creation.
+ * @complexity 2
+ * @post Returns an integer datasource_id.
+ * @pre dashboard_id exists.
+ */
+
+// --- SupersetDatabasesMixin (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Database domain mixin for SupersetClient — list, get, summary, by_uuid.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientGetDatabases (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Получает полный список баз данных.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDatabase (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Получает информацию о конкретной базе данных по её ID.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDatabasesSummary (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Fetch a summary of databases including uuid, name, and engine.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDatabaseByUuid (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Find a database by its UUID.
+ * @complexity 3
+ */
+
+// --- SupersetDatasetsMixin (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Dataset domain mixin for SupersetClient — list, get, detail, update.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientGetDatasets (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Получает полный список датасетов, автоматически обрабатывая пагинацию.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDatasetsSummary (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetches dataset metadata optimized for the Dataset Hub grid.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDatasetLinkedDashboardCount (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetch the number of dashboards linked to a dataset via related_objects endpoint.
+ * @complexity 2
+ * @rationale Added to fix linked_count=0 in StatsBar. Reuses the same /dataset/{id}/related_objects call
+ */
+
+// --- SupersetClientGetDatasetDetail (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetches detailed dataset information including columns and linked dashboards.
+ * @complexity 3
+ */
+
+// --- SupersetClientGetDataset (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Получает информацию о конкретном датасете по его ID.
+ * @complexity 3
+ */
+
+// --- SupersetClientUpdateDataset (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Обновляет данные датасета по его ID.
+ * @complexity 3
+ * @side_effect Modifies resource in upstream Superset environment.
+ */
+
+// --- SupersetDatasetsPreviewMixin (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Dataset preview compilation mixin for SupersetClient — build query context, compile SQL.
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientCompileDatasetPreview (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Compile dataset preview SQL through the strongest supported Superset preview endpoint family and return normalized SQL output.
+ * @complexity 4
+ */
+
+// --- SupersetClientBuildDatasetPreviewLegacyFormData (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Build browser-style legacy form_data payload for Superset preview endpoints inferred from observed deployment traffic.
+ * @complexity 4
+ */
+
+// --- SupersetClientBuildDatasetPreviewQueryContext (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Build a reduced-scope chart-data query context for deterministic dataset preview compilation.
+ * @complexity 4
+ */
+
+// --- SupersetDatasetsPreviewFiltersMixin (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Filter normalization and SQL extraction helpers for dataset preview compilation.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- SupersetClientNormalizeEffectiveFiltersForQueryContext (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Convert execution mappings into Superset chart-data filter objects.
+ * @complexity 3
+ */
+
+// --- SupersetClientExtractCompiledSqlFromPreviewResponse (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Normalize compiled SQL from either chart-data or legacy form_data preview responses.
+ * @complexity 3
+ */
+
+// --- LayoutUtils (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Utility functions for manipulating Superset dashboard position_json layout.
+ * @complexity 2
+ * @layer Infrastructure
+ * @rationale Extracted from SupersetDashboardsWriteMixin to stay under INV_7 400 LOC.
+ */
+
+// --- parse_position_json (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Parse position_json from a dashboard API response (may be string or dict).
+ * @complexity 1
+ * @post Returns a dict.
+ * @pre raw_position is a string, dict, or None.
+ */
+
+// --- _estimate_markdown_height (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Estimate grid height for a MARKDOWN element based on HTML content.
+ * @complexity 1
+ */
+
+// --- _generate_banner_id (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Generate a deterministic row and markdown key for a banner chart.
+ * @complexity 1
+ */
+
+// --- insert_banner_markdown_at_top (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Insert a ROW + native MARKDOWN pair at the top of the dashboard grid.
+ * @complexity 2
+ */
+
+// --- update_banner_markdown_content (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Update the code content and adaptive height of an existing banner markdown element.
+ * @complexity 1
+ * @post position_json is mutated; markdown content and height updated.
+ * @pre position_json has markdown_key. content is the new HTML/markdown string.
+ */
+
+// --- remove_banner_from_position (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Remove the banner ROW + MARKDOWN pair from the position dict and GRID children.
+ * @complexity 2
+ */
+
+// --- SupersetUserProjection (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief User/owner payload normalization helpers for Superset client responses.
+ * @complexity 2
+ * @layer Infrastructure
+ */
+
+// --- SupersetUserProjectionMixin (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Mixin providing user/owner payload normalization for Superset API responses.
+ * @complexity 2
+ */
+
+// --- SupersetClientExtractOwnerLabels (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Normalize dashboard owners payload to stable display labels.
+ * @complexity 1
+ */
+
+// --- SupersetClientExtractUserDisplay (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Normalize user payload to a stable display name.
+ * @complexity 1
+ */
+
+// --- SupersetClientSanitizeUserText (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Convert scalar value to non-empty user-facing text.
+ * @complexity 1
+ */
+
+// --- SupersetProfileLookup (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Provides environment-scoped Superset account lookup adapter with stable normalized output.
+ * @complexity 5
+ * @data_contract ProfileQuery -> SupersetProfile
+ * @invariant Adapter never leaks raw upstream payload shape to API consumers.
+ * @layer Service
+ * @side_effect Makes HTTP requests to Superset
+ */
+
+// --- SupersetAccountLookupAdapter (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Lookup Superset users and normalize candidates for profile binding.
+ * @complexity 3
+ */
+
+// --- __init__ (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Initializes lookup adapter with authenticated API client and environment context.
+ * @post Adapter is ready to perform users lookup requests.
+ * @pre network_client supports request(method, endpoint, params=...).
+ */
+
+// --- get_users_page (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Fetch one users page from Superset with passthrough search/sort parameters.
+ * @post Returns deterministic payload with normalized items and total count.
+ * @pre page_index >= 0 and page_size >= 1.
+ * @return Dict[str, Any]
+ */
+
+// --- _normalize_lookup_payload (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Convert Superset users response variants into stable candidates payload.
+ * @post Output contains canonical keys: status, environment_id, page_index, page_size, total, items.
+ * @pre response can be dict/list in any supported upstream shape.
+ * @return Dict[str, Any]
+ */
+
+// --- normalize_user_payload (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Project raw Superset user object to canonical candidate shape.
+ * @post Returns normalized candidate keys (environment_id, username, display_name, email, is_active).
+ * @pre raw_user may have heterogenous key names between Superset versions.
+ * @return Dict[str, Any]
+ */
+
+// --- TaskManagerPackage (backend/src/core/task_manager/__init__.py)
+/**!
+ */
+
+// --- TestContext (backend/src/core/task_manager/__tests__/test_context.py)
+/**!
+ * @brief Verify TaskContext preserves optional background task scheduler across sub-context creation.
+ * @complexity 3
+ */
+
+// --- test_task_context_preserves_background_tasks_across_sub_context (backend/src/core/task_manager/__tests__/test_context.py)
+/**!
+ * @brief Plugins must be able to access background_tasks from both root and sub-context loggers.
+ * @post background_tasks remains available on root and derived sub-contexts.
+ * @pre TaskContext is initialized with a BackgroundTasks-like object.
+ */
+
+// --- __tests__/test_task_logger (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Contract testing for TaskLogger
+ */
+
+// --- test_task_logger_initialization (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger initializes with correct task_id and state.
+ * @test_contract invariants -> "All specific log methods (info, error) delegate to _log"
+ */
+
+// --- test_log_methods_delegation (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger delegates log method calls to the underlying persistence service.
+ * @test_contract invariants -> "with_source creates a new logger with the same task_id"
+ */
+
+// --- test_with_source (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger.with_source returns a new logger with the correct source attribution.
+ * @test_edge missing_task_id -> raises TypeError
+ */
+
+// --- test_missing_task_id (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger raises or handles missing task_id gracefully.
+ * @test_edge invalid_add_log_fn -> raises TypeError
+ */
+
+// --- test_invalid_add_log_fn (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger raises ValueError for invalid add_log_fn parameter.
+ * @test_invariant consistent_delegation
+ */
+
+// --- test_progress_log (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger correctly logs progress updates with percentage and message.
+ */
+
+// --- TaskCleanupModule (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Implements task cleanup and retention policies, including associated logs.
+ * @complexity 3
+ * @layer Core
+ */
+
+// --- TaskCleanupService (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Provides methods to clean up old task records and their associated logs.
+ * @complexity 3
+ */
+
+// --- run_cleanup (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Deletes tasks older than the configured retention period and their logs.
+ * @post Old tasks and their logs are deleted from persistence.
+ * @pre Config manager has valid settings.
+ */
+
+// --- delete_task_with_logs (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Delete a single task and all its associated logs.
+ * @param task_id (str) - The task ID to delete.
+ * @post Task and all its logs are deleted.
+ * @pre task_id is a valid task ID.
+ */
+
+// --- TaskContextModule (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Provides execution context passed to plugins during task execution.
+ * @complexity 5
+ * @data_contract Input[task_id, add_log_fn, params, default_source, background_tasks] -> Output[TaskContext]
+ * @invariant Each TaskContext is bound to a single task execution.
+ * @layer Core
+ * @post Plugins receive context instances with stable logger and parameter accessors.
+ * @pre Task execution pipeline provides valid task identifiers, logging callbacks, and parameter dictionaries.
+ * @side_effect Creates task-scoped logger wrappers and carries optional background task handles across sub-contexts.
+ */
+
+// --- TaskContext (backend/src/core/task_manager/context.py)
+/**!
+ * @brief A container passed to plugin.execute() providing the logger and other task-specific utilities.
+ * @complexity 5
+ * @data_contract Input[task_id, add_log_fn, params, default_source, background_tasks] -> Output[TaskContext]
+ * @invariant logger is always a valid TaskLogger instance.
+ * @post Instance exposes immutable task identity with logger, params, and optional background task access.
+ * @pre Constructor receives non-empty task_id, callable add_log_fn, and params mapping.
+ * @side_effect Emits structured task logs through TaskLogger on plugin interactions.
+ * @test_contract TaskContextContract ->
+ * @ux_state Idle -> Active -> Complete
+ */
+
+// --- task_id (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the task ID.
+ * @post Returns the task ID string.
+ * @pre TaskContext must be initialized.
+ * @return str - The task ID.
+ */
+
+// --- logger (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the TaskLogger instance for this context.
+ * @post Returns the TaskLogger instance.
+ * @pre TaskContext must be initialized.
+ * @return TaskLogger - The logger instance.
+ */
+
+// --- params (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the task parameters.
+ * @post Returns the parameters dictionary.
+ * @pre TaskContext must be initialized.
+ * @return Dict[str, Any] - The task parameters.
+ */
+
+// --- background_tasks (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Expose optional background task scheduler for plugins that dispatch deferred side effects.
+ * @post Returns BackgroundTasks-like object or None.
+ * @pre TaskContext must be initialized.
+ */
+
+// --- get_param (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get a specific parameter value with optional default.
+ * @param default (Any) - Default value if key not found.
+ * @post Returns parameter value or default.
+ * @pre TaskContext must be initialized.
+ * @return Any - Parameter value or default.
+ */
+
+// --- create_sub_context (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Create a sub-context with a different default source.
+ * @param source (str) - New default source for logging.
+ * @post Returns new TaskContext with different logger source.
+ * @pre source is a non-empty string.
+ * @return TaskContext - New context with different source.
+ */
+
+// --- EventBusModule (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Task-scoped log buffering, persistence flushes, and subscriber fan-out for real-time
+ * @complexity 5
+ */
+
+// --- EventBus (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Coordinates task-scoped log buffering, persistence flushes, and subscriber fan-out
+ * @complexity 5
+ */
+
+// --- flush_task_logs (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Flush logs for a specific task immediately.
+ * @complexity 3
+ * @post Task's buffered logs are written to database.
+ * @pre task_id exists.
+ */
+
+// --- add_log (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Adds a log entry to a task buffer and notifies subscribers.
+ * @complexity 3
+ * @post Log added to buffer and pushed to queues (if level meets task_log_level filter).
+ * @pre Task exists.
+ */
+
+// --- TaskGraphModule (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief In-memory task registry with persistence-backed hydration, pagination, and
+ * @complexity 5
+ */
+
+// --- TaskGraph (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief In-memory task dependency graph spanning task registry nodes, pause futures,
+ * @complexity 5
+ */
+
+// --- add_task (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Register a task in the in-memory registry.
+ * @complexity 2
+ */
+
+// --- remove_tasks (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Remove tasks from registry and persistence, cancel futures for waiting tasks.
+ * @complexity 3
+ */
+
+// --- create_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Create and store a future for a paused task.
+ * @complexity 1
+ */
+
+// --- resolve_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Resolve a paused task's future and remove it from the map.
+ * @complexity 1
+ */
+
+// --- remove_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Remove a future without resolving it.
+ * @complexity 1
+ */
+
+// --- JobLifecycleModule (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Task creation, execution, pause/resume, and completion transitions for plugin-backed
+ * @complexity 5
+ */
+
+// --- JobLifecycle (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Encodes task creation, execution, pause/resume, and completion transitions for
+ * @complexity 5
+ */
+
+// --- _broadcast_dataset_updated (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Broadcast dataset.updated event to all subscribers for a given environment.
+ * @complexity 3
+ */
+
+// --- TaskManagerModule (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Thin facade composing TaskGraph (registry), EventBus (log/pub-sub), and JobLifecycle
+ * @complexity 5
+ */
+
+// --- TaskManager (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Facade composing TaskGraph, EventBus, and JobLifecycle into a single interface.
+ * @complexity 5
+ * @layer Core
+ * @post In-memory task graph, lifecycle scheduler, and log event bus stay consistent with
+ * @pre Plugin loader resolves plugin ids and persistence services are available.
+ */
+
+// --- _make_add_log_callback (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Create a closure for adding logs that looks up the task and delegates to EventBus.
+ * @complexity 2
+ */
+
+// --- _flusher_loop (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus._flusher_loop.
+ * @complexity 3
+ */
+
+// --- _flush_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus._flush_logs.
+ * @complexity 3
+ */
+
+// --- _flush_task_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus.flush_task_logs.
+ * @complexity 3
+ */
+
+// --- get_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves a task by its ID.
+ * @complexity 2
+ */
+
+// --- get_all_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves all registered tasks.
+ * @complexity 1
+ */
+
+// --- get_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves tasks with pagination and optional status filter.
+ * @complexity 3
+ */
+
+// --- load_persisted_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Load persisted tasks using persistence service.
+ * @complexity 2
+ */
+
+// --- clear_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Clears tasks based on status filter (also deletes associated logs).
+ * @complexity 4
+ * @side_effect Removes tasks from registry and persistence; cancels futures.
+ */
+
+// --- get_task_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves logs for a specific task (from memory or persistence).
+ * @complexity 3
+ */
+
+// --- get_task_log_stats (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Get statistics about logs for a task.
+ * @complexity 2
+ */
+
+// --- get_task_log_sources (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Get unique sources for a task's logs.
+ * @complexity 2
+ */
+
+// --- subscribe_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Subscribes to real-time logs for a task.
+ * @complexity 2
+ */
+
+// --- unsubscribe_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Unsubscribes from real-time logs for a task.
+ * @complexity 2
+ */
+
+// --- create_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Creates and queues a new task for execution.
+ * @complexity 4
+ */
+
+// --- _run_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Internal method to execute a task with TaskContext support (delegates to lifecycle).
+ * @complexity 4
+ */
+
+// --- resolve_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Resumes a task that is awaiting mapping.
+ * @complexity 3
+ */
+
+// --- wait_for_resolution (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Pauses execution and waits for a resolution signal.
+ * @complexity 3
+ */
+
+// --- wait_for_input (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Pauses execution and waits for user input.
+ * @complexity 3
+ */
+
+// --- await_input (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Transition a task to AWAITING_INPUT state with input request.
+ * @complexity 3
+ */
+
+// --- resume_task_with_password (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Resume a task that is awaiting input with provided passwords.
+ * @complexity 3
+ */
+
+// --- subscribe_dataset_events (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Subscribe to dataset.updated events for an environment.
+ * @complexity 2
+ */
+
+// --- unsubscribe_dataset_events (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Unsubscribe from dataset.updated events.
+ * @complexity 2
+ */
+
+// --- TaskManagerModels (backend/src/core/task_manager/models.py)
+/**!
+ * @brief Defines the data models and enumerations used by the Task Manager.
+ * @complexity 5
+ * @data_contract TaskInput -> TaskModel
+ * @invariant Must use Pydantic for data validation.
+ * @layer Domain
+ * @post Task models exported with immutable IDs
+ * @pre Task manager initialized
+ * @side_effect Defines task data schema
+ */
+
+// --- TaskStatus (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- LogLevel (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- TaskLog (backend/src/core/task_manager/models.py)
+/**!
+ * @brief A Pydantic model representing a persisted log entry from the database.
+ * @complexity 3
+ */
+
+// --- LogFilter (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- LogStats (backend/src/core/task_manager/models.py)
+/**!
+ * @brief Statistics about log entries for a task.
+ * @complexity 1
+ */
+
+// --- Task (backend/src/core/task_manager/models.py)
+/**!
+ * @brief A Pydantic model representing a single execution instance of a plugin, including its status, parameters, and logs.
+ * @complexity 3
+ */
+
+// --- TaskPersistenceModule (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Handles the persistence of tasks using SQLAlchemy and the tasks.db database.
+ * @complexity 5
+ * @data_contract Input[Task, LogEntry] -> Model[TaskRecord, TaskLogRecord]
+ * @invariant Database schema must match the TaskRecord model structure.
+ * @layer Core
+ * @post Provides reliable storage and retrieval for task metadata and logs.
+ * @pre Tasks database must be initialized with TaskRecord and TaskLogRecord schemas.
+ * @side_effect Performs database I/O on tasks.db.
+ */
+
+// --- TaskPersistenceService (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Provides methods to save, load, and delete task records in tasks.db using SQLAlchemy models.
+ * @complexity 5
+ * @data_contract Input[Task | List[Task] | List[str] | Query(limit:int,status:Optional[TaskStatus])] -> Model[TaskRecord, Environment] -> Output[None | List[Task]]
+ * @invariant Persistence must handle potentially missing task fields natively.
+ * @post Persist operations leave matching TaskRecord rows committed or rolled back without leaking sessions, load operations return reconstructed Task objects from stored TaskRecord rows, and delete operations remove only the addressed task rows.
+ * @pre TasksSessionLocal must provide an active SQLAlchemy session, Task inputs must expose id/plugin_id/status/params/result/logs fields, and TaskRecord plus Environment schemas must be available.
+ * @side_effect Opens SQLAlchemy sessions, reads and writes task_records rows, resolves environment foreign keys against environments, commits or rolls back transactions, and emits error logs on persistence failures.
+ * @test_contract TaskPersistenceContract ->
+ */
+
+// --- _json_load_if_needed (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Safely load JSON strings from DB if necessary
+ * @complexity 1
+ * @post Returns parsed JSON object, list, string, or primitive
+ * @pre value is an arbitrary database value
+ */
+
+// --- _parse_datetime (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Safely parse a datetime string from the database
+ * @complexity 1
+ * @post Returns datetime object or None
+ * @pre value is an ISO string or datetime object
+ */
+
+// --- _resolve_environment_id (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Resolve environment id into existing environments.id value to satisfy FK constraints.
+ * @complexity 3
+ * @data_contract Input[env_id: Optional[str]] -> Output[Optional[str]]
+ * @post Returns existing environments.id or None when unresolved.
+ * @pre Session is active
+ */
+
+// --- persist_task (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Persists or updates a single task in the database.
+ * @complexity 3
+ * @data_contract Input[Task] -> Model[TaskRecord]
+ * @param task (Task) - The task object to persist.
+ * @post Task record created or updated in database.
+ * @pre isinstance(task, Task)
+ * @side_effect Writes to task_records table in tasks.db
+ */
+
+// --- persist_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Persists multiple tasks.
+ * @complexity 3
+ * @param tasks (List[Task]) - The list of tasks to persist.
+ * @post All tasks in list are persisted.
+ * @pre isinstance(tasks, list)
+ */
+
+// --- load_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Loads tasks from the database.
+ * @complexity 3
+ * @data_contract Model[TaskRecord] -> Output[List[Task]]
+ * @param status (Optional[TaskStatus]) - Filter by status.
+ * @post Returns list of Task objects.
+ * @pre limit is an integer.
+ * @return List[Task] - The loaded tasks.
+ */
+
+// --- delete_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Deletes specific tasks from the database.
+ * @complexity 3
+ * @param task_ids (List[str]) - List of task IDs to delete.
+ * @post Specified task records deleted from database.
+ * @pre task_ids is a list of strings.
+ * @side_effect Deletes rows from task_records table.
+ */
+
+// --- TaskLogPersistenceService (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Provides methods to store, query, summarize, and delete task log rows in the task_logs table.
+ * @complexity 5
+ * @data_contract Input[task_id:str, logs:List[LogEntry], log_filter:LogFilter, task_ids:List[str]] -> Model[TaskLogRecord] -> Output[None | List[TaskLog] | LogStats | List[str]]
+ * @invariant Log entries are batch-inserted for performance.
+ * @post add_logs commits all provided log entries or rolls back on failure, query methods return TaskLog or LogStats views reconstructed from TaskLogRecord rows, and delete methods remove only log rows matching the supplied task identifiers.
+ * @pre TasksSessionLocal must provide an active SQLAlchemy session, task_id inputs must identify task log rows, LogEntry batches must expose timestamp/level/source/message/metadata fields, and LogFilter inputs must provide pagination and filter attributes used by queries.
+ * @side_effect Opens SQLAlchemy sessions, inserts, reads, aggregates, and deletes task_logs rows, serializes log metadata to JSON, commits or rolls back transactions, and emits error logs on persistence failures.
+ * @test_contract TaskLogPersistenceContract ->
+ */
+
+// --- add_logs (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Batch insert log entries for a task.
+ * @complexity 3
+ * @data_contract Input[List[LogEntry]] -> Model[TaskLogRecord]
+ * @param logs (List[LogEntry]) - Log entries to insert.
+ * @post All logs inserted into task_logs table.
+ * @pre logs is a list of LogEntry objects.
+ * @side_effect Writes to task_logs table.
+ */
+
+// --- get_logs (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Query logs for a task with filtering and pagination.
+ * @complexity 3
+ * @data_contract Model[TaskLogRecord] -> Output[List[TaskLog]]
+ * @param log_filter (LogFilter) - Filter parameters.
+ * @post Returns list of TaskLog objects matching filters.
+ * @pre task_id is a valid task ID.
+ * @return List[TaskLog] - Filtered log entries.
+ */
+
+// --- get_log_stats (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Get statistics about logs for a task.
+ * @complexity 3
+ * @data_contract Model[TaskLogRecord] -> Output[LogStats]
+ * @param task_id (str) - The task ID.
+ * @post Returns LogStats with counts by level and source.
+ * @pre task_id is a valid task ID.
+ * @return LogStats - Statistics about task logs.
+ */
+
+// --- get_sources (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Get unique sources for a task's logs.
+ * @complexity 3
+ * @data_contract Model[TaskLogRecord] -> Output[List[str]]
+ * @param task_id (str) - The task ID.
+ * @post Returns list of unique source strings.
+ * @pre task_id is a valid task ID.
+ * @return List[str] - Unique source names.
+ */
+
+// --- delete_logs_for_task (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Delete all logs for a specific task.
+ * @complexity 3
+ * @param task_id (str) - The task ID.
+ * @post All logs for the task are deleted.
+ * @pre task_id is a valid task ID.
+ * @side_effect Deletes from task_logs table.
+ */
+
+// --- delete_logs_for_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Delete all logs for multiple tasks.
+ * @complexity 3
+ * @param task_ids (List[str]) - List of task IDs.
+ * @post All logs for the tasks are deleted.
+ * @pre task_ids is a list of task IDs.
+ * @side_effect Deletes rows from task_logs table.
+ */
+
+// --- TaskLoggerModule (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Provides a dedicated logger for tasks with automatic source attribution.
+ * @complexity 2
+ * @invariant Each TaskLogger instance is bound to a specific task_id and default source.
+ * @layer Core
+ */
+
+// --- TaskLogger (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief A wrapper around TaskManager._add_log that carries task_id and source context.
+ * @complexity 2
+ * @invariant All log calls include the task_id and source.
+ * @test_contract TaskLoggerContract ->
+ * @ux_state Idle -> Logging -> (system records log)
+ */
+
+// --- with_source (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Create a sub-logger with a different default source.
+ * @param source (str) - New default source.
+ * @post Returns new TaskLogger with the same task_id but different source.
+ * @pre source is a non-empty string.
+ * @return TaskLogger - New logger instance.
+ */
+
+// --- _log (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Internal method to log a message at a given level.
+ * @param metadata (Optional[Dict]) - Additional structured data.
+ * @post Log entry added via add_log_fn.
+ * @pre level is a valid log level string.
+ * @ux_state Logging -> (writing internal log)
+ */
+
+// --- debug (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a DEBUG level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added via internally with DEBUG level.
+ * @pre message is a string.
+ */
+
+// --- info (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log an INFO level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with INFO level.
+ * @pre message is a string.
+ */
+
+// --- warning (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a WARNING level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with WARNING level.
+ * @pre message is a string.
+ */
+
+// --- error (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log an ERROR level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with ERROR level.
+ * @pre message is a string.
+ */
+
+// --- progress (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a progress update with percentage.
+ * @param source (Optional[str]) - Override source.
+ * @post Log entry with progress metadata added.
+ * @pre percent is between 0 and 100.
+ */
+
+// --- AppTimezone (backend/src/core/timezone.py)
+/**!
+ * @brief Application-level timezone utilities. Reads APP_TIMEZONE from env (default Europe/Moscow)
+ * @complexity 3
+ */
+
+// --- _get_default_tz_name (backend/src/core/timezone.py)
+/**!
+ * @brief Read APP_TIMEZONE from env, fall back to Europe/Moscow.
+ * @complexity 1
+ * @post Returns a valid IANA timezone string.
+ * @pre Environment is loaded (dotenv or os.environ).
+ */
+
+// --- get_app_timezone (backend/src/core/timezone.py)
+/**!
+ * @brief Return cached ZoneInfo for the configured application timezone.
+ * @complexity 1
+ * @post Returns a ZoneInfo instance matching APP_TIMEZONE env var.
+ * @side_effect Reads os.environ on first call; result is cached.
+ */
+
+// --- invalidate_timezone_cache (backend/src/core/timezone.py)
+/**!
+ * @brief Reset the cached ZoneInfo so the next get_app_timezone() call re-reads from env/DB.
+ * @complexity 1
+ * @post _APP_TZ_CACHE is set to None; subsequent get_app_timezone() will re-resolve.
+ * @rationale Called after PATCH /settings/consolidated updates app_timezone.
+ */
+
+// --- validate_timezone (backend/src/core/timezone.py)
+/**!
+ * @brief Validate that a timezone string is a known IANA timezone.
+ * @complexity 1
+ * @post Returns True if ZoneInfo accepts the name, False otherwise.
+ * @pre tz_name is a string.
+ */
+
+// --- localize (backend/src/core/timezone.py)
+/**!
+ * @brief Convert a timezone-aware or naive UTC datetime to the configured app timezone.
+ * @complexity 1
+ * @post Returns a datetime with the app timezone attached (astimezone).
+ * @pre If dt is timezone-naive, it is assumed to be UTC.
+ */
+
+// --- now (backend/src/core/timezone.py)
+/**!
+ * @brief Get current time in the configured application timezone.
+ * @complexity 1
+ * @post Returns timezone-aware datetime in the app timezone.
+ */
+
+// --- format_timezone_offset (backend/src/core/timezone.py)
+/**!
+ * @brief Return the UTC offset string for the configured timezone (e.g. "+03:00").
+ * @complexity 1
+ * @post Returns string like "+03:00" or "+00:00".
+ */
+
+// --- CoreUtils (backend/src/core/utils/__init__.py)
+/**!
+ * @brief Shared utility package root.
+ */
+
+// --- AsyncAPIClient.__init__ (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Initialize async API client for one environment.
+ * @complexity 3
+ * @data_contract Input[config: Dict[str, Any]] -> self._auth_cache_key[str]
+ * @post Client is ready for async request/authentication flow.
+ * @pre config contains base_url and auth payload.
+ */
+
+// --- AsyncAPIClient._normalize_base_url (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Normalize base URL for Superset API root construction.
+ * @complexity 1
+ * @post Returns canonical base URL without trailing slash and duplicate /api/v1 suffix.
+ */
+
+// --- AsyncAPIClient._build_api_url (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Build full API URL from relative Superset endpoint.
+ * @complexity 1
+ * @post Returns absolute URL for upstream request.
+ */
+
+// --- AsyncAPIClient._get_auth_lock (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Return per-cache-key async lock to serialize fresh login attempts.
+ * @complexity 1
+ * @post Returns stable asyncio.Lock instance.
+ */
+
+// --- AsyncAPIClient.authenticate (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Authenticate against Superset and cache access/csrf tokens.
+ * @complexity 3
+ * @data_contract None -> Output[Dict[str, str]]
+ * @post Client tokens are populated and reusable across requests.
+ * @side_effect Performs network requests to Superset authentication endpoints.
+ */
+
+// --- AsyncAPIClient.get_headers (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Return authenticated Superset headers for async requests.
+ * @complexity 3
+ * @post Headers include Authorization and CSRF tokens.
+ */
+
+// --- AsyncAPIClient._is_dashboard_endpoint (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+ * @complexity 2
+ * @post Returns true only for dashboard-specific endpoints.
+ */
+
+// --- AsyncAPIClient._handle_network_error (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Translate generic httpx errors into NetworkError.
+ * @complexity 3
+ * @data_contract Input[httpx.HTTPError] -> NetworkError
+ * @post Raises NetworkError with URL context.
+ */
+
+// --- AsyncAPIClient.aclose (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Close underlying httpx client.
+ * @complexity 3
+ * @post Client resources are released.
+ * @side_effect Closes network connections.
+ */
+
+// --- DatasetMapperModule (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Этот модуль отвечает за обновление метаданных (verbose_name) в датасетах Superset,
+ */
+
+// --- DatasetMapper (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Класс для маппинга и обновления verbose_name в датасетах Superset.
+ */
+
+// --- get_sqllab_mappings (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Извлекает маппинги column_name -> verbose_name через SQL Lab Superset.
+ * @post Возвращается словарь column_name -> verbose_name из результатов SQL-запроса.
+ * @pre dataset_id должен существовать в Superset.
+ */
+
+// --- load_excel_mappings (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Загружает маппинги column_name -> verbose_name из XLSX файла.
+ * @error Exception - При ошибках чтения файла или парсинга.
+ * @param file_path (str) - Путь к XLSX файлу.
+ * @post Возвращается словарь с маппингами из файла.
+ * @pre file_path должен указывать на существующий XLSX файл.
+ * @return Dict[str, str] - Словарь с маппингами.
+ */
+
+// --- run_mapping (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Основная функция для выполнения маппинга и обновления verbose_name датасета в Superset.
+ * @param excel_path (Optional[str]) - Путь к XLSX файлу.
+ * @post Если найдены изменения, датасет в Superset обновлен через API.
+ * @pre dataset_id должен быть существующим ID в Superset.
+ */
+
+// --- FileIO (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Предоставляет набор утилит для управления файловыми операциями, включая работу с временными файлами, архивами ZIP, файлами YAML и очистку директорий.
+ * @complexity 3
+ * @layer Infrastructure
+ * @public_api create_temp_file, remove_empty_directories, read_dashboard_from_disk, calculate_crc32, RetentionPolicy, archive_exports, save_and_unpack_dashboard, update_yamls, create_dashboard_export, sanitize_filename, get_filename_from_headers, consolidate_archive_folders
+ */
+
+// --- InvalidZipFormatError (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Exception raised when a file is not a valid ZIP archive.
+ */
+
+// --- create_temp_file (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Контекстный менеджер для создания временного файла или директории с гарантированным удалением.
+ * @post Временный ресурс создан и путь к нему возвращен; ресурс удален после выхода из контекста.
+ * @pre suffix должен быть строкой, определяющей тип ресурса.
+ * @yields Path - Путь к временному ресурсу.
+ */
+
+// --- remove_empty_directories (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Рекурсивно удаляет все пустые поддиректории, начиная с указанного пути.
+ * @post Все пустые поддиректории удалены, возвращено их количество.
+ * @pre root_dir должен быть путем к существующей директории.
+ */
+
+// --- read_dashboard_from_disk (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Читает бинарное содержимое файла с диска.
+ * @post Возвращает байты содержимого и имя файла.
+ * @pre file_path должен указывать на существующий файл.
+ */
+
+// --- calculate_crc32 (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Вычисляет контрольную сумму CRC32 для файла.
+ * @post Возвращает 8-значную hex-строку CRC32.
+ * @pre file_path должен быть объектом Path к существующему файлу.
+ */
+
+// --- RetentionPolicy (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Определяет политику хранения для архивов (ежедневные, еженедельные, ежемесячные).
+ */
+
+// --- archive_exports (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Управляет архивом экспортированных файлов, применяя политику хранения и дедупликацию.
+ * @post Старые или дублирующиеся архивы удалены согласно политике.
+ * @pre output_dir должен быть путем к существующей директории.
+ */
+
+// --- apply_retention_policy (backend/src/core/utils/fileio.py)
+/**!
+ * @brief (Helper) Применяет политику хранения к списку файлов, возвращая те, что нужно сохранить.
+ * @post Returns a set of files to keep.
+ * @pre files_with_dates is a list of (Path, date) tuples.
+ */
+
+// --- save_and_unpack_dashboard (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Сохраняет бинарное содержимое ZIP-архива на диск и опционально распаковывает его.
+ * @post ZIP-файл сохранен, и если unpack=True, он распакован в output_dir.
+ * @pre zip_content должен быть байтами валидного ZIP-архива.
+ */
+
+// --- update_yamls (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Обновляет конфигурации в YAML-файлах, заменяя значения или применяя regex.
+ * @post Все YAML файлы в директории обновлены согласно переданным параметрам.
+ * @pre path должен быть существующей директорией.
+ */
+
+// --- _update_yaml_file (backend/src/core/utils/fileio.py)
+/**!
+ * @brief (Helper) Обновляет один YAML файл.
+ * @post Файл обновлен согласно переданным конфигурациям или регулярному выражению.
+ * @pre file_path должен быть объектом Path к существующему YAML файлу.
+ */
+
+// --- replacer (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Функция замены, сохраняющая кавычки если они были.
+ * @post Возвращает строку с новым значением, сохраняя префикс и кавычки.
+ * @pre match должен быть объектом совпадения регулярного выражения.
+ */
+
+// --- create_dashboard_export (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Создает ZIP-архив из указанных исходных путей.
+ * @post ZIP-архив создан по пути zip_path.
+ * @pre source_paths должен содержать существующие пути.
+ */
+
+// --- sanitize_filename (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Очищает строку от символов, недопустимых в именах файлов.
+ * @post Возвращает строку без спецсимволов.
+ * @pre filename должен быть строкой.
+ */
+
+// --- get_filename_from_headers (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Извлекает имя файла из HTTP заголовка 'Content-Disposition'.
+ * @post Возвращает имя файла или None, если заголовок отсутствует.
+ * @pre headers должен быть словарем заголовков.
+ */
+
+// --- consolidate_archive_folders (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Консолидирует директории архивов на основе общего слага в имени.
+ * @post Директории с одинаковым префиксом объединены в одну.
+ * @pre root_directory должен быть объектом Path к существующей директории.
+ */
+
+// --- FuzzyMatching (backend/src/core/utils/matching.py)
+/**!
+ * @brief Provides utility functions for fuzzy matching database names.
+ * @invariant Confidence scores are returned as floats between 0.0 and 1.0.
+ * @layer Core
+ */
+
+// --- suggest_mappings (backend/src/core/utils/matching.py)
+/**!
+ * @brief Suggests mappings between source and target databases using fuzzy matching.
+ * @post Returns a list of suggested mappings with confidence scores.
+ * @pre source_databases and target_databases are lists of dictionaries with 'uuid' and 'database_name'.
+ */
+
+// --- NetworkModule (backend/src/core/utils/network.py)
+/**!
+ * @brief Инкапсулирует низкоуровневую HTTP-логику для взаимодействия с Superset API, включая аутентификацию, управление сессией, retry-логику и обработку ошибок.
+ * @complexity 3
+ * @layer Infrastructure
+ * @public_api APIClient
+ */
+
+// --- SupersetAPIError (backend/src/core/utils/network.py)
+/**!
+ * @brief Base exception for all Superset API related errors.
+ * @complexity 1
+ */
+
+// --- AuthenticationError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when authentication fails.
+ * @complexity 1
+ */
+
+// --- PermissionDeniedError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when access is denied.
+ */
+
+// --- DashboardNotFoundError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when a dashboard cannot be found.
+ */
+
+// --- NetworkError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when a network level error occurs.
+ */
+
+// --- NetworkError.__init__ (backend/src/core/utils/network.py)
+/**!
+ * @brief Initializes the network error.
+ * @post NetworkError is initialized.
+ * @pre message is a string.
+ */
+
+// --- SupersetAuthCache (backend/src/core/utils/network.py)
+/**!
+ * @brief Process-local cache for Superset access/csrf tokens keyed by environment credentials.
+ * @post Cached entries expire automatically by TTL and can be reused across requests.
+ * @pre base_url and username are stable strings.
+ */
+
+// --- SupersetAuthCache.get (backend/src/core/utils/network.py)
+/**!
+ */
+
+// --- SupersetAuthCache.set (backend/src/core/utils/network.py)
+/**!
+ */
+
+// --- APIClient (backend/src/core/utils/network.py)
+/**!
+ * @brief Synchronous Superset API client with process-local auth token caching.
+ * @complexity 3
+ */
+
+// --- APIClient.__init__ (backend/src/core/utils/network.py)
+/**!
+ * @brief Инициализирует API клиент с конфигурацией, сессией и логгером.
+ * @param timeout (int) - Таймаут запросов.
+ * @post APIClient instance is initialized with a session.
+ * @pre config must contain 'base_url' and 'auth'.
+ */
+
+// --- _init_session (backend/src/core/utils/network.py)
+/**!
+ * @brief Создает и настраивает `requests.Session` с retry-логикой.
+ * @post Returns a configured requests.Session instance.
+ * @pre self.request_settings must be initialized.
+ * @return requests.Session - Настроенная сессия.
+ */
+
+// --- _normalize_base_url (backend/src/core/utils/network.py)
+/**!
+ * @brief Normalize Superset environment URL to base host/path without trailing slash and /api/v1 suffix.
+ */
+
+// --- _build_api_url (backend/src/core/utils/network.py)
+/**!
+ * @brief Build absolute Superset API URL for endpoint using canonical /api/v1 base.
+ * @post Returns full URL without accidental duplicate slashes.
+ * @pre endpoint is relative path or absolute URL.
+ * @return str
+ */
+
+// --- APIClient.authenticate (backend/src/core/utils/network.py)
+/**!
+ * @brief Выполняет аутентификацию в Superset API и получает access и CSRF токены.
+ * @error AuthenticationError, NetworkError - при ошибках.
+ * @post `self._tokens` заполнен, `self._authenticated` установлен в `True`.
+ * @pre self.auth and self.base_url must be valid.
+ * @return Dict[str, str] - Словарь с токенами.
+ */
+
+// --- headers (backend/src/core/utils/network.py)
+/**!
+ * @brief Возвращает HTTP-заголовки для аутентифицированных запросов.
+ * @post Returns headers including auth tokens.
+ * @pre APIClient is initialized and authenticated or can be authenticated.
+ */
+
+// --- request (backend/src/core/utils/network.py)
+/**!
+ * @brief Выполняет универсальный HTTP-запрос к API.
+ * @error SupersetAPIError, NetworkError и их подклассы.
+ * @param raw_response (bool) - Возвращать ли сырой ответ.
+ * @post Returns response content or raw Response object.
+ * @pre method and endpoint must be strings.
+ * @return `requests.Response` если `raw_response=True`, иначе `dict`.
+ */
+
+// --- _handle_http_error (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Преобразует HTTP ошибки в кастомные исключения.
+ * @param endpoint (str) - Эндпоинт.
+ * @post Raises a specific SupersetAPIError or subclass.
+ * @pre e must be a valid HTTPError with a response.
+ */
+
+// --- _is_dashboard_endpoint (backend/src/core/utils/network.py)
+/**!
+ * @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+ * @post Returns true only for dashboard-specific endpoints.
+ * @pre endpoint may be relative or absolute.
+ */
+
+// --- _handle_network_error (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Преобразует сетевые ошибки в `NetworkError`.
+ * @param url (str) - URL.
+ * @post Raises a NetworkError.
+ * @pre e must be a RequestException.
+ */
+
+// --- upload_file (backend/src/core/utils/network.py)
+/**!
+ * @brief Загружает файл на сервер через multipart/form-data.
+ * @error SupersetAPIError, NetworkError, TypeError.
+ * @param timeout (Optional[int]) - Таймаут.
+ * @post File is uploaded and response returned.
+ * @pre file_info must contain 'file_obj' and 'file_name'.
+ * @return Ответ API в виде словаря.
+ */
+
+// --- _perform_upload (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Выполняет POST запрос с файлом.
+ * @param timeout (Optional[int]) - Таймаут.
+ * @post POST request is performed and JSON response returned.
+ * @pre url, files, and headers must be provided.
+ * @return Dict - Ответ.
+ */
+
+// --- fetch_paginated_count (backend/src/core/utils/network.py)
+/**!
+ * @brief Получает общее количество элементов для пагинации.
+ * @param count_field (str) - Поле с количеством.
+ * @post Returns total count of items.
+ * @pre query_params must be a dictionary.
+ * @return int - Количество.
+ */
+
+// --- fetch_paginated_data (backend/src/core/utils/network.py)
+/**!
+ * @brief Автоматически собирает данные со всех страниц пагинированного эндпоинта.
+ * @param pagination_options (Dict[str, Any]) - Опции пагинации.
+ * @post Returns all items across all pages.
+ * @pre pagination_options must contain 'base_query', 'results_field'. 'total_count' is optional.
+ * @return List[Any] - Список данных.
+ */
+
+// --- SupersetCompilationAdapter (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Interact with Superset preview compilation and SQL Lab execution endpoints using the current approved execution context.
+ * @complexity 4
+ * @invariant The adapter never fabricates compiled SQL locally; preview truth is delegated to Superset only.
+ * @layer Infrastructure
+ * @post preview and launch calls return Superset-originated artifacts or explicit errors.
+ * @pre effective template params and dataset execution reference are available.
+ * @side_effect performs upstream Superset preview and SQL Lab calls.
+ */
+
+// --- SupersetCompilationAdapter.imports (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ */
+
+// --- PreviewCompilationPayload (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Typed preview payload for Superset-side compilation.
+ * @complexity 2
+ */
+
+// --- SqlLabLaunchPayload (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Typed SQL Lab payload for audited launch handoff.
+ * @complexity 2
+ */
+
+// --- SupersetCompilationAdapter.__init__ (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Bind adapter to one Superset environment and client instance.
+ * @complexity 2
+ */
+
+// --- SupersetCompilationAdapter._supports_client_method (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Detect explicitly implemented client capabilities without treating loose mocks as real methods.
+ * @complexity 2
+ */
+
+// --- SupersetCompilationAdapter.compile_preview (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Request Superset-side compiled SQL preview for the current effective inputs.
+ * @complexity 4
+ * @data_contract Input[PreviewCompilationPayload] -> Output[CompiledPreview]
+ * @post returns a ready or failed preview artifact backed only by Superset-originated SQL or diagnostics.
+ * @pre dataset_id and effective inputs are available for the current session.
+ * @side_effect performs upstream preview requests.
+ */
+
+// --- SupersetCompilationAdapter.mark_preview_stale (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Invalidate previous preview after mapping or value changes.
+ * @complexity 2
+ * @post preview status becomes stale without fabricating a replacement artifact.
+ * @pre preview is a persisted preview artifact or current in-memory snapshot.
+ */
+
+// --- SupersetCompilationAdapter.create_sql_lab_session (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Create the canonical audited execution session after all launch gates pass.
+ * @complexity 4
+ * @data_contract Input[SqlLabLaunchPayload] -> Output[str]
+ * @post returns one canonical SQL Lab session reference from Superset.
+ * @pre compiled_sql is Superset-originated and launch gates are already satisfied.
+ * @side_effect performs upstream SQL Lab execution/session creation.
+ */
+
+// --- SupersetCompilationAdapter._request_superset_preview (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Request preview compilation through explicit client support backed by real Superset endpoints only.
+ * @complexity 4
+ * @data_contract Input[PreviewCompilationPayload] -> Output[Dict[str,Any]]
+ * @post returns one normalized upstream compilation response including the chosen strategy metadata.
+ * @pre payload contains a valid dataset identifier and deterministic execution inputs for one preview attempt.
+ * @side_effect issues one or more Superset preview requests through the client fallback chain.
+ */
+
+// --- SupersetCompilationAdapter._request_sql_lab_session (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Probe supported SQL Lab execution surfaces and return the first successful response.
+ * @complexity 4
+ * @data_contract Input[SqlLabLaunchPayload] -> Output[Dict[str,Any]]
+ * @post returns the first successful SQL Lab execution response from Superset.
+ * @pre payload carries non-empty Superset-originated SQL and a preview identifier for the current launch.
+ * @side_effect issues Superset dataset lookup and SQL Lab execution requests.
+ */
+
+// --- SupersetCompilationAdapter._normalize_preview_response (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Normalize candidate Superset preview responses into one compiled-sql structure.
+ * @complexity 3
+ */
+
+// --- SupersetCompilationAdapter._dump_json (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Serialize Superset request payload deterministically for network transport.
+ * @complexity 1
+ */
+
+// --- SupersetContextExtractorPackage (backend/src/core/utils/superset_context_extractor/__init__.py)
+/**!
+ * @brief Recover dataset and dashboard context from Superset links while preserving explicit partial-recovery markers.
+ * @complexity 4
+ * @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+ * @layer Infrastructure
+ * @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+ * @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+ * @rationale Decomposed from monolithic superset_context_extractor.py (1397 lines) into
+ * @side_effect Performs upstream Superset API reads.
+ */
+
+// --- SupersetContextExtractor (backend/src/core/utils/superset_context_extractor/__init__.py)
+/**!
+ * @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+ * @complexity 4
+ * @post extractor instance is ready to parse links against one Superset environment.
+ * @pre constructor receives a configured environment with a usable Superset base URL.
+ * @side_effect downstream parse operations may call Superset APIs through SupersetClient.
+ */
+
+// --- SupersetContextExtractorBase (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Base class and helpers for recovering dataset/dashboard context from Superset links with explicit partial-recovery markers.
+ * @complexity 4
+ * @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+ * @layer Infrastructure
+ * @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+ * @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+ * @side_effect Performs upstream Superset API reads.
+ */
+
+// --- _base_imports (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ */
+
+// --- SupersetParsedContext (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Normalized output of Superset link parsing for session intake and recovery.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase.__init__ (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Bind extractor to one Superset environment and client instance.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase.build_recovery_summary (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Summarize recovered, partial, and unresolved context for session state and UX.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase._extract_numeric_identifier (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a numeric identifier from a REST-like Superset URL path.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_reference (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard id-or-slug reference from a Superset URL path.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_permalink_key (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard permalink key from a Superset URL path.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_id_from_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard identifier from returned permalink state when present.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase._extract_chart_id_from_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a chart identifier from returned permalink state when dashboard id is absent.
+ * @complexity 2
+ */
+
+// --- SupersetContextExtractorBase._search_nested_numeric_key (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Recursively search nested dict/list payloads for the first numeric value under a candidate key set.
+ * @complexity 3
+ */
+
+// --- SupersetContextExtractorBase._decode_query_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Decode query-string structures used by Superset URL state transport.
+ * @complexity 2
+ */
+
+// --- SupersetContextFiltersExtractMixin (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ * @brief Extract normalized imported filters from decoded Superset query state (native_filters, dataMask, native_filter_state, form_data).
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- _filters_imports (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ */
+
+// --- SupersetContextFiltersExtractMixin._extract_imported_filters (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ * @brief Normalize imported filters from decoded query state without fabricating missing values.
+ * @complexity 2
+ */
+
+// --- SupersetContextParsingMixin (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- _parsing_imports (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ */
+
+// --- SupersetContextParsingMixin.parse_superset_link (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Extract candidate identifiers and query state from supported Superset URLs.
+ * @complexity 4
+ * @data_contract Input[link:str] -> Output[SupersetParsedContext]
+ * @post returns resolved dataset/dashboard context, preserving explicit partial-recovery state if some identifiers cannot be confirmed.
+ * @pre link is a non-empty Superset URL compatible with the configured environment.
+ * @side_effect may issue Superset API reads to resolve dataset references from dashboard or chart URLs.
+ */
+
+// --- SupersetContextParsingMixin._recover_dataset_binding_from_dashboard (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Recover a dataset binding from resolved dashboard context while preserving explicit unresolved markers.
+ * @complexity 3
+ */
+
+// --- SupersetContextExtractorPII (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief PII redaction helpers for assistant-facing dataset-review context — mask emails, UUIDs, long digit strings, and mixed identifiers.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- _pii_imports (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ */
+
+// --- mask_pii_value (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Redact likely sensitive identifiers while preserving structural hints for assistant-facing dataset-review context.
+ * @complexity 2
+ */
+
+// --- sanitize_imported_filter_for_assistant (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Build assistant-safe imported-filter payload with raw-value redaction metadata when sensitive tokens are detected.
+ * @complexity 2
+ */
+
+// --- _mask_sensitive_text (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Redact likely PII substrings from one string while preserving non-sensitive delimiters and token shape.
+ * @complexity 2
+ */
+
+// --- SupersetContextRecoveryMixin (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Recover imported filters from Superset parsed context and dashboard metadata.
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- _recovery_imports (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ */
+
+// --- SupersetContextRecoveryMixin.recover_imported_filters (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Build imported filter entries from URL state and Superset-side saved context.
+ * @complexity 4
+ * @data_contract Input[SupersetParsedContext] -> Output[List[Dict[str,Any]]]
+ * @post returns explicit recovered and partial filter entries with preserved provenance and confirmation requirements.
+ * @pre parsed_context comes from a successful Superset link parse for one environment.
+ * @side_effect may issue Superset reads for dashboard metadata enrichment.
+ */
+
+// --- SupersetContextRecoveryMixin._normalize_imported_filter_payload (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Normalize one imported-filter payload with explicit provenance and confirmation state.
+ * @complexity 2
+ */
+
+// --- SupersetContextTemplatesMixin (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Deterministically detect runtime variables and Jinja references from dataset query-bearing fields without execution.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- _templates_imports (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ */
+
+// --- SupersetContextTemplatesMixin.discover_template_variables (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Detect runtime variables and Jinja references from dataset query-bearing fields.
+ * @complexity 4
+ * @data_contract Input[dataset_payload:Dict[str,Any]] -> Output[List[Dict[str,Any]]]
+ * @post returns deduplicated explicit variable records without executing Jinja or fabricating runtime values.
+ * @pre dataset_payload is a Superset dataset-detail style payload with query-bearing fields when available.
+ * @side_effect none.
+ */
+
+// --- SupersetContextTemplatesMixin._collect_query_bearing_expressions (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Collect SQL and expression-bearing dataset fields for deterministic template-variable discovery.
+ * @complexity 3
+ */
+
+// --- SupersetContextTemplatesMixin._append_template_variable (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Append one deduplicated template-variable descriptor.
+ * @complexity 2
+ */
+
+// --- SupersetContextTemplatesMixin._extract_primary_jinja_identifier (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Extract a deterministic primary identifier from a Jinja expression without executing it.
+ * @complexity 2
+ */
+
+// --- SupersetContextTemplatesMixin._normalize_default_literal (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Normalize literal default fragments from template helper calls into JSON-safe values.
+ * @complexity 2
+ */
+
+// --- WsLogHandlerModule (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief WebSocket log handler module providing LogEntry DTO and WebSocketLogHandler for buffered log streaming.
+ * @complexity 3
+ */
+
+// --- WebSocketLogHandler (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Custom logging handler that captures log records into a fixed-capacity buffer for WebSocket streaming.
+ * @complexity 3
+ */
+
+// --- WebSocketLogHandler.__init__ (backend/src/core/ws_log_handler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- WebSocketLogHandler.emit (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Captures a log record, formats it, and stores it in the buffer as a LogEntry.
+ * @complexity 2
+ */
+
+// --- WebSocketLogHandler.get_recent_logs (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Returns a list of recent log entries from the buffer.
+ * @complexity 2
+ */
+
+// --- AppDependencies (backend/src/dependencies.py)
+/**!
+ * @brief Provides shared instances to app and routers.
+ * @complexity 4
+ * @layer Core
+ */
+
+// --- get_config_manager (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for ConfigManager.
+ * @complexity 1
+ * @post Returns shared ConfigManager instance.
+ * @pre Global config_manager must be initialized.
+ */
+
+// --- get_plugin_loader (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for PluginLoader.
+ * @complexity 1
+ * @post Returns shared PluginLoader instance.
+ * @pre Global plugin_loader must be initialized.
+ */
+
+// --- get_task_manager (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for TaskManager.
+ * @complexity 1
+ * @post Returns shared TaskManager instance.
+ * @pre Global task_manager must be initialized.
+ */
+
+// --- get_scheduler_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for SchedulerService.
+ * @complexity 1
+ * @post Returns shared SchedulerService instance.
+ * @pre Global scheduler_service must be initialized.
+ */
+
+// --- get_resource_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for ResourceService.
+ * @complexity 1
+ * @post Returns shared ResourceService instance.
+ * @pre Global resource_service must be initialized.
+ */
+
+// --- get_mapping_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for MappingService.
+ * @complexity 1
+ * @post Returns new MappingService instance.
+ * @pre Global config_manager must be initialized.
+ */
+
+// --- get_clean_release_repository (backend/src/dependencies.py)
+/**!
+ * @brief Legacy compatibility shim for CleanReleaseRepository.
+ * @complexity 1
+ * @post Returns a shared CleanReleaseRepository instance.
+ */
+
+// --- get_clean_release_facade (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for CleanReleaseFacade.
+ * @complexity 1
+ * @post Returns a facade instance with a fresh DB session.
+ */
+
+// --- APIKeyPrincipal (backend/src/dependencies.py)
+/**!
+ * @brief Dataclass representing an authenticated API key principal for service-to-service auth.
+ * @complexity 1
+ */
+
+// --- require_api_key_or_jwt (backend/src/dependencies.py)
+/**!
+ * @brief Factory: creates a dependency that accepts either a valid API key (with permission check)
+ * @complexity 4
+ */
+
+// --- check_api_key_environment_scope (backend/src/dependencies.py)
+/**!
+ * @brief Check the request's API key environment scope against a target env_id. Raises 400 if mismatch.
+ * @complexity 1
+ */
+
+// --- get_api_key_principal (backend/src/dependencies.py)
+/**!
+ * @brief FastAPI dependency that reads X-API-Key header and returns APIKeyPrincipal or None.
+ * @complexity 3
+ * @post If valid key: returns APIKeyPrincipal; if no header: returns None; if invalid: raises 401.
+ * @pre X-API-Key header may be present in the request.
+ * @side_effect Updates last_used_at on the APIKey row (non-blocking flush).
+ */
+
+// --- oauth2_scheme (backend/src/dependencies.py)
+/**!
+ * @brief OAuth2 password bearer scheme for token extraction (raises 401 on missing token).
+ * @complexity 1
+ */
+
+// --- oauth2_scheme_optional (backend/src/dependencies.py)
+/**!
+ * @brief Optional OAuth2 scheme — returns None instead of raising 401 when no token.
+ * @complexity 1
+ * @rationale Used in dual-auth routes (API key OR JWT) where JWT may be absent.
+ */
+
+// --- get_current_user (backend/src/dependencies.py)
+/**!
+ * @brief Dependency for retrieving currently authenticated user from a JWT.
+ * @complexity 3
+ * @post Returns User object if token is valid.
+ * @pre JWT token provided in Authorization header.
+ */
+
+// --- has_permission (backend/src/dependencies.py)
+/**!
+ * @brief Dependency for checking if the current user has a specific permission.
+ * @complexity 3
+ * @post Returns True if user has permission.
+ * @pre User is authenticated.
+ */
+
+// --- ModelsPackage (backend/src/models/__init__.py)
+/**!
+ * @brief Domain model package root.
+ */
+
+// --- TestCleanReleaseModels (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Contract testing for Clean Release models
+ */
+
+// --- test_release_candidate_valid (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a valid release candidate can be instantiated.
+ */
+
+// --- test_release_candidate_empty_id (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a release candidate with an empty ID is rejected.
+ * @test_fixture valid_enterprise_policy
+ */
+
+// --- test_enterprise_policy_valid (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a valid enterprise policy is accepted.
+ * @test_edge enterprise_policy_missing_prohibited
+ */
+
+// --- test_enterprise_policy_missing_prohibited (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that an enterprise policy without prohibited categories is rejected.
+ * @test_edge enterprise_policy_external_allowed
+ */
+
+// --- test_enterprise_policy_external_allowed (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that an enterprise policy allowing external sources is rejected.
+ * @test_edge manifest_count_mismatch
+ * @test_invariant manifest_consistency
+ */
+
+// --- test_manifest_count_mismatch (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a manifest with count mismatches is rejected.
+ */
+
+// --- test_compliant_run_validation (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify compliant run validation logic and mandatory stage checks.
+ */
+
+// --- test_report_validation (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify compliance report validation based on status and violation counts.
+ */
+
+// --- test_models (backend/src/models/__tests__/test_models.py)
+/**!
+ * @brief Unit tests for data models
+ * @complexity 1
+ * @layer Domain
+ */
+
+// --- test_environment_model (backend/src/models/__tests__/test_models.py)
+/**!
+ * @brief Tests that Environment model correctly stores values.
+ * @post Values are verified.
+ * @pre Environment class is available.
+ */
+
+// --- test_report_models (backend/src/models/__tests__/test_report_models.py)
+/**!
+ * @brief Unit tests for report Pydantic models and their validators
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- APIKeyModel (backend/src/models/api_key.py)
+/**!
+ * @brief SQLAlchemy model for API Key authentication — stores SHA-256 hash only, raw key shown once at creation.
+ * @complexity 1
+ * @invariant Raw key is NEVER stored — shown once at creation and discarded.
+ * @layer Domain
+ */
+
+// --- APIKey (backend/src/models/api_key.py)
+/**!
+ * @brief Stores API key metadata and SHA-256 hash for service-to-service authentication.
+ * @complexity 1
+ */
+
+// --- AssistantModels (backend/src/models/assistant.py)
+/**!
+ * @brief SQLAlchemy models for assistant audit trail and confirmation tokens.
+ * @complexity 3
+ * @data_contract AssistantData -> AssistantRecord
+ * @invariant Assistant records preserve immutable ids and creation timestamps.
+ * @layer Domain
+ * @side_effect Defines assistant audit/message/confirmation tables
+ */
+
+// --- AssistantAuditRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Store audit decisions and outcomes produced by assistant command handling.
+ * @complexity 3
+ * @post Audit payload remains available for compliance and debugging.
+ * @pre user_id must identify the actor for every record.
+ */
+
+// --- AssistantMessageRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Persist chat history entries for assistant conversations.
+ * @complexity 3
+ * @post Message row can be queried in chronological order.
+ * @pre user_id, conversation_id, role and text must be present.
+ */
+
+// --- AssistantConfirmationRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Persist risky operation confirmation tokens with lifecycle state.
+ * @complexity 3
+ * @post State transitions can be tracked and audited.
+ * @pre intent/dispatch and expiry timestamp must be provided.
+ */
+
+// --- AuthModels (backend/src/models/auth.py)
+/**!
+ * @brief SQLAlchemy models for multi-user authentication and authorization.
+ * @complexity 5
+ * @data_contract UserData -> UserRecord
+ * @invariant Usernames and emails must be unique.
+ * @layer Domain
+ * @post Auth ORM models registered with unique constraints
+ * @pre Database engine initialized
+ * @side_effect Defines auth user tables
+ */
+
+// --- generate_uuid (backend/src/models/auth.py)
+/**!
+ * @brief Generates a unique UUID string.
+ * @post Returns a string representation of a new UUID.
+ */
+
+// --- user_roles (backend/src/models/auth.py)
+/**!
+ * @brief Association table for many-to-many relationship between Users and Roles.
+ */
+
+// --- role_permissions (backend/src/models/auth.py)
+/**!
+ * @brief Association table for many-to-many relationship between Roles and Permissions.
+ */
+
+// --- Role (backend/src/models/auth.py)
+/**!
+ * @brief Represents a collection of permissions.
+ */
+
+// --- Permission (backend/src/models/auth.py)
+/**!
+ * @brief Represents a specific capability within the system.
+ */
+
+// --- ADGroupMapping (backend/src/models/auth.py)
+/**!
+ * @brief Maps an Active Directory group to a local System Role.
+ */
+
+// --- CleanReleaseModels (backend/src/models/clean_release.py)
+/**!
+ * @brief Define canonical clean release domain entities and lifecycle guards.
+ * @complexity 3
+ * @data_contract Model[ReleaseCandidate, CandidateArtifact, DistributionManifest, ComplianceRun, ComplianceReport]
+ * @invariant Immutable snapshots are never mutated; forbidden lifecycle transitions are rejected.
+ * @layer Domain
+ * @post Provides SQLAlchemy and dataclass definitions for governance domain.
+ * @pre Base mapping model and release enums are available.
+ * @side_effect None (schema definition).
+ */
+
+// --- ExecutionMode (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible execution mode enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckFinalStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible final status enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageName (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage name enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage status enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageResult (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage result container for legacy TUI/orchestrator tests.
+ */
+
+// --- ProfileType (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible profile enum for legacy TUI bootstrap logic.
+ */
+
+// --- RegistryStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible registry status enum for legacy TUI bootstrap logic.
+ */
+
+// --- ReleaseCandidateStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible release candidate status enum for legacy TUI.
+ */
+
+// --- ResourceSourceEntry (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible source entry model for legacy TUI bootstrap logic.
+ */
+
+// --- ResourceSourceRegistry (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible source registry model for legacy TUI bootstrap logic.
+ */
+
+// --- CleanProfilePolicy (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible policy model for legacy TUI bootstrap logic.
+ */
+
+// --- ComplianceCheckRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible run model for legacy TUI typing/import compatibility.
+ */
+
+// --- ReleaseCandidate (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents the release unit being prepared and governed.
+ * @post status advances only through legal transitions.
+ * @pre id, version, source_snapshot_ref are non-empty.
+ */
+
+// --- CandidateArtifact (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents one artifact associated with a release candidate.
+ */
+
+// --- ManifestItem (backend/src/models/clean_release.py)
+/**!
+ */
+
+// --- ManifestSummary (backend/src/models/clean_release.py)
+/**!
+ */
+
+// --- DistributionManifest (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable snapshot of the candidate payload.
+ * @invariant Immutable after creation.
+ */
+
+// --- SourceRegistrySnapshot (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable registry snapshot for allowed sources.
+ */
+
+// --- CleanPolicySnapshot (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable policy snapshot used to evaluate a run.
+ */
+
+// --- ComplianceRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Operational record for one compliance execution.
+ */
+
+// --- ComplianceStageRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Stage-level execution record inside a run.
+ */
+
+// --- ViolationSeverity (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible violation severity enum for legacy clean-release tests.
+ */
+
+// --- ViolationCategory (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible violation category enum for legacy clean-release tests.
+ */
+
+// --- ComplianceViolation (backend/src/models/clean_release.py)
+/**!
+ * @brief Violation produced by a stage.
+ */
+
+// --- ComplianceReport (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable result derived from a completed run.
+ * @invariant Immutable after creation.
+ */
+
+// --- ApprovalDecision (backend/src/models/clean_release.py)
+/**!
+ * @brief Approval or rejection bound to a candidate and report.
+ */
+
+// --- PublicationRecord (backend/src/models/clean_release.py)
+/**!
+ * @brief Publication or revocation record.
+ */
+
+// --- CleanReleaseAuditLog (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents a persistent audit log entry for clean release actions.
+ */
+
+// --- AppConfigRecord (backend/src/models/config.py)
+/**!
+ * @brief Stores persisted application configuration as a single authoritative record model.
+ * @data_contract Input -> persistence row {id:str, payload:json, updated_at:datetime}; Output -> AppConfigRecord ORM entity.
+ * @post ORM table 'app_configurations' exposes id, payload, and updated_at fields with declared nullability/default semantics.
+ * @pre SQLAlchemy declarative Base is initialized and table metadata registration is active.
+ * @side_effect Registers ORM mapping metadata during module import.
+ */
+
+// --- NotificationConfig (backend/src/models/config.py)
+/**!
+ * @brief Stores persisted provider-level notification configuration and encrypted credentials metadata.
+ * @data_contract Input -> persistence row {id:str, type:str, name:str, credentials:json, is_active:bool, created_at:datetime, updated_at:datetime}; Output -> NotificationConfig ORM entity.
+ * @post ORM table 'notification_configs' exposes id, type, name, credentials, is_active, created_at, updated_at fields with declared constraints/defaults.
+ * @pre SQLAlchemy declarative Base is initialized and uuid generation is available at instance creation time.
+ * @side_effect Registers ORM mapping metadata during module import; may generate UUID values for new entity instances.
+ */
+
+// --- DashboardModels (backend/src/models/dashboard.py)
+/**!
+ * @brief Defines data models for dashboard metadata and selection.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- DashboardMetadata (backend/src/models/dashboard.py)
+/**!
+ * @brief Represents a dashboard available for migration.
+ * @complexity 1
+ */
+
+// --- DashboardSelection (backend/src/models/dashboard.py)
+/**!
+ * @brief Represents the user's selection of dashboards to migrate.
+ * @complexity 1
+ */
+
+// --- DatasetReviewModels (backend/src/models/dataset_review.py)
+/**!
+ * @brief Thin facade re-exporting all dataset review domain models from the decomposed sub-package.
+ * @complexity 2
+ * @invariant All public model classes and enums remain importable from `src.models.dataset_review` without changes.
+ * @layer Domain
+ * @rationale Original 984-line monolith violated INV_7 (400-line module limit). Decomposed into domain-focused sub-modules while preserving backward-compatible import paths.
+ * @rejected Keeping all models in a single file because it exceeded the fractal limit by 2.5x and accumulated structural erosion risk.
+ */
+
+// --- DatasetReviewClarificationModels (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief Clarification session, question, option, and answer models for guided review flow.
+ * @complexity 3
+ * @data_contract ClarificationData -> ClarificationRecord
+ * @invariant Only one active clarification question may exist at a time per session.
+ * @layer Domain
+ * @post Clarification ORM models registered
+ * @pre Database engine initialized
+ * @side_effect Defines dataset review clarification tables
+ */
+
+// --- ClarificationSession (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One clarification session aggregate owning questions and tracking resolution progress.
+ * @complexity 2
+ */
+
+// --- ClarificationQuestion (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One clarification question with priority ordering, options, and state machine.
+ * @complexity 2
+ */
+
+// --- ClarificationOption (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One selectable option for a clarification question with recommendation flag.
+ * @complexity 1
+ */
+
+// --- ClarificationAnswer (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One persisted clarification answer with impact summary and feedback tracking.
+ * @complexity 2
+ */
+
+// --- DatasetReviewEnums (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief All enumeration types for the dataset review domain, grouped for stable cross-module reuse.
+ * @complexity 2
+ * @invariant Enum values are string-based for JSON serialization compatibility.
+ * @layer Domain
+ */
+
+// --- SessionStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status of a dataset review session.
+ * @complexity 1
+ */
+
+// --- SessionPhase (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Ordered phase progression for dataset review orchestration.
+ * @complexity 1
+ */
+
+// --- ReadinessState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Granular readiness indicator driving the recommended-action UX flow.
+ * @complexity 1
+ */
+
+// --- RecommendedAction (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Next-action guidance derived from the current readiness state.
+ * @complexity 1
+ */
+
+// --- SessionCollaboratorRole (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief RBAC role for session collaborators.
+ * @complexity 1
+ */
+
+// --- BusinessSummarySource (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Provenance of the dataset business summary text.
+ * @complexity 1
+ */
+
+// --- ConfidenceState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Confidence level for dataset profile completeness.
+ * @complexity 1
+ */
+
+// --- FindingArea (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Domain area classification for validation findings.
+ * @complexity 1
+ */
+
+// --- FindingSeverity (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Severity classification for validation findings.
+ * @complexity 1
+ */
+
+// --- ResolutionState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Resolution status for validation findings and clarification items.
+ * @complexity 1
+ */
+
+// --- SemanticSourceType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Classification of semantic enrichment source origins.
+ * @complexity 1
+ */
+
+// --- TrustLevel (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Trust classification for semantic source reliability.
+ * @complexity 1
+ */
+
+// --- SemanticSourceStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for semantic source application.
+ * @complexity 1
+ */
+
+// --- FieldKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Kind classification for semantic field entries.
+ * @complexity 1
+ */
+
+// --- FieldProvenance (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Provenance tracking for semantic field value origin.
+ * @complexity 1
+ */
+
+// --- CandidateMatchType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Match type classification for semantic candidates.
+ * @complexity 1
+ */
+
+// --- CandidateStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for semantic candidate proposals.
+ * @complexity 1
+ */
+
+// --- FilterSource (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Origin classification for imported filters.
+ * @complexity 1
+ */
+
+// --- FilterConfidenceState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Confidence classification for imported filter values.
+ * @complexity 1
+ */
+
+// --- FilterRecoveryStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Recovery quality status for imported filters.
+ * @complexity 1
+ */
+
+// --- VariableKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Kind classification for template variables.
+ * @complexity 1
+ */
+
+// --- MappingStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for template variable mapping.
+ * @complexity 1
+ */
+
+// --- MappingMethod (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Method classification for execution mapping creation.
+ * @complexity 1
+ */
+
+// --- MappingWarningLevel (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Warning severity for execution mapping quality indicators.
+ * @complexity 1
+ */
+
+// --- ApprovalState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Approval lifecycle for execution mapping gate checks.
+ * @complexity 1
+ */
+
+// --- ClarificationStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for clarification sessions.
+ * @complexity 1
+ */
+
+// --- QuestionState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief State machine for individual clarification questions.
+ * @complexity 1
+ */
+
+// --- AnswerKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Classification of clarification answer types.
+ * @complexity 1
+ */
+
+// --- PreviewStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for compiled SQL previews.
+ * @complexity 1
+ */
+
+// --- LaunchStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Outcome status for dataset launch handoff.
+ * @complexity 1
+ */
+
+// --- ArtifactType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Type classification for export artifacts.
+ * @complexity 1
+ */
+
+// --- ArtifactFormat (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Format classification for export artifact output.
+ * @complexity 1
+ */
+
+// --- DatasetReviewExecutionModels (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief Compiled preview, run context, session event, and export artifact models for execution and audit.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- CompiledPreview (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One compiled SQL preview snapshot with fingerprint for staleness detection.
+ * @complexity 2
+ */
+
+// --- DatasetRunContext (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief Immutable launch audit snapshot capturing effective filters, template params, and approval state at launch time.
+ * @complexity 2
+ */
+
+// --- SessionEvent (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One persisted audit event for dataset review session mutations.
+ * @complexity 2
+ */
+
+// --- ExportArtifact (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One persisted export artifact reference for documentation and validation outputs.
+ * @complexity 2
+ */
+
+// --- DatasetReviewFilterModels (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Imported filter and template variable models for Superset context recovery and execution mapping.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- ImportedFilter (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Recovered Superset filter with confidence and recovery status tracking.
+ * @complexity 2
+ */
+
+// --- TemplateVariable (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Discovered template variable from dataset SQL with mapping status tracking.
+ * @complexity 2
+ */
+
+// --- DatasetReviewFindingModels (backend/src/models/dataset_review_pkg/_finding_models.py)
+/**!
+ * @brief Validation finding model for tracking blocking, warning, and informational issues during review.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- ValidationFinding (backend/src/models/dataset_review_pkg/_finding_models.py)
+/**!
+ * @brief Structured finding record for dataset review validation issues with resolution tracking.
+ * @complexity 2
+ */
+
+// --- DatasetReviewMappingModels (backend/src/models/dataset_review_pkg/_mapping_models.py)
+/**!
+ * @brief Execution mapping model linking imported filters to template variables with approval gates.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- ExecutionMapping (backend/src/models/dataset_review_pkg/_mapping_models.py)
+/**!
+ * @brief One filter-to-variable mapping with approval gate, effective value, and transformation metadata.
+ * @complexity 2
+ * @invariant Explicit approval is required before launch when requires_explicit_approval is true.
+ */
+
+// --- DatasetReviewProfileModels (backend/src/models/dataset_review_pkg/_profile_models.py)
+/**!
+ * @brief Dataset profile model capturing business summary, confidence, and completeness metadata.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- DatasetProfile (backend/src/models/dataset_review_pkg/_profile_models.py)
+/**!
+ * @brief One-to-one profile snapshot for a dataset review session, tracking business summary provenance and completeness.
+ * @complexity 2
+ */
+
+// --- DatasetReviewSemanticModels (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Semantic source, field entry, and candidate models for dictionary-driven semantic enrichment.
+ * @complexity 3
+ * @data_contract SemanticData -> SemanticFieldEntry
+ * @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+ * @layer Domain
+ * @post Semantic ORM models registered with override protection
+ * @pre Database engine initialized
+ * @side_effect Defines dataset review semantic tables
+ */
+
+// --- SemanticSource (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Registered semantic enrichment source with trust level and application status.
+ * @complexity 2
+ */
+
+// --- SemanticFieldEntry (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Per-field semantic metadata entry with provenance tracking, lock state, and candidate set.
+ * @complexity 3
+ * @invariant Locked fields preserve their active value regardless of later candidate proposals.
+ */
+
+// --- SemanticCandidate (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief One proposed semantic value for a field entry, ranked by match type and confidence.
+ * @complexity 2
+ */
+
+// --- DatasetReviewSessionModels (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief Session aggregate root and collaborator models for dataset review orchestration.
+ * @complexity 3
+ * @data_contract SessionData -> SessionRecord
+ * @invariant Session and profile entities are strictly scoped to an authenticated user.
+ * @layer Domain
+ * @post Session ORM models registered with optimistic locking
+ * @pre Database engine initialized
+ * @side_effect Defines dataset review session tables
+ */
+
+// --- SessionCollaborator (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief RBAC collaborator record linking a user to a dataset review session with a specific role.
+ * @complexity 2
+ */
+
+// --- DatasetReviewSession (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief Aggregate root for the dataset review lifecycle, owning all child entities and driving readiness transitions.
+ * @complexity 3
+ * @invariant Optimistic-lock version column prevents lost-update races on concurrent mutations.
+ */
+
+// --- FilterStateModels (backend/src/models/filter_state.py)
+/**!
+ * @brief Pydantic models for Superset native filter state extraction and restoration.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- FilterState (backend/src/models/filter_state.py)
+/**!
+ * @brief Represents the state of a single native filter.
+ * @complexity 2
+ * @data_contract Input[extraFormData: Dict, filterState: Dict, ownState: Optional[Dict]] -> Model[FilterState]
+ */
+
+// --- NativeFilterDataMask (backend/src/models/filter_state.py)
+/**!
+ * @brief Represents the dataMask containing all native filter states.
+ * @complexity 2
+ * @data_contract Input[Dict[filter_id, FilterState]] -> Model[NativeFilterDataMask]
+ */
+
+// --- ParsedNativeFilters (backend/src/models/filter_state.py)
+/**!
+ * @brief Result of parsing native filters from permalink or native_filters_key.
+ * @complexity 2
+ * @data_contract Input[dataMask: Dict, metadata: Dict] -> Model[ParsedNativeFilters]
+ */
+
+// --- DashboardURLFilterExtraction (backend/src/models/filter_state.py)
+/**!
+ * @brief Result of parsing a complete dashboard URL for filter information.
+ * @complexity 2
+ * @data_contract Input[url: str, dashboard_id: Optional, filter_type: Optional, filters: Dict] -> Model[DashboardURLFilterExtraction]
+ */
+
+// --- ExtraFormDataMerge (backend/src/models/filter_state.py)
+/**!
+ * @brief Configuration for merging extraFormData from different sources.
+ * @complexity 2
+ * @data_contract Input[append_keys: List[str], override_keys: List[str]] -> Model[ExtraFormDataMerge]
+ */
+
+// --- GitModels (backend/src/models/git.py)
+/**!
+ */
+
+// --- GitServerConfig (backend/src/models/git.py)
+/**!
+ * @brief Configuration for a Git server connection.
+ * @complexity 1
+ */
+
+// --- GitRepository (backend/src/models/git.py)
+/**!
+ * @brief Tracking for a local Git repository linked to a dashboard.
+ * @complexity 1
+ */
+
+// --- DeploymentEnvironment (backend/src/models/git.py)
+/**!
+ * @brief Target Superset environments for dashboard deployment.
+ * @complexity 1
+ */
+
+// --- LlmModels (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy models for LLM provider configuration and validation results.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- ValidationPolicy (backend/src/models/llm.py)
+/**!
+ * @brief Defines a scheduled rule for validating a group of dashboards within an execution window.
+ */
+
+// --- LLMProvider (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy model for LLM provider configuration.
+ */
+
+// --- ValidationRecord (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy model for dashboard validation history.
+ */
+
+// --- MaintenanceModels (backend/src/models/maintenance.py)
+/**!
+ * @brief SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.
+ * @complexity 2
+ * @invariant MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint
+ * @layer Domain
+ */
+
+// --- MaintenanceEventStatus (backend/src/models/maintenance.py)
+/**!
+ * @complexity 1
+ */
+
+// --- MaintenanceDashboardBannerStatus (backend/src/models/maintenance.py)
+/**!
+ * @complexity 1
+ */
+
+// --- MaintenanceDashboardStateStatus (backend/src/models/maintenance.py)
+/**!
+ * @complexity 1
+ */
+
+// --- DashboardScope (backend/src/models/maintenance.py)
+/**!
+ * @complexity 1
+ */
+
+// --- MaintenanceEvent (backend/src/models/maintenance.py)
+/**!
+ * @brief A record of a maintenance event with table list, time window, status, and linked dashboard states.
+ * @complexity 1
+ */
+
+// --- MaintenanceDashboardBanner (backend/src/models/maintenance.py)
+/**!
+ * @brief The canonical "one chart per dashboard" entity. Unique partial index enforces single active banner per dashboard.
+ * @complexity 1
+ * @invariant Unique partial index (environment_id, dashboard_id) WHERE status='active'
+ */
+
+// --- MaintenanceDashboardState (backend/src/models/maintenance.py)
+/**!
+ * @brief Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.
+ * @complexity 1
+ */
+
+// --- MaintenanceSettings (backend/src/models/maintenance.py)
+/**!
+ * @brief Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').
+ * @complexity 1
+ * @invariant id must always be 'default' — enforced by CheckConstraint
+ */
+
+// --- MappingModels (backend/src/models/mapping.py)
+/**!
+ * @brief Defines the database schema for environment metadata and database mappings using SQLAlchemy.
+ * @complexity 5
+ * @invariant All primary keys are UUID strings.
+ * @layer Domain
+ */
+
+// --- Base (backend/src/models/mapping.py)
+/**!
+ * @brief SQLAlchemy declarative base for all domain models.
+ * @complexity 1
+ */
+
+// --- ResourceType (backend/src/models/mapping.py)
+/**!
+ * @brief Enumeration of possible Superset resource types for ID mapping.
+ * @complexity 1
+ */
+
+// --- MigrationStatus (backend/src/models/mapping.py)
+/**!
+ * @brief Enumeration of possible migration job statuses.
+ * @complexity 1
+ */
+
+// --- MigrationJob (backend/src/models/mapping.py)
+/**!
+ * @brief Represents a single migration execution job.
+ * @complexity 2
+ */
+
+// --- ResourceMapping (backend/src/models/mapping.py)
+/**!
+ * @brief Maps a universal UUID for a resource to its actual ID on a specific environment.
+ * @complexity 3
+ * @test_data resource_mapping_record -> {'environment_id': 'prod-env-1', 'resource_type': 'chart', 'uuid': '123e4567-e89b-12d3-a456-426614174000', 'remote_integer_id': '42'}
+ */
+
+// --- ProfileModels (backend/src/models/profile.py)
+/**!
+ * @brief Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
+ * @complexity 5
+ * @data_contract ProfileData -> PreferenceRecord
+ * @invariant Sensitive Git token is stored encrypted and never returned in plaintext.
+ * @layer Domain
+ * @post Profile ORM models registered
+ * @pre Database engine initialized
+ * @side_effect Defines user profile/preference tables
+ */
+
+// --- UserDashboardPreference (backend/src/models/profile.py)
+/**!
+ * @brief Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
+ * @complexity 3
+ */
+
+// --- ReportModels (backend/src/models/report.py)
+/**!
+ * @brief Canonical report schemas for unified task reporting across heterogeneous task types.
+ * @complexity 3
+ * @data_contract Model[TaskReport, ReportCollection, ReportDetailView]
+ * @invariant Canonical report fields are always present for every report item.
+ * @layer Domain
+ * @post Provides validated schemas for cross-plugin reporting and UI consumption.
+ * @pre Pydantic library and task manager models are available.
+ * @side_effect None (schema definition).
+ */
+
+// --- TaskType (backend/src/models/report.py)
+/**!
+ * @brief Supported normalized task report types.
+ * @complexity 3
+ * @invariant Must contain valid generic task type mappings.
+ */
+
+// --- ReportStatus (backend/src/models/report.py)
+/**!
+ * @brief Supported normalized report status values.
+ * @complexity 3
+ * @invariant TaskStatus enum mapping logic holds.
+ */
+
+// --- ErrorContext (backend/src/models/report.py)
+/**!
+ * @brief Error and recovery context for failed/partial reports.
+ * @complexity 3
+ * @invariant The properties accurately describe error state.
+ * @test_contract ErrorContextModel ->
+ */
+
+// --- TaskReport (backend/src/models/report.py)
+/**!
+ * @brief Canonical normalized report envelope for one task execution.
+ * @complexity 3
+ * @invariant Must represent canonical task record attributes.
+ * @test_contract TaskReportModel ->
+ */
+
+// --- ReportQuery (backend/src/models/report.py)
+/**!
+ * @brief Query object for server-side report filtering, sorting, and pagination.
+ * @complexity 3
+ * @invariant Time and pagination queries are mutually consistent.
+ * @test_contract ReportQueryModel ->
+ */
+
+// --- ReportCollection (backend/src/models/report.py)
+/**!
+ * @brief Paginated collection of normalized task reports.
+ * @complexity 3
+ * @invariant Represents paginated data correctly.
+ * @test_contract ReportCollectionModel ->
+ */
+
+// --- ReportDetailView (backend/src/models/report.py)
+/**!
+ * @brief Detailed report representation including diagnostics and recovery actions.
+ * @complexity 3
+ * @invariant Incorporates a report and logs correctly.
+ * @test_contract ReportDetailViewModel ->
+ */
+
+// --- StorageModels (backend/src/models/storage.py)
+/**!
+ * @rationale Fixed typo 'repositorys' → 'repositories' in FileCategory.REPOSITORY and StorageConfig.repo_path default. Breaking change documented for existing installations.
+ */
+
+// --- FileCategory (backend/src/models/storage.py)
+/**!
+ * @brief Enumeration of supported file categories in the storage system.
+ * @complexity 1
+ */
+
+// --- StorageConfig (backend/src/models/storage.py)
+/**!
+ * @brief Configuration model for the storage system, defining paths and naming patterns.
+ * @complexity 1
+ */
+
+// --- StoredFile (backend/src/models/storage.py)
+/**!
+ * @brief Data model representing metadata for a file stored in the system.
+ * @complexity 1
+ */
+
+// --- TaskModels (backend/src/models/task.py)
+/**!
+ * @brief Defines the database schema for task execution records.
+ * @complexity 1
+ * @invariant All primary keys are UUID strings.
+ * @layer Domain
+ */
+
+// --- TaskRecord (backend/src/models/task.py)
+/**!
+ * @brief Represents a persistent record of a task execution.
+ * @complexity 1
+ */
+
+// --- TaskLogRecord (backend/src/models/task.py)
+/**!
+ * @brief Represents a single persistent log entry for a task.
+ * @complexity 3
+ * @invariant Each log entry belongs to exactly one task.
+ * @test_contract TaskLogCreate ->
+ */
+
+// --- TranslateModels (backend/src/models/translate.py)
+/**!
+ * @brief SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- TranslationJob (backend/src/models/translate.py)
+/**!
+ * @brief A translation job representing a multi-dialect conversion task with column mappings, LLM config, and dictionary attachments.
+ * @rationale Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.
+ * @rejected Invalidating in-progress runs on config edit would break scheduled run continuity.
+ */
+
+// --- TranslationRun (backend/src/models/translate.py)
+/**!
+ * @brief Represents a single execution of a translation job, capturing status, timing, and Superset execution metadata.
+ */
+
+// --- TranslationBatch (backend/src/models/translate.py)
+/**!
+ * @brief Groups translation records within a run into manageable batches with timing and record counts.
+ */
+
+// --- TranslationRecord (backend/src/models/translate.py)
+/**!
+ * @brief Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.
+ */
+
+// --- TranslationEvent (backend/src/models/translate.py)
+/**!
+ * @brief Audit/event log for translation operations, with optional run_id for context.
+ */
+
+// --- TranslationPreviewSession (backend/src/models/translate.py)
+/**!
+ * @brief A preview session allowing users to review proposed translations before applying them.
+ */
+
+// --- TranslationPreviewRecord (backend/src/models/translate.py)
+/**!
+ * @brief Individual preview entry within a preview session, showing original and translated content side by side.
+ */
+
+// --- TerminologyDictionary (backend/src/models/translate.py)
+/**!
+ * @brief A named collection of terminology mappings used during translation to ensure consistent term translation.
+ */
+
+// --- DictionaryEntry (backend/src/models/translate.py)
+/**!
+ * @brief A single term mapping entry with case-insensitive unique constraint on source_term_normalized and origin tracking.
+ */
+
+// --- TranslationSchedule (backend/src/models/translate.py)
+/**!
+ * @brief Defines a cron-based schedule for recurring translation jobs.
+ */
+
+// --- TranslationJobDictionary (backend/src/models/translate.py)
+/**!
+ * @brief Many-to-many association between translation jobs and terminology dictionaries.
+ */
+
+// --- MetricSnapshot (backend/src/models/translate.py)
+/**!
+ * @brief Captures translation performance metrics at a point in time with config/content/dictionary hash keys for aggregation.
+ */
+
+// --- TranslationLanguage (backend/src/models/translate.py)
+/**!
+ * @brief Per-language translation result for a single record, supporting multi-language output.
+ * @complexity 1
+ */
+
+// --- TranslationPreviewLanguage (backend/src/models/translate.py)
+/**!
+ * @brief Per-language preview entry within a preview session.
+ * @complexity 1
+ */
+
+// --- TranslationRunLanguageStats (backend/src/models/translate.py)
+/**!
+ * @brief Per-language statistics for a translation run (row counts, tokens, cost).
+ * @complexity 1
+ */
+
+// --- src.plugins (backend/src/plugins/__init__.py)
+/**!
+ * @brief Plugin package root for dynamic discovery and runtime imports.
+ */
+
+// --- BackupPlugin (backend/src/plugins/backup.py)
+/**!
+ * @brief A plugin that provides functionality to back up Superset dashboards.
+ * @layer App
+ */
+
+// --- DebugPluginModule (backend/src/plugins/debug.py)
+/**!
+ * @brief Plugin for diagnostics. Inherits PluginBase.
+ * @layer Plugin
+ */
+
+// --- DebugPlugin (backend/src/plugins/debug.py)
+/**!
+ * @brief Plugin for system diagnostics and debugging.
+ */
+
+// --- GitPluginExt (backend/src/plugins/git/__init__.py)
+/**!
+ * @brief Git plugin extension package root.
+ */
+
+// --- GitLLMExtensionModule (backend/src/plugins/git/llm_extension.py)
+/**!
+ * @brief LLM-based extensions for the Git plugin, specifically for commit message generation.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- GitLLMExtension (backend/src/plugins/git/llm_extension.py)
+/**!
+ * @brief Provides LLM capabilities to the Git plugin.
+ */
+
+// --- GitPluginModule (backend/src/plugins/git_plugin.py)
+/**!
+ * @brief Предоставляет плагин для версионирования и развертывания дашбордов Superset.
+ * @complexity 4
+ * @invariant _handle_sync сохраняет backup управляемых директорий перед удалением;
+ * @layer Plugin
+ */
+
+// --- GitPlugin (backend/src/plugins/git_plugin.py)
+/**!
+ * @brief Реализация плагина Git Integration для управления версиями дашбордов.
+ */
+
+// --- LLMAnalysisPackage (backend/src/plugins/llm_analysis/__init__.py)
+/**!
+ */
+
+// --- LLMAnalysisModels (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Define Pydantic models for LLM Analysis plugin.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- LLMProviderType (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Enum for supported LLM providers.
+ */
+
+// --- LLMProviderConfig (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Configuration for an LLM provider.
+ */
+
+// --- ValidationStatus (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Enum for dashboard validation status.
+ */
+
+// --- DetectedIssue (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Model for a single issue detected during validation.
+ */
+
+// --- ValidationResult (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Model for dashboard validation result.
+ */
+
+// --- LLMAnalysisPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Implements DashboardValidationPlugin and DocumentationPlugin.
+ * @complexity 5
+ * @data_contract AnalysisRequest -> AnalysisResult
+ * @invariant All LLM interactions must be executed as asynchronous tasks.
+ * @layer Plugin
+ */
+
+// --- _is_masked_or_invalid_api_key (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Guards against placeholder or malformed API keys in runtime.
+ * @post Returns True when value cannot be used for authenticated provider calls.
+ * @pre value may be None.
+ */
+
+// --- _json_safe_value (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Recursively normalize payload values for JSON serialization.
+ * @post datetime values are converted to ISO strings.
+ * @pre value may be nested dict/list with datetime values.
+ */
+
+// --- DashboardValidationPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Plugin for automated dashboard health analysis using LLMs.
+ */
+
+// --- DocumentationPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Plugin for automated dataset documentation using LLMs.
+ */
+
+// --- LLMAnalysisScheduler (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Provides helper functions to schedule LLM-based validation tasks.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- schedule_dashboard_validation (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Schedules a recurring dashboard validation task.
+ * @side_effect Adds a job to the scheduler service.
+ */
+
+// --- _parse_cron (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Basic cron parser placeholder.
+ */
+
+// --- LLMAnalysisService (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Services for LLM interaction and dashboard screenshots.
+ * @complexity 5
+ * @data_contract DashboardSpec -> Screenshot + Analysis
+ * @invariant Screenshots must be 1920px width and capture full page height.
+ * @layer Plugin
+ * @rationale Extracted all hardcoded timeouts into named module-level constants (PLAYWRIGHT_NAVIGATION_TIMEOUT_MS, PLAYWRIGHT_WAIT_TIMEOUT_MS, PLAYWRIGHT_SHORT_TIMEOUT_MS, HTTP_REQUEST_TIMEOUT_MS, SCREENSHOT_SERVICE_TIMEOUT_MS, LLM_HTTP_TIMEOUT_S) and DEFAULT_USER_AGENT. Zero remaining numeric timeout literals.
+ */
+
+// --- ScreenshotService (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Handles capturing screenshots of Superset dashboards.
+ */
+
+// --- LLMClient (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Wrapper for LLM provider APIs.
+ */
+
+// --- MaintenanceBannerPlugin (backend/src/plugins/maintenance_banner.py)
+/**!
+ * @brief TaskManager plugin for executing maintenance banner operations (start, end, end-all).
+ * @complexity 4
+ */
+
+// --- MapperPluginModule (backend/src/plugins/mapper.py)
+/**!
+ * @brief Plugin for dataset column mapping. Inherits PluginBase.
+ * @layer Plugin
+ */
+
+// --- MapperPlugin (backend/src/plugins/mapper.py)
+/**!
+ * @brief Plugin for mapping dataset columns verbose names.
+ */
+
+// --- MigrationPlugin (backend/src/plugins/migration.py)
+/**!
+ * @brief Orchestrates export, DB-mapping transformation, and import of Superset dashboards across environments.
+ * @complexity 5
+ * @data_contract Input[TaskContext{from_env,to_env,dashboard_regex,replace_db_config,from_db_id,to_db_id,passwords?}] -> Output[MigrationResult|artifact set]
+ * @invariant Dashboards must never be imported with unmapped/source DB connections to prevent data leaks or cross-environment pollution.
+ * @layer App
+ * @post Plugin metadata remains stable and migration execution preserves mapped-environment import guarantees.
+ * @pre Plugin loader can resolve infrastructure dependencies and execution requests provide validated migration context.
+ * @side_effect Reads config, opens database sessions, creates temporary artifacts, and triggers Superset export/import workflows.
+ */
+
+// --- SearchPluginModule (backend/src/plugins/search.py)
+/**!
+ * @brief Plugin for text search across datasets. Inherits PluginBase.
+ * @layer Plugin
+ */
+
+// --- SearchPlugin (backend/src/plugins/search.py)
+/**!
+ * @brief Plugin for searching text patterns in Superset datasets.
+ */
+
+// --- StoragePluginPackage (backend/src/plugins/storage/__init__.py)
+/**!
+ */
+
+// --- StoragePlugin (backend/src/plugins/storage/plugin.py)
+/**!
+ * @brief Provides core filesystem operations for managing backups and repositories.
+ * @invariant All file operations must be restricted to the configured storage root.
+ * @layer App
+ * @rationale Replaced Path(__file__).parents[3] with BASE_DIR import from database.py for path resolution consistency.
+ */
+
+// --- TranslatePluginPackage (backend/src/plugins/translate/__init__.py)
+/**!
+ */
+
+// --- TestClickHouseTimestampNormalization (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify Unix timestamp detection and conversion for ClickHouse Date columns.
+ */
+
+// --- TestClickHouseInsertSqlGeneration (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify SQLGenerator produces valid ClickHouse INSERT SQL with normalized dates.
+ */
+
+// --- TestClickHouseJoinVerification (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify the JOIN query SQL is syntactically correct for ClickHouse.
+ */
+
+// --- TestOrchestratorInsertFlow (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify the orchestrator's _generate_and_insert_sql produces correct SQL for ClickHouse.
+ */
+
+// --- TestClickHouseEndToEnd (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief End-to-end test: generate SQL, verify structure, simulate execution.
+ */
+
+// --- TestDictionaryLegacyHub (backend/src/plugins/translate/__tests__/test_dictionary.py)
+/**!
+ * @brief Legacy test module — all tests migrated to domain-specific test files:
+ * @complexity 3
+ */
+
+// --- TestDictionaryCorrection (backend/src/plugins/translate/__tests__/test_dictionary_correction.py)
+/**!
+ * @brief Validate InlineCorrectionService and dictionary correction flows.
+ * @complexity 3
+ */
+
+// --- TestDictionaryCRUD (backend/src/plugins/translate/__tests__/test_dictionary_crud.py)
+/**!
+ * @brief Validate DictionaryCRUD and DictionaryEntryCRUD operations.
+ * @complexity 3
+ * @test_edge same_term_different_lang_pair -> allowed (not duplicate)
+ * @test_invariant unique_normalized -> verifies: [duplicate_entry, same_term_different_lang_pair allowed]
+ */
+
+// --- TestDictionaryFilter (backend/src/plugins/translate/__tests__/test_dictionary_filter.py)
+/**!
+ * @brief Validate DictionaryBatchFilter operations.
+ * @complexity 3
+ */
+
+// --- TestDictionaryImport (backend/src/plugins/translate/__tests__/test_dictionary_import.py)
+/**!
+ * @brief Validate DictionaryImportExport operations.
+ * @complexity 3
+ * @test_edge import_invalid_format -> ValueError for missing required columns
+ */
+
+// --- TestDictionaryPromptBuilder (backend/src/plugins/translate/__tests__/test_dictionary_prompt_builder.py)
+/**!
+ * @brief Validate ContextAwarePromptBuilder operations: Jaccard similarity, context truncation, entry rendering.
+ * @complexity 3
+ */
+
+// --- TestDictionaryUtils (backend/src/plugins/translate/__tests__/test_dictionary_utils.py)
+/**!
+ * @brief Validate utility functions: _normalize_term and _detect_delimiter.
+ * @complexity 3
+ */
+
+// --- LanguageDetectServiceTests (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @brief Unit tests for LanguageDetectService — local language detection via lingua.
+ * @complexity 3
+ */
+
+// --- test_detect_language_basic (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @brief Verify core language detection for common languages.
+ * @complexity 1
+ */
+
+// --- test_detect_language_edge_cases (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_batch_detect (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_build_detector (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_get_detector_cache (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_code_to_lang_mapping (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @complexity 1
+ */
+
+// --- fixtures (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @complexity 1
+ */
+
+// --- TestTextCleaner (backend/src/plugins/translate/__tests__/test_text_cleaner.py)
+/**!
+ * @brief Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.
+ * @complexity 3
+ * @test_edge zero_max_length — max_length=0 forces truncation on any non-empty text
+ */
+
+// --- TestTokenBudget (backend/src/plugins/translate/__tests__/test_token_budget.py)
+/**!
+ * @brief Verify estimate_token_budget contracts — safe batch sizing, auto-reduction, warning generation.
+ * @complexity 3
+ * @test_edge conservative_min — even with huge rows, batch_size_adjusted >= 1
+ * @test_invariant warning is None when batch fits, str when reduced
+ */
+
+// --- BatchInsertService (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @brief Insert successful translation records into target table via Superset SQL Lab.
+ * @complexity 3
+ */
+
+// --- insert_batch_to_target (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @brief Insert successful records from a single batch into the target table.
+ * @complexity 3
+ */
+
+// --- _fetch_batch_records (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _build_target_columns (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _build_context_keys (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _build_insert_rows (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 3
+ */
+
+// --- _resolve_insert_backend (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _generate_insert_sql (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _execute_insert_sql (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @complexity 1
+ */
+
+// --- BatchProcessingService (backend/src/plugins/translate/_batch_proc.py)
+/**!
+ * @brief Batch processing for translation: classify rows (same-language/cache/preview/LLM),
+ * @complexity 4
+ */
+
+// --- process_batch (backend/src/plugins/translate/_batch_proc.py)
+/**!
+ * @brief Process a single batch: create record, classify rows, call LLM, persist.
+ * @complexity 3
+ * @post TranslationBatch and TranslationRecord rows are created.
+ * @pre job and batch_rows are valid.
+ * @side_effect LLM API call; DB writes.
+ */
+
+// --- AdaptiveBatchSizer (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Adaptive batch sizing for LLM translation — splits source rows into variable-sized
+ * @complexity 3
+ */
+
+// --- resolve_provider_model (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Resolve the LLM provider model name for token budget estimation.
+ * @complexity 2
+ * @post Returns model name string or None if resolution fails.
+ * @side_effect DB query to LLM provider table.
+ */
+
+// --- auto_size_batches (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Split source rows into variable-sized batches based on content length.
+ * @complexity 3
+ * @post Returns list of batches, each batch is a list of row dicts.
+ * @pre source_rows is non-empty. job has valid config.
+ */
+
+// --- LanguageDetectService (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Local language detection powered by lingua-language-detector (no LLM).
+ * @complexity 2
+ */
+
+// --- _detector_cache_key (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Build a deterministic cache key from target languages list.
+ * @complexity 1
+ */
+
+// --- build_detector (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Build a LanguageDetector restricted to target + common source languages.
+ * @complexity 2
+ */
+
+// --- get_detector (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Get or create a cached detector for the given target languages.
+ * @complexity 2
+ */
+
+// --- detect_language (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Detect the language of a single text string. Returns BCP-47 code or "und".
+ * @complexity 2
+ * @error Does not raise — all exceptions caught internally and return "und".
+ */
+
+// --- _character_block_fallback (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief When lingua returns "und", check if character-block dominance (e.g. Cyrillic)
+ * @complexity 2
+ */
+
+// --- batch_detect (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Detect language for multiple texts in batch. Builds detector if not provided.
+ * @complexity 3
+ */
+
+// --- LLMTranslationService (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief LLM interaction for batch translation: call provider with retry, handle truncation
+ * @complexity 4
+ */
+
+// --- call_llm_for_batch (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief Call LLM for a batch of rows requiring translation. Parse and persist results.
+ * @complexity 3
+ * @post Returns dict with successful/failed/skipped counts.
+ * @pre job has valid provider_id. batch_rows is non-empty.
+ * @side_effect HTTP call to LLM provider; DB writes.
+ */
+
+// --- call_llm (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief Route to provider-specific LLM call implementation.
+ * @complexity 3
+ */
+
+// --- LLMHttpClient (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @brief HTTP client for OpenAI-compatible LLM API calls with rate-limit handling and
+ * @complexity 3
+ * @rationale Extracted 'openai' default provider type and 8192 default max_tokens into module-level constants DEFAULT_PROVIDER_TYPE and DEFAULT_MAX_TOKENS.
+ */
+
+// --- call_openai_compatible (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @brief Call OpenAI-compatible API with rate-limit handling and structured output fallback.
+ * @complexity 3
+ * @post Returns (response text, finish_reason).
+ * @pre Valid API endpoint, key, model, and prompt.
+ * @side_effect HTTP POST to LLM API.
+ */
+
+// --- _do_http_request (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _handle_response_format_fallback (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @complexity 1
+ */
+
+// --- LLMResponseParser (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ * @brief Parse LLM JSON response into per-row translations with support for markdown code
+ * @complexity 3
+ */
+
+// --- _recover_from_markdown (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _recover_truncated_rows (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ * @complexity 1
+ */
+
+// --- RunExecutionService (backend/src/plugins/translate/_run_service.py)
+/**!
+ * @brief Full run lifecycle: prepare run, fetch source rows, filter new keys, orchestrate batches,
+ * @complexity 4
+ */
+
+// --- RunSourceFetcher (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @brief Fetch source rows for translation runs from Superset datasource or preview session.
+ * @complexity 3
+ */
+
+// --- fetch_source_rows (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @brief Fetch source rows from Superset datasource or preview session fallback.
+ * @complexity 3
+ */
+
+// --- _extract_chart_data_rows (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @complexity 1
+ */
+
+// --- TextCleaner (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Text cleaning utilities for the translation pipeline — whitespace normalization
+ * @complexity 3
+ */
+
+// --- normalize_whitespace (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Collapse multiple spaces, tabs, and newlines into single spaces; trim leading/trailing
+ * @complexity 2
+ */
+
+// --- truncate_text (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Truncate text to max_length characters, appending "..." if truncation occurs.
+ * @complexity 2
+ * @post When len(text) <= max_length, returns text unchanged.
+ * @pre text is a string. max_length >= 0.
+ */
+
+// --- clean_text (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Combine whitespace normalization and truncation into one step.
+ * @complexity 2
+ */
+
+// --- estimate_token_budget (backend/src/plugins/translate/_token_budget.py)
+/**!
+ * @brief Calculate safe batch_size and max_tokens for LLM translation calls based on actual content length and model context window limits.
+ * @complexity 3
+ * @layer Domain
+ * @rationale Added comment clarifying PROVIDER_DEFAULTS is a fallback — primary source should be LLMProvider API.
+ */
+
+// --- DEFAULT_CONTEXT_WINDOW (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DEFAULT_MAX_OUTPUT_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- REASONING_OVERHEAD (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- PROVIDER_DEFAULTS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- OUTPUT_PER_ROW_PER_LANG (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- JSON_OVERHEAD_PER_ROW (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- PROMPT_BASE_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DICT_TOKENS_PER_ENTRY (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DICT_TOKENS_MAX (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- CHARS_PER_TOKEN_MIXED (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- MIN_MAX_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- MAX_OUTPUT_HEADROOM (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- TranslationUtils (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Shared utility functions for the translation plugin — dictionary enforcement,
+ * @complexity 3
+ */
+
+// --- _normalize_term (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Normalize a term for case-insensitive unique constraint lookup.
+ * @rationale NFC normalization is applied before lowercasing to ensure consistent
+ */
+
+// --- _detect_delimiter (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Detect the delimiter used in a CSV/TSV header line.
+ */
+
+// --- _enforce_dictionary (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Post-process LLM output: enforce dictionary term replacements.
+ * @complexity 2
+ * @post per_lang_values may be mutated to include forced dictionary replacements.
+ * @pre dict_matches is a list of dict entries with source_term/target_term.
+ * @side_effect Logs when enforcement is applied.
+ */
+
+// --- _compute_source_hash (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Compute deterministic cache key for a source row.
+ * @complexity 2
+ */
+
+// --- _check_translation_cache (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Look up a previously successful translation by source_hash.
+ * @complexity 2
+ */
+
+// --- _compute_key_hash (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Compute a stable hash from source_data dict for matching preview edits.
+ * @complexity 1
+ */
+
+// --- estimate_row_tokens (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Estimate token count for a single source row including context fields.
+ * @complexity 2
+ * @post Returns estimated token count >= 1.
+ * @pre source_text is a string.
+ */
+
+// --- DictionaryManagerModule (backend/src/plugins/translate/dictionary.py)
+/**!
+ * @brief Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering.
+ * @complexity 4
+ * @layer Domain
+ * @post Dictionary and entry mutations are persisted with conflict detection.
+ * @pre Database session is open and valid.
+ * @rationale C4 complexity because dictionary CRUD is stateful with referential integrity enforcement on deletion.
+ * @rejected Monolithic DictionaryManager class — violated INV_7. Decomposed into DictionaryCRUD, DictionaryEntryCRUD, DictionaryImportExport, DictionaryBatchFilter, DictionaryCorrectionService.
+ * @side_effect Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards.
+ */
+
+// --- DictionaryManager (backend/src/plugins/translate/dictionary.py)
+/**!
+ * @brief Facade for terminology dictionaries: delegates to DictionaryCRUD, DictionaryEntryCRUD, DictionaryImportExport, DictionaryBatchFilter, DictionaryCorrectionService.
+ * @complexity 4
+ * @post Dictionary and entry mutations are persisted with conflict detection.
+ * @pre Database session is open and valid.
+ * @rationale Thin facade preserves API compatibility after decomposition.
+ * @rejected Removing the facade would break all upstream imports; delegation pattern preferred.
+ * @side_effect Creates, updates, deletes TerminologyDictionary and DictionaryEntry rows; enforces deletion guards.
+ */
+
+// --- DictionaryCorrectionService (backend/src/plugins/translate/dictionary_correction.py)
+/**!
+ * @brief Submit term corrections and bulk corrections to dictionaries with conflict detection.
+ * @complexity 3
+ */
+
+// --- DictionaryCRUD (backend/src/plugins/translate/dictionary_crud.py)
+/**!
+ * @brief CRUD operations for TerminologyDictionary records.
+ * @complexity 3
+ */
+
+// --- DictionaryEntryCRUD (backend/src/plugins/translate/dictionary_entries.py)
+/**!
+ * @brief CRUD operations for DictionaryEntry records.
+ * @complexity 3
+ */
+
+// --- DictionaryBatchFilter (backend/src/plugins/translate/dictionary_filter.py)
+/**!
+ * @brief Scan batch texts for case-insensitive, word-boundary-aware matches against dictionaries.
+ * @complexity 3
+ */
+
+// --- DictionaryImportExport (backend/src/plugins/translate/dictionary_import_export.py)
+/**!
+ * @brief Import/export entries as CSV/TSV with conflict detection, and migration of old entries.
+ * @complexity 3
+ */
+
+// --- _validate_bcp47 (backend/src/plugins/translate/dictionary_validation.py)
+/**!
+ * @brief Validate that a language tag is a non-empty BCP-47 string.
+ * @complexity 2
+ */
+
+// --- TranslationEventLog (backend/src/plugins/translate/events.py)
+/**!
+ * @brief Structured event logging for translation operations with terminal event invariant enforcement.
+ * @complexity 5
+ * @data_contract Input[run_id:Optional[str], job_id:str, event_type:str, payload:dict] -> Output[TranslationEvent]
+ * @invariant Exactly one run_started + exactly one terminal event per non-null run_id.
+ * @layer Domain
+ * @post Events are persisted immutably; terminal events enforce exactly-one invariant per run.
+ * @pre Database session is open and valid.
+ * @rationale Immutable event log with nullable run_id allows job-level events (no run context) and run-level events.
+ * @rejected Separate event table per entity — single TranslationEvent table with nullable run_id is simpler for audit.
+ * @side_effect Writes TranslationEvent rows; prunes expired events with MetricSnapshot before deletion.
+ */
+
+// --- TranslationExecutor (backend/src/plugins/translate/executor.py)
+/**!
+ * @brief Process translation in batches: fetch source rows, call LLM, persist TranslationBatch
+ * @complexity 4
+ */
+
+// --- TranslationMetrics (backend/src/plugins/translate/metrics.py)
+/**!
+ * @brief Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting.
+ * @complexity 4
+ * @layer Domain
+ * @post Metrics are aggregated and returned; no side effects.
+ * @pre Database session is open.
+ * @rationale Live events (<90 days) + MetricSnapshot (>=90 days) fusion for complete picture.
+ * @rejected Querying all events for all time — would be slow; MetricSnapshot provides historical summary.
+ */
+
+// --- TranslationOrchestrator (backend/src/plugins/translate/orchestrator.py)
+/**!
+ * @brief Run lifecycle coordination: validate preconditions, dispatch executor, generate SQL, submit to Superset, record events.
+ * @complexity 5
+ * @data_contract Input[db, config_manager, current_user] -> Output[TranslationRun]
+ * @invariant State transitions: PENDING -> RUNNING -> COMPLETED|FAILED|CANCELLED. Exactly one terminal event per run.
+ * @layer Domain
+ * @post Translation run is executed, SQL generated and submitted, events recorded.
+ * @pre Valid job and accepted preview (for manual runs). Superset and LLM are reachable.
+ * @rationale C5 orchestrator because preview, execution, event logging, and retry share state within single transaction boundary.
+ * @rejected stdout-only logging — lacks structured payload integrity; cannot enforce terminal-event invariant.
+ * @side_effect Creates TranslationRun; creates batches and records; generates SQL; submits to Superset; records events.
+ */
+
+// --- TranslationResultAggregator (backend/src/plugins/translate/orchestrator_aggregator.py)
+/**!
+ * @brief Query translation run status, records, and history.
+ * @complexity 4
+ * @post Returns structured run data with pagination.
+ * @pre Database session is available.
+ * @rationale Language stats aggregation extracted to orchestrator_lang_stats; query methods to orchestrator_query.
+ */
+
+// --- orchestrator_cancel (backend/src/plugins/translate/orchestrator_cancel.py)
+/**!
+ * @brief Cancel and retry-insert operations for translation runs.
+ * @complexity 3
+ * @rationale Extracted from orchestrator_retry.py for INV_7 compliance (module < 150 lines).
+ */
+
+// --- orchestrator_config (backend/src/plugins/translate/orchestrator_config.py)
+/**!
+ * @brief Config hash and dictionary snapshot hash utilities for translation planning.
+ * @complexity 3
+ */
+
+// --- TranslationExecutionEngine (backend/src/plugins/translate/orchestrator_exec.py)
+/**!
+ * @brief Execute translation runs: dispatch executor, manage completion and failure paths.
+ * @complexity 4
+ * @post Run is executed with SQL generated; events recorded.
+ * @pre Database session and config manager are available. Run is in valid state.
+ * @side_effect LLM calls, DB writes, Superset API calls.
+ */
+
+// --- update_language_stats (backend/src/plugins/translate/orchestrator_lang_stats.py)
+/**!
+ * @brief Aggregate TranslationLanguage entries by language_code and update TranslationRunLanguageStats.
+ * @complexity 3
+ * @side_effect DB writes on language_stats objects.
+ */
+
+// --- TranslationPlanner (backend/src/plugins/translate/orchestrator_planner.py)
+/**!
+ * @brief Handle translation run planning: validation, config hashing, dictionary snapshot.
+ * @complexity 4
+ * @post TranslationRun is planned with hashes and config snapshot; events recorded.
+ * @pre Database session and config manager are available.
+ * @rationale Split from monolithic class: validation -> orchestrator_validation, hashing -> orchestrator_config.
+ * @side_effect Creates TranslationRun; computes config and dict hashes; logs events.
+ */
+
+// --- orchestrator_query (backend/src/plugins/translate/orchestrator_query.py)
+/**!
+ * @brief Query translation run records and history with pagination.
+ * @complexity 3
+ */
+
+// --- TranslationRunRetryManager (backend/src/plugins/translate/orchestrator_retry.py)
+/**!
+ * @brief Manage retry of translation run batches.
+ * @complexity 4
+ * @post Retried batches are re-executed.
+ * @pre Database session and config manager are available.
+ * @rationale Cancel and retry-insert extracted to orchestrator_cancel module for INV_7 compliance.
+ * @side_effect DB writes, event log entries.
+ */
+
+// --- orchestrator_run_completion (backend/src/plugins/translate/orchestrator_run_completion.py)
+/**!
+ * @brief Post-execution run completion handlers: cancelled, success-with-insert, and failure paths.
+ * @complexity 3
+ */
+
+// --- TranslationStageRunner (backend/src/plugins/translate/orchestrator_runner.py)
+/**!
+ * @brief Coordinate translation run execution, retry, and cancellation via delegated components.
+ * @complexity 4
+ * @post Run is executed; events recorded.
+ * @pre Database session and config manager are available. Run is in valid state.
+ * @side_effect LLM calls, DB writes, Superset API calls.
+ */
+
+// --- SQLInsertService (backend/src/plugins/translate/orchestrator_sql.py)
+/**!
+ * @brief Generate INSERT SQL from translation records and submit to Superset SQL Lab.
+ * @complexity 4
+ * @post SQL is generated and submitted to Superset; returns execution result.
+ * @pre Job has target table configured. Run has successful records.
+ * @rationale Row/column building extracted to orchestrator_sql_rows module for INV_7 compliance.
+ * @side_effect Superset API call; event log entries.
+ */
+
+// --- orchestrator_sql_rows (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Column and row building utilities for SQL insertion in translate plugin.
+ * @complexity 3
+ */
+
+// --- build_columns (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build list of target columns for SQL INSERT from job configuration.
+ * @complexity 2
+ */
+
+// --- build_context_keys (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build list of context keys for SQL row data.
+ * @complexity 1
+ */
+
+// --- build_rows (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build row data for SQL INSERT with per-language expansion.
+ * @complexity 2
+ * @side_effect Reads translation record language entries.
+ */
+
+// --- validate_job_preconditions (backend/src/plugins/translate/orchestrator_validation.py)
+/**!
+ * @brief Validate preconditions before starting a translation run.
+ * @complexity 3
+ * @post Raises ValueError if any precondition fails.
+ * @pre Job exists and db session is valid.
+ */
+
+// --- TranslatePlugin (backend/src/plugins/translate/plugin.py)
+/**!
+ * @brief TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.
+ * @complexity 2
+ * @layer Domain
+ * @rationale Separate plugin avoids bloating LLMAnalysisPlugin beyond fractal limit (<400 lines).
+ * @rejected Extending LLMAnalysisPlugin would conflate two distinct feature domains.
+ */
+
+// --- DEFAULT_EXECUTION_PROMPT_TEMPLATE (backend/src/plugins/translate/preview_constants.py)
+/**!
+ * @brief Default LLM prompt template for full execution (batch translation).
+ * @complexity 1
+ */
+
+// --- DEFAULT_PREVIEW_PROMPT_TEMPLATE (backend/src/plugins/translate/preview_constants.py)
+/**!
+ * @brief Default LLM prompt template for preview (sample translation).
+ * @complexity 1
+ */
+
+// --- PreviewExecutor (backend/src/plugins/translate/preview_executor.py)
+/**!
+ * @brief Fetch sample data from Superset and call LLM provider for preview.
+ * @complexity 4
+ * @post Sample rows fetched, LLM called.
+ * @pre Database session, config manager, and Superset client are available.
+ * @rationale LLM response parsing and hash utilities extracted to preview_response_parser module for INV_7 compliance.
+ * @side_effect Fetches data from Superset; makes HTTP calls to LLM provider.
+ */
+
+// --- PreviewPromptBuilder (backend/src/plugins/translate/preview_prompt_builder.py)
+/**!
+ * @brief Build LLM prompts for preview sessions including dictionary glossary and row context.
+ * @complexity 3
+ * @rationale Token estimation and budget helpers extracted to preview_prompt_helpers module for INV_7 compliance.
+ */
+
+// --- preview_prompt_helpers (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Token estimation metadata and budget helpers for preview prompt building.
+ * @complexity 2
+ */
+
+// --- estimate_token_budget_for_rows (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Check token budget and optionally truncate source rows for preview.
+ * @complexity 2
+ * @post Returns adjusted source_rows, actual_row_count, and token_budget dict.
+ */
+
+// --- compute_build_token_metadata (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Compute token estimation metadata for prompt builder return dict.
+ * @complexity 1
+ * @post Returns prompt, row_meta, target_languages, cost estimates, and cost_warning.
+ */
+
+// --- preview_response_parser (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Parse LLM JSON responses and Superset data; compute config/dict hashes for preview.
+ * @complexity 3
+ */
+
+// --- parse_llm_response (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Parse LLM JSON response into structured translations dict with per-language support.
+ * @complexity 3
+ * @post Returns dict mapping row_id -> {detected_source_language, lang_code: translation, ...}.
+ * @pre response_text is a valid JSON string (possibly wrapped in markdown code block).
+ */
+
+// --- extract_data_rows (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Extract data rows from Superset chart data API response.
+ * @complexity 1
+ */
+
+// --- compute_config_hash (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Compute a deterministic hash of job configuration for snapshot comparison.
+ * @complexity 1
+ */
+
+// --- compute_dict_snapshot_hash (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Compute a hash of dictionary state for snapshot comparison.
+ * @complexity 2
+ */
+
+// --- PreviewSessionManager (backend/src/plugins/translate/preview_review.py)
+/**!
+ * @brief Manage preview session row-level actions: approve/edit/reject rows.
+ * @complexity 3
+ * @rationale Session accept/get and serialization extracted to preview_session_ops module for INV_7 compliance.
+ */
+
+// --- preview_session_ops (backend/src/plugins/translate/preview_session_ops.py)
+/**!
+ * @brief Preview session lifecycle operations: accept and query preview sessions.
+ * @complexity 3
+ */
+
+// --- get_preview_session (backend/src/plugins/translate/preview_session_ops.py)
+/**!
+ * @brief Get the latest preview session for a job with its records.
+ * @complexity 2
+ */
+
+// --- preview_session_serializer (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Serialization and action helpers for preview sessions: record serialization and per-row approve/reject/edit actions.
+ * @complexity 3
+ * @rationale Extracted from preview_session_ops.py for INV_7 compliance (module < 150 lines).
+ */
+
+// --- serialize_preview_record (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Serialize a TranslationPreviewRecord to a response dict.
+ * @complexity 1
+ */
+
+// --- apply_language_action (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Apply approve/reject/edit action to a TranslationPreviewLanguage entry.
+ * @complexity 2
+ */
+
+// --- apply_record_action (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Apply approve/reject/edit action to a TranslationPreviewRecord and its language entries.
+ * @complexity 2
+ */
+
+// --- TokenEstimator (backend/src/plugins/translate/preview_token_estimator.py)
+/**!
+ * @brief Estimate token counts and costs for LLM translation operations.
+ * @complexity 2
+ * @rationale Token estimation uses a heuristic (chars/token ratio) since exact tokenization depends on the LLM model.
+ * @rejected Using an external tokenizer library would introduce a heavy dependency for estimation only.
+ */
+
+// --- ContextAwarePromptBuilder (backend/src/plugins/translate/prompt_builder.py)
+/**!
+ * @brief Pure-function prompt builder that enhances dictionary entries with context annotations.
+ * @complexity 2
+ * @layer Domain
+ * @rationale Pure functions only — no I/O, no DB access. Separated from executor for testability.
+ * @rejected Embedding context inline in the executor would make it untestable without mocking DB.
+ */
+
+// --- TranslationScheduler (backend/src/plugins/translate/scheduler.py)
+/**!
+ * @brief Manage TranslationSchedule rows and register them with core SchedulerService.
+ * @complexity 4
+ * @layer Domain
+ * @post TranslationSchedule CRUD persisted; APScheduler jobs registered/updated/removed.
+ * @pre Database session and SchedulerService are available.
+ * @rationale Uses existing SchedulerService (APScheduler) to avoid creating a second scheduler instance.
+ * @rejected Polling-based approach — event-driven APScheduler is more precise.
+ * @side_effect Registers APScheduler jobs; runs translations on trigger; creates events.
+ */
+
+// --- execute_scheduled_translation (backend/src/plugins/translate/scheduler.py)
+/**!
+ * @brief APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.
+ * @complexity 4
+ * @post Translation run created and executed if no concurrent run exists.
+ * @pre schedule_id is valid.
+ * @rationale New-key-only mode compares keys against most recent succeeded run; baseline_expired fallback does full.
+ * @side_effect DB writes; LLM calls; Superset API calls.
+ */
+
+// --- TranslateJobService (backend/src/plugins/translate/service.py)
+/**!
+ * @brief Service layer for translation job CRUD with datasource column validation and database dialect detection.
+ * @complexity 4
+ * @layer Domain
+ * @post Translation jobs are created/updated/deleted with column validation and dialect caching.
+ * @pre Database session and config manager are available.
+ * @rationale Snapshot isolation — in-progress runs use config snapshot; config edits affect future runs only.
+ * @rejected Monolithic service.py — violated INV_7. Decomposed into service_datasource, service_inline_correction, service_bulk_replace, service_utils.
+ * @side_effect Queries Superset for column metadata and database dialect at save time.
+ */
+
+// --- BulkFindReplaceService (backend/src/plugins/translate/service_bulk_replace.py)
+/**!
+ * @brief Service for bulk find-and-replace operations on translated values.
+ * @complexity 3
+ */
+
+// --- DatasourceMetadataService (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Fetch datasource column metadata and database dialect from Superset.
+ * @complexity 4
+ * @layer Domain
+ * @post Datasource metadata is fetched with column details and normalized dialect.
+ * @pre Database session and config manager are available.
+ */
+
+// --- get_dialect_from_database (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Extract normalized dialect string from a Superset database record.
+ * @complexity 2
+ */
+
+// --- fetch_datasource_metadata (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Fetch datasource columns and database dialect from Superset.
+ * @complexity 3
+ */
+
+// --- detect_virtual_columns (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Identify virtual (calculated) columns from column metadata.
+ * @complexity 2
+ */
+
+// --- InlineCorrectionService (backend/src/plugins/translate/service_inline_correction.py)
+/**!
+ * @brief Service for inline editing translated values and submitting corrections to dictionaries.
+ * @complexity 4
+ * @post Inline edits applied with optional dictionary submission.
+ * @pre Database session is available.
+ * @side_effect Modifies TranslationLanguage entries; optionally creates DictionaryEntry rows.
+ */
+
+// --- TargetSchemaValidation (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Проверка схемы целевой таблицы: запрос колонок через Superset SQL Lab,
+ * @complexity 4
+ */
+
+// --- _build_expected_columns (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Собирает список ожидаемых колонок по конфигурации column mapping.
+ * @complexity 2
+ */
+
+// --- _extract_columns_from_rows (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Извлекает список колонок таблицы из data-строк результата SQL Lab.
+ * @complexity 2
+ */
+
+// --- _parse_sqllab_result (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Извлекает data-строки из ответа Superset SQL Lab.
+ * @complexity 2
+ */
+
+// --- validate_target_table_schema (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Основная функция: проверяет схему целевой таблицы через Superset SQL Lab.
+ * @complexity 4
+ * @post Возвращает TargetSchemaValidationResponse с diff-анализом.
+ * @pre Superset окружение и target_database_id валидны.
+ * @side_effect Выполняет SQL-запрос к information_schema через Superset SQL Lab API.
+ */
+
+// --- ServiceUtils (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Utility functions for the translate service layer.
+ * @complexity 1
+ */
+
+// --- _extract_dialect (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Extract database dialect from Superset backend URI.
+ */
+
+// --- job_to_response (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Convert a TranslationJob ORM model to a TranslateJobResponse schema with dictionary_ids.
+ */
+
+// --- SQLGenerator (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Dialect-aware safe SQL generation for INSERT/UPSERT operations.
+ * @complexity 3
+ * @layer Domain
+ * @post Returns safe SQL strings for the target dialect.
+ * @pre Job has target_schema and target_table configured. Dialect is one of supported SUPPORTED_DIALECTS.
+ * @rationale Dialect-aware SQL uses ON CONFLICT for PostgreSQL; plain INSERT for ClickHouse with documented limitations.
+ * @rejected ORM-based insert bypasses Superset's SQL Lab audit trail.
+ * @side_effect None — pure code generation.
+ */
+
+// --- _normalize_timestamp_value (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Detect Unix timestamp strings (seconds or millis) and convert to 'YYYY-MM-DD' for Date columns.
+ * @complexity 2
+ */
+
+// --- _quote_identifier (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.
+ * @complexity 4
+ * @post Returns safely quoted identifier.
+ * @pre identifier is a non-empty string.
+ */
+
+// --- _encode_sql_value (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Encode a Python value into a SQL-safe literal for INSERT VALUES, with ClickHouse timestamp normalization.
+ * @complexity 2
+ */
+
+// --- _build_values_clause (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Build a VALUES clause for multiple rows with per-column value encoding and dialect-aware quoting.
+ * @complexity 2
+ */
+
+// --- generate_insert_sql (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Generate a dialect-aware plain INSERT SQL statement for the given table, columns, and rows.
+ * @complexity 3
+ */
+
+// --- generate_upsert_sql (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.
+ * @complexity 4
+ * @post Returns UPSERT SQL string or raises ValueError.
+ * @pre dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.
+ */
+
+// --- SupersetSqlLabExecutor (backend/src/plugins/translate/superset_executor.py)
+/**!
+ * @brief Submit SQL to Superset SQL Lab API and poll execution status.
+ * @complexity 4
+ * @layer Infrastructure
+ * @post SQL is submitted to Superset SQL Lab; execution reference is returned.
+ * @pre Valid Superset environment configuration and authenticated client.
+ * @rationale Direct SQL Lab API submission provides audit trail and execution monitoring within Superset.
+ * @rejected Direct database connection bypass — would skip Superset's SQL Lab audit and RBAC.
+ * @side_effect Makes HTTP calls to Superset /api/v1/sqllab/execute/; polls status.
+ */
+
+// --- SchemasPackage (backend/src/schemas/__init__.py)
+/**!
+ * @brief API schema package root.
+ */
+
+// --- TestSettingsAndHealthSchemas (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Regression tests for settings and health schema contracts updated in 026 fix batch.
+ * @complexity 3
+ */
+
+// --- test_validation_policy_create_accepts_structured_custom_channels (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Ensure policy schema accepts structured custom channel objects with type/target fields.
+ */
+
+// --- test_validation_policy_create_rejects_legacy_string_custom_channels (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Ensure legacy list[str] custom channel payload is rejected by typed channel contract.
+ */
+
+// --- test_dashboard_health_item_status_accepts_only_whitelisted_values (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Verify strict grouped regex only accepts PASS/WARN/FAIL/UNKNOWN exact statuses.
+ */
+
+// --- AuthSchemas (backend/src/schemas/auth.py)
+/**!
+ * @brief Pydantic schemas for authentication requests and responses.
+ * @complexity 5
+ * @data_contract AuthPayload -> AuthSchema
+ * @invariant Sensitive fields like password must not be included in response schemas.
+ * @layer API
+ */
+
+// --- Token (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a JWT access token response.
+ * @complexity 1
+ */
+
+// --- TokenData (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents the data encoded in a JWT token.
+ * @complexity 1
+ */
+
+// --- PermissionSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a permission in API responses.
+ * @complexity 1
+ */
+
+// --- RoleSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a role in API responses.
+ */
+
+// --- RoleCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating a new role.
+ */
+
+// --- RoleUpdate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for updating an existing role.
+ */
+
+// --- ADGroupMappingSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents an AD Group to Role mapping in API responses.
+ */
+
+// --- ADGroupMappingCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating an AD Group mapping.
+ */
+
+// --- UserBase (backend/src/schemas/auth.py)
+/**!
+ * @brief Base schema for user data.
+ */
+
+// --- UserCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating a new user.
+ */
+
+// --- UserUpdate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for updating an existing user.
+ */
+
+// --- User (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for user data in API responses.
+ */
+
+// --- DatasetReviewSchemas (backend/src/schemas/dataset_review.py)
+/**!
+ * @brief Thin facade re-exporting all dataset review API schemas from decomposed sub-modules.
+ * @complexity 2
+ * @layer API
+ * @rationale Original 419-line file exceeded INV_7 (400-line module limit). Decomposed into DTO and composite sub-modules.
+ * @rejected Keeping all schemas in a single file because it exceeded the fractal limit.
+ */
+
+// --- DatasetReviewSchemaComposites (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Composite Pydantic DTOs for clarification, preview, run context, and session summary/detail responses.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- ClarificationOptionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification option DTO.
+ * @complexity 1
+ */
+
+// --- ClarificationAnswerDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification answer DTO with feedback.
+ * @complexity 1
+ */
+
+// --- ClarificationQuestionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification question DTO with nested options and answer.
+ * @complexity 2
+ */
+
+// --- ClarificationSessionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification session DTO with nested questions.
+ * @complexity 2
+ */
+
+// --- CompiledPreviewDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Compiled preview DTO with fingerprint and session version.
+ * @complexity 1
+ */
+
+// --- DatasetRunContextDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Run context DTO with launch audit data and session version.
+ * @complexity 1
+ */
+
+// --- SessionSummary (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Lightweight session summary DTO for list responses.
+ * @complexity 2
+ */
+
+// --- SessionDetail (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Full session detail DTO with all nested aggregates for detail views.
+ * @complexity 2
+ */
+
+// --- DatasetReviewSchemaDtos (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Pydantic DTOs for session, profile, findings, collaborators, and semantic field API payloads.
+ * @complexity 2
+ * @layer API
+ */
+
+// --- SessionCollaboratorDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Collaborator DTO for session access control.
+ * @complexity 1
+ */
+
+// --- DatasetProfileDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Dataset profile DTO with business summary and confidence metadata.
+ * @complexity 1
+ */
+
+// --- ValidationFindingDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Validation finding DTO with resolution tracking.
+ * @complexity 1
+ */
+
+// --- SemanticSourceDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic source DTO with trust level and status.
+ * @complexity 1
+ */
+
+// --- SemanticCandidateDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic candidate DTO with match type and confidence score.
+ * @complexity 1
+ */
+
+// --- SemanticFieldEntryDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic field entry DTO with nested candidates and session version.
+ * @complexity 2
+ */
+
+// --- ImportedFilterDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Imported filter DTO with confidence and recovery status.
+ * @complexity 1
+ */
+
+// --- TemplateVariableDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Template variable DTO with mapping status.
+ * @complexity 1
+ */
+
+// --- ExecutionMappingDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Execution mapping DTO with approval state and session version.
+ * @complexity 1
+ */
+
+// --- HealthSchemas (backend/src/schemas/health.py)
+/**!
+ * @brief Pydantic schemas for dashboard health summary.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- DashboardHealthItem (backend/src/schemas/health.py)
+/**!
+ * @brief Represents the latest health status of a single dashboard.
+ */
+
+// --- HealthSummaryResponse (backend/src/schemas/health.py)
+/**!
+ * @brief Aggregated health summary for all dashboards.
+ */
+
+// --- ProfileSchemas (backend/src/schemas/profile.py)
+/**!
+ * @brief Defines API schemas for profile preference persistence, security read-only snapshot, and Superset account lookup.
+ * @complexity 5
+ * @data_contract ProfilePayload -> ProfileSchema
+ * @invariant Schema shapes stay stable for profile UI states and backend preference contracts.
+ * @layer API
+ */
+
+// --- ProfilePermissionState (backend/src/schemas/profile.py)
+/**!
+ * @brief Represents one permission badge state for profile read-only security view.
+ * @complexity 3
+ */
+
+// --- ProfileSecuritySummary (backend/src/schemas/profile.py)
+/**!
+ * @brief Read-only security and access snapshot for current user.
+ * @complexity 3
+ */
+
+// --- ProfilePreference (backend/src/schemas/profile.py)
+/**!
+ * @brief Represents persisted profile preference for a single authenticated user.
+ * @complexity 3
+ */
+
+// --- ProfilePreferenceUpdateRequest (backend/src/schemas/profile.py)
+/**!
+ * @brief Request payload for updating current user's profile settings.
+ * @complexity 3
+ */
+
+// --- ProfilePreferenceResponse (backend/src/schemas/profile.py)
+/**!
+ * @brief Response envelope for profile preference read/update endpoints.
+ * @complexity 3
+ */
+
+// --- SupersetAccountLookupRequest (backend/src/schemas/profile.py)
+/**!
+ * @brief Query contract for Superset account lookup by selected environment.
+ * @complexity 3
+ */
+
+// --- SupersetAccountCandidate (backend/src/schemas/profile.py)
+/**!
+ * @brief Canonical account candidate projected from Superset users payload.
+ * @complexity 3
+ */
+
+// --- SupersetAccountLookupResponse (backend/src/schemas/profile.py)
+/**!
+ * @brief Response envelope for Superset account lookup (success or degraded mode).
+ * @complexity 3
+ */
+
+// --- SettingsSchemas (backend/src/schemas/settings.py)
+/**!
+ * @brief Pydantic schemas for application settings and automation policies.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- NotificationChannel (backend/src/schemas/settings.py)
+/**!
+ * @brief Structured notification channel definition for policy-level custom routing.
+ */
+
+// --- ValidationPolicyBase (backend/src/schemas/settings.py)
+/**!
+ * @brief Base schema for validation policy data.
+ */
+
+// --- ValidationPolicyCreate (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for creating a new validation policy.
+ */
+
+// --- ValidationPolicyUpdate (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for updating an existing validation policy.
+ */
+
+// --- ValidationPolicyResponse (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for validation policy response data.
+ */
+
+// --- TranslationScheduleItem (backend/src/schemas/settings.py)
+/**!
+ * @brief Response schema for a translation schedule item with joined job name.
+ * @complexity 1
+ */
+
+// --- TranslateSchemas (backend/src/schemas/translate.py)
+/**!
+ * @brief Pydantic v2 schemas for translation API request/response serialization.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- TranslateJobCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for creating a new translation job.
+ */
+
+// --- TranslateJobUpdate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for updating an existing translation job.
+ */
+
+// --- TranslateJobResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation job API responses.
+ */
+
+// --- DatasourceColumnResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for datasource column metadata response.
+ */
+
+// --- DatasourceColumnsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for datasource columns endpoint response.
+ */
+
+// --- DuplicateJobResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for duplicate job response.
+ */
+
+// --- DictionaryCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for creating a new terminology dictionary.
+ */
+
+// --- DictionaryImport (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for importing entries into a terminology dictionary.
+ */
+
+// --- DictionaryResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for terminology dictionary API responses.
+ */
+
+// --- DictionaryEntryCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for adding/editing a dictionary entry with language pair support.
+ */
+
+// --- DictionaryEntryResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for dictionary entry API responses.
+ */
+
+// --- DictionaryImportResult (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for dictionary import result.
+ */
+
+// --- PreviewRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for triggering a translation preview.
+ */
+
+// --- PreviewRowUpdate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for approving/editing/rejecting a preview row.
+ */
+
+// --- PreviewAcceptResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for preview accept response.
+ */
+
+// --- CostEstimate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for cost estimation in preview response.
+ */
+
+// --- TermCorrectionSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting a term correction in a translation preview.
+ */
+
+// --- TermCorrectionBulkSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting multiple term corrections atomically.
+ */
+
+// --- CorrectionConflictResult (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for reporting conflicts in correction submission.
+ */
+
+// --- CorrectionSubmitResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for correction submission response.
+ */
+
+// --- ScheduleResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for schedule API responses.
+ */
+
+// --- NextExecutionResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for next execution preview.
+ */
+
+// --- TranslationRunResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation run API responses.
+ */
+
+// --- RunDetailResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for detailed run response including records, events, and config snapshot.
+ */
+
+// --- RunHistoryFilter (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for filtering run history.
+ */
+
+// --- RunListResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for paginated run list response.
+ */
+
+// --- AggregatedMetricsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for aggregated per-job metrics.
+ */
+
+// --- TranslationPreviewLanguageResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language preview data in API responses.
+ * @complexity 1
+ */
+
+// --- PreviewRow (backend/src/schemas/translate.py)
+/**!
+ * @brief A single row in a translation preview showing original and translated content side by side.
+ */
+
+// --- TranslationPreviewResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation preview session API responses.
+ */
+
+// --- TranslationBatchResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation batch API responses.
+ */
+
+// --- MetricsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation metrics API responses.
+ */
+
+// --- TranslationLanguageResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language translation data in API responses.
+ * @complexity 1
+ */
+
+// --- TranslationRunLanguageStatsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language statistics in run API responses.
+ * @complexity 1
+ */
+
+// --- OverrideLanguageRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for manually overriding the detected source language of a translation.
+ * @complexity 1
+ */
+
+// --- BulkFindReplaceRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for bulk find-and-replace within translations for a target language.
+ * @complexity 1
+ */
+
+// --- InlineEditRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for inline editing a translated value on a completed run result.
+ * @complexity 1
+ */
+
+// --- BulkReplacePreviewItem (backend/src/schemas/translate.py)
+/**!
+ * @brief A single item in a bulk replace preview list.
+ * @complexity 1
+ */
+
+// --- BulkReplaceResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Response for bulk find-and-replace operation.
+ * @complexity 1
+ */
+
+// --- InlineCorrectionSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting an inline correction for a specific translated record.
+ * @complexity 1
+ */
+
+// --- TargetSchemaValidationRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for requesting target table schema validation.
+ * @complexity 1
+ */
+
+// --- TargetSchemaColumnInfo (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for a single column in the schema validation response.
+ * @complexity 1
+ */
+
+// --- TargetSchemaValidationResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for target table schema validation response.
+ * @complexity 1
+ */
+
+// --- ValidationSchemas (backend/src/schemas/validation.py)
+/**!
+ * @brief Pydantic v2 schemas for validation task management and run history API serialization.
+ * @complexity 3
+ * @layer API
+ */
+
+// --- ValidationTaskCreate (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for creating a new validation task (policy).
+ * @complexity 1
+ */
+
+// --- ValidationTaskUpdate (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for updating an existing validation task (policy).
+ * @complexity 1
+ */
+
+// --- ValidationTaskResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for validation task API responses — includes last run status from join.
+ * @complexity 1
+ */
+
+// --- ValidationTaskListResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for paginated task list response.
+ * @complexity 1
+ */
+
+// --- ValidationRunResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for validation run history listing.
+ * @complexity 1
+ */
+
+// --- ValidationRunListResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for paginated run list response.
+ * @complexity 1
+ */
+
+// --- ValidationRunDetailResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for full run detail including parsed issues and raw response.
+ * @complexity 1
+ */
+
+// --- TriggerRunResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for trigger-run response — returns spawned task ID.
+ * @complexity 1
+ */
+
+// --- ScriptsPackage (backend/src/scripts/__init__.py)
+/**!
+ * @brief Script entrypoint package root.
+ */
+
+// --- CleanReleaseCliScript (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Provide headless CLI commands for candidate registration, artifact import and manifest build.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- build_parser (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Build argparse parser for clean release CLI.
+ */
+
+// --- run_candidate_register (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Register candidate in repository via CLI command.
+ * @post Candidate is persisted in DRAFT status.
+ * @pre Candidate ID must be unique.
+ */
+
+// --- run_artifact_import (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Import single artifact for existing candidate.
+ * @post Artifact is persisted for candidate.
+ * @pre Candidate must exist.
+ */
+
+// --- run_manifest_build (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Build immutable manifest snapshot for candidate.
+ * @post New manifest version is persisted.
+ * @pre Candidate must exist.
+ */
+
+// --- run_compliance_run (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Execute compliance run for candidate with optional manifest fallback.
+ * @post Returns run payload and exit code 0 on success.
+ * @pre Candidate exists and trusted snapshots are configured.
+ */
+
+// --- run_compliance_status (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read run status by run id.
+ * @post Returns run status payload.
+ * @pre Run exists.
+ */
+
+// --- _to_payload (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Serialize domain models for CLI JSON output across SQLAlchemy/Pydantic variants.
+ * @post Returns dictionary payload without mutating value.
+ * @pre value is serializable model or primitive object.
+ */
+
+// --- run_compliance_report (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read immutable report by run id.
+ * @post Returns report payload.
+ * @pre Run and report exist.
+ */
+
+// --- run_compliance_violations (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read run violations by run id.
+ * @post Returns violations payload.
+ * @pre Run exists.
+ */
+
+// --- run_approve (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Approve candidate based on immutable PASSED report.
+ * @post Persists APPROVED decision and returns success payload.
+ * @pre Candidate and report exist; report is PASSED.
+ */
+
+// --- run_reject (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Reject candidate without mutating compliance evidence.
+ * @post Persists REJECTED decision and returns success payload.
+ * @pre Candidate and report exist.
+ */
+
+// --- run_publish (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Publish approved candidate to target channel.
+ * @post Appends ACTIVE publication record and returns payload.
+ * @pre Candidate is approved and report belongs to candidate.
+ */
+
+// --- run_revoke (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Revoke active publication record.
+ * @post Publication record status becomes REVOKED.
+ * @pre Publication id exists and is ACTIVE.
+ */
+
+// --- CleanReleaseTuiScript (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Interactive terminal interface for Enterprise Clean Release compliance validation.
+ * @complexity 3
+ * @data_contract CLIArgs -> TUIExitCode
+ * @invariant TUI refuses startup in non-TTY environments; headless flow is CLI/API only.
+ * @layer UI
+ */
+
+// --- TuiFacadeAdapter (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Thin TUI adapter that routes business mutations through application services.
+ * @post Business actions return service results/errors without direct TUI-owned mutations.
+ * @pre repository contains candidate and trusted policy/registry snapshots for execution.
+ */
+
+// --- CleanReleaseTUI (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Curses-based application for compliance monitoring.
+ * @ux_feedback Red alerts for BLOCKED status, Green for COMPLIANT.
+ * @ux_state BLOCKED -> Violations detected, release forbidden.
+ */
+
+// --- run_checks (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Execute compliance run via facade adapter and update UI state.
+ * @post UI reflects final run/report/violation state from service result.
+ * @pre Candidate and policy snapshots are present in repository.
+ */
+
+// --- bundle_build_mode (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Interactive bundle build screen — select type, enter tag, watch live build output.
+ * @complexity 4
+ * @post Subprocess completes (success/failure). Output displayed. User returns via Esc.
+ * @pre TTY is available. Bundle type selected (1 or 2). Tag is non-empty.
+ * @side_effect Runs docker build subprocess, creates dist/docker/ files
+ * @ux_state BUNDLE_DONE -> Build completed with success/failure result
+ */
+
+// --- CreateAdminScript (backend/src/scripts/create_admin.py)
+/**!
+ * @brief CLI tool for creating the initial admin user.
+ * @complexity 5
+ * @data_contract CLIArgs -> AdminUser
+ * @invariant Admin user must have the "Admin" role.
+ * @layer Infrastructure
+ * @side_effect Writes admin user to database
+ */
+
+// --- create_admin (backend/src/scripts/create_admin.py)
+/**!
+ * @brief Creates an admin user and necessary roles/permissions.
+ * @post Admin user exists in auth.db.
+ * @pre username and password provided via CLI.
+ */
+
+// --- DeleteRunningTasksUtil (backend/src/scripts/delete_running_tasks.py)
+/**!
+ * @brief Script to delete tasks with RUNNING status from the database.
+ * @complexity 3
+ * @layer Infrastructure
+ * @semantics maintenance, database, cleanup
+ */
+
+// --- delete_running_tasks (backend/src/scripts/delete_running_tasks.py)
+/**!
+ * @brief Delete all tasks with RUNNING status from the database.
+ * @complexity 4
+ * @post All tasks with status 'RUNNING' are removed from the database.
+ * @pre Database is accessible and TaskRecord model is defined.
+ * @side_effect Modifies DB: deletes RUNNING tasks. Prints to stdout.
+ */
+
+// --- InitAuthDbScript (backend/src/scripts/init_auth_db.py)
+/**!
+ * @brief Initializes the auth database and creates the necessary tables.
+ * @complexity 2
+ * @invariant Safe to run multiple times (idempotent).
+ * @layer Service
+ */
+
+// --- run_init (backend/src/scripts/init_auth_db.py)
+/**!
+ * @brief Main entry point for the initialization script.
+ * @complexity 3
+ * @post auth.db is initialized with the correct schema and seeded permissions.
+ */
+
+// --- SeedPermissionsScript (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Populates the auth database with initial system permissions.
+ * @complexity 5
+ * @data_contract CLIArgs -> SeedSummary
+ * @invariant Safe to run multiple times (idempotent).
+ * @layer Infrastructure
+ * @side_effect Writes permissions to database
+ */
+
+// --- INITIAL_PERMISSIONS (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Canonical bootstrap permission tuples seeded into auth storage.
+ * @complexity 3
+ */
+
+// --- seed_permissions (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Inserts missing permissions into the database.
+ * @complexity 3
+ * @post All INITIAL_PERMISSIONS exist in the DB.
+ */
+
+// --- SeedSupersetLoadTestScript (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Creates randomized load-test data in Superset by cloning chart configurations and creating dashboards in target environments.
+ * @complexity 5
+ * @data_contract CLIArgs -> TestDataSummary
+ * @invariant Created chart and dashboard names are globally unique for one script run.
+ * @layer Infrastructure
+ */
+
+// --- _parse_args (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Parses CLI arguments for load-test data generation.
+ * @post Returns validated argument namespace.
+ * @pre Script is called from CLI.
+ */
+
+// --- _extract_result_payload (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Normalizes Superset API payloads that may be wrapped in `result`.
+ * @post Returns the unwrapped object when present.
+ * @pre payload is a JSON-decoded API response.
+ */
+
+// --- _extract_created_id (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Extracts object ID from create/update API response.
+ * @post Returns integer object ID or None if missing.
+ * @pre payload is a JSON-decoded API response.
+ */
+
+// --- _generate_unique_name (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Generates globally unique random names for charts/dashboards.
+ * @post Returns a unique string and stores it in used_names.
+ * @pre used_names is mutable set for collision tracking.
+ */
+
+// --- _resolve_target_envs (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Resolves requested environment IDs from configuration.
+ * @post Returns mapping env_id -> configured environment object.
+ * @pre env_ids is non-empty.
+ */
+
+// --- _build_chart_template_pool (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Builds a pool of source chart templates to clone in one environment.
+ * @post Returns non-empty list of chart payload templates.
+ * @pre Client is authenticated.
+ */
+
+// --- seed_superset_load_data (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Creates dashboards and cloned charts for load testing across target environments.
+ * @post Returns execution statistics dictionary.
+ * @pre Target environments must be reachable and authenticated.
+ * @side_effect Creates objects in Superset environments.
+ */
+
+// --- main (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief CLI entrypoint for Superset load-test data seeding.
+ * @post Prints summary and exits with non-zero status on failure.
+ * @pre Command line arguments are valid.
+ */
+
+// --- test_dataset_dashboard_relations_script (backend/src/scripts/test_dataset_dashboard_relations.py)
+/**!
+ * @brief Tests and inspects dataset-to-dashboard relationship responses from Superset API.
+ * @complexity 2
+ * @rationale Added '# DIAGNOSTIC SCRIPT — not a test' header comment. Script already had if __name__ guard.
+ */
+
+// --- services (backend/src/services/__init__.py)
+/**!
+ * @brief Package initialization for services module
+ * @complexity 2
+ * @note GitService, AuthService, LLMProviderService have circular import issues - import directly when needed
+ */
+
+// --- auth_service (backend/src/services/auth_service.py)
+/**!
+ * @brief Orchestrates credential authentication and ADFS JIT user provisioning.
+ * @complexity 5
+ * @data_contract [Credentials | ADFSClaims] -> [UserEntity | SessionToken]
+ * @invariant Authentication succeeds only for active users with valid credentials; issued sessions encode subject and scopes from assigned roles.
+ * @layer Domain
+ * @post User identity verified and session tokens issued according to role scopes.
+ * @pre Core auth models and security utilities available.
+ * @side_effect Writes last login timestamps and JIT-provisions external users.
+ */
+
+// --- AuthService (backend/src/services/auth_service.py)
+/**!
+ * @brief Provides high-level authentication services.
+ * @complexity 3
+ */
+
+// --- CleanReleaseContracts (backend/src/services/clean_release/__init__.py)
+/**!
+ * @brief Publish the canonical semantic root for the clean-release backend service cluster.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- ApprovalService (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Enforce approval/rejection gates over immutable compliance reports.
+ * @complexity 5
+ * @data_contract ApprovalRequest -> ApprovalDecision
+ * @invariant Approval is allowed only for PASSED report bound to candidate; decisions are append-only.
+ * @layer Domain
+ * @post Approval decision appended; candidate lifecycle advanced
+ * @pre Report with PASSED final_status exists for candidate
+ * @side_effect Persists approval decisions, transitions candidate status
+ */
+
+// --- _get_or_init_decisions_store (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Provide append-only in-memory storage for approval decisions.
+ * @post Returns mutable decision list attached to repository.
+ * @pre repository is initialized.
+ */
+
+// --- _latest_decision_for_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Resolve latest approval decision for candidate from append-only store.
+ * @post Returns latest ApprovalDecision or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- _resolve_candidate_and_report (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Validate candidate/report existence and ownership prior to decision persistence.
+ * @post Returns tuple(candidate, report); raises ApprovalGateError on contract violation.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- approve_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Persist immutable APPROVED decision and advance candidate lifecycle to APPROVED.
+ * @post Approval decision is appended and candidate transitions to APPROVED.
+ * @pre Candidate exists, report belongs to candidate, report final_status is PASSED, candidate not already APPROVED.
+ */
+
+// --- reject_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Persist immutable REJECTED decision without promoting candidate lifecycle.
+ * @post Rejected decision is appended; candidate lifecycle is unchanged.
+ * @pre Candidate exists and report belongs to candidate.
+ */
+
+// --- ArtifactCatalogLoader (backend/src/services/clean_release/artifact_catalog_loader.py)
+/**!
+ * @brief Load bootstrap artifact catalogs for clean release real-mode flows.
+ * @complexity 5
+ * @data_contract FilePath -> CandidateArtifact[]
+ * @invariant Artifact catalog must produce deterministic CandidateArtifact entries with required identity and checksum fields.
+ * @layer Domain
+ * @side_effect Reads JSON file from filesystem
+ */
+
+// --- load_bootstrap_artifacts (backend/src/services/clean_release/artifact_catalog_loader.py)
+/**!
+ * @brief Parse artifact catalog JSON into CandidateArtifact models for TUI/bootstrap flows.
+ * @post Returns non-mutated CandidateArtifact models with required fields populated.
+ * @pre path points to readable JSON file; payload is list[artifact] or {"artifacts": list[artifact]}.
+ */
+
+// --- AuditService (backend/src/services/clean_release/audit_service.py)
+/**!
+ * @brief Provide lightweight audit hooks for clean release preparation/check/report lifecycle.
+ * @complexity 3
+ * @data_contract AuditAction -> LogEntry
+ * @invariant Audit hooks are append-only log actions.
+ * @layer Infrastructure
+ * @post Audit events appended to log
+ * @pre Logger configured
+ * @side_effect Writes audit events to logger and repository
+ */
+
+// --- candidate_service (backend/src/services/clean_release/candidate_service.py)
+/**!
+ * @brief Register release candidates with validated artifacts and advance lifecycle through legal transitions.
+ * @complexity 5
+ * @invariant Candidate lifecycle transitions are delegated to domain guard logic.
+ * @layer Domain
+ * @post candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.
+ * @pre candidate_id must be unique; artifacts input must be non-empty and valid.
+ */
+
+// --- _validate_artifacts (backend/src/services/clean_release/candidate_service.py)
+/**!
+ * @brief Validate raw artifact payload list for required fields and shape.
+ * @post Returns normalized artifact list or raises ValueError.
+ * @pre artifacts payload is provided by caller.
+ */
+
+// --- ComplianceExecutionService (backend/src/services/clean_release/compliance_execution_service.py)
+/**!
+ * @brief Create and execute compliance runs with trusted snapshots, deterministic stages, violations and immutable report persistence.
+ * @complexity 5
+ * @data_contract Input[candidate_id, requested_by, manifest_id?, policy snapshots, stage results] -> Output[ComplianceExecutionResult]
+ * @invariant A run binds to exactly one candidate/manifest/policy/registry snapshot set.
+ * @layer Domain
+ * @post Candidate-scoped compliance runs persist stage evidence, terminal status, and immutable report artifacts when execution succeeds.
+ * @pre Repository adapters, trusted policy resolution, and deterministic stage implementations are available for the run request.
+ * @side_effect Persists runs, stage results, violations, and reports through repository adapters and audit helpers.
+ */
+
+// --- ComplianceExecutionResult (backend/src/services/clean_release/compliance_execution_service.py)
+/**!
+ * @brief Return envelope for compliance execution with run/report and persisted stage artifacts.
+ */
+
+// --- ComplianceOrchestrator (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Execute mandatory clean compliance stages and produce final COMPLIANT/BLOCKED/FAILED outcome.
+ * @complexity 5
+ * @data_contract Manifest -> ComplianceReport
+ * @invariant COMPLIANT is impossible when any mandatory stage fails.
+ * @layer Domain
+ * @post OrchestrationResult with compliance status
+ * @pre ManifestService and PolicyEngine are available
+ * @side_effect Triggers compliance checks; may modify manifest state
+ * @test_contract ComplianceCheckRun -> ComplianceCheckRun
+ * @test_edge report_generation_error -> Downstream reporting failure does not alter orchestrator status derivation contract
+ * @test_fixture compliant_candidate -> file:backend/tests/fixtures/clean_release/fixtures_clean_release.json
+ * @test_invariant compliant_requires_all_mandatory_pass -> VERIFIED_BY: [stage_failure_blocks_release]
+ */
+
+// --- CleanComplianceOrchestrator (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Coordinate clean-release compliance verification stages.
+ */
+
+// --- run_check_legacy (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Legacy wrapper for compatibility with previous orchestrator call style.
+ * @data_contract Input -> (repository:CleanReleaseRepository, candidate_id:str, policy_id:str, requested_by:str, manifest_id:str), Output -> ComplianceRun
+ * @post Returns finalized ComplianceRun produced by orchestrator start->execute->finalize sequence.
+ * @pre repository and identifiers are valid and resolvable by orchestrator dependencies.
+ * @side_effect Reads/writes compliance entities through repository during orchestrator calls.
+ */
+
+// --- DemoDataService (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Provide deterministic namespace helpers and isolated in-memory repository creation for demo and real modes.
+ * @complexity 5
+ * @data_contract SeedConfig -> DemoEntities
+ * @invariant Demo and real namespaces must never collide for generated physical identifiers.
+ * @layer Domain
+ * @side_effect Writes demo entities to repository
+ */
+
+// --- resolve_namespace (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Resolve canonical clean-release namespace for requested mode.
+ * @post Returns deterministic namespace key for demo/real separation.
+ * @pre mode is a non-empty string identifying runtime mode.
+ */
+
+// --- build_namespaced_id (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Build storage-safe physical identifier under mode namespace.
+ * @post Returns deterministic "{namespace}::{logical_id}" identifier.
+ * @pre namespace and logical_id are non-empty strings.
+ */
+
+// --- create_isolated_repository (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Create isolated in-memory repository instance for selected mode namespace.
+ * @post Returns repository instance tagged with namespace metadata.
+ * @pre mode is a valid runtime mode marker.
+ */
+
+// --- clean_release_dto (backend/src/services/clean_release/dto.py)
+/**!
+ * @brief Data Transfer Objects for clean release compliance subsystem.
+ * @complexity 3
+ * @layer Application
+ */
+
+// --- clean_release_enums (backend/src/services/clean_release/enums.py)
+/**!
+ * @brief Canonical enums for clean release lifecycle and compliance.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- clean_release_exceptions (backend/src/services/clean_release/exceptions.py)
+/**!
+ * @brief Domain exceptions for clean release compliance subsystem.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- clean_release_facade (backend/src/services/clean_release/facade.py)
+/**!
+ * @brief Unified entry point for clean release operations.
+ * @complexity 3
+ * @layer Application
+ */
+
+// --- ManifestBuilder (backend/src/services/clean_release/manifest_builder.py)
+/**!
+ * @brief Build deterministic distribution manifest from classified artifact input.
+ * @complexity 5
+ * @data_contract ArtifactSet -> Manifest
+ * @invariant Equal semantic artifact sets produce identical deterministic hash values.
+ * @layer Domain
+ * @side_effect Computes hash of artifact set
+ */
+
+// --- build_distribution_manifest (backend/src/services/clean_release/manifest_builder.py)
+/**!
+ * @brief Build DistributionManifest with deterministic hash and validated counters.
+ * @post Returns DistributionManifest with summary counts matching items cardinality.
+ * @pre artifacts list contains normalized classification values.
+ */
+
+// --- ManifestService (backend/src/services/clean_release/manifest_service.py)
+/**!
+ * @brief Build immutable distribution manifests with deterministic digest and version increment.
+ * @complexity 5
+ * @data_contract Manifest -> ManifestRecord; Candidate -> ManifestRecord
+ * @invariant Existing manifests are never mutated.
+ * @layer Domain
+ * @post New immutable manifest is persisted with incremented version and deterministic digest.
+ * @pre Candidate exists and is PREPARED or MANIFEST_BUILT; artifacts are present.
+ * @side_effect May modify manifest state during processing
+ */
+
+// --- build_manifest_snapshot (backend/src/services/clean_release/manifest_service.py)
+/**!
+ * @brief Create a new immutable manifest version for a candidate.
+ * @post Returns persisted DistributionManifest with monotonically incremented version.
+ * @pre Candidate is prepared, artifacts are available, candidate_id is valid.
+ */
+
+// --- clean_release_mappers (backend/src/services/clean_release/mappers.py)
+/**!
+ * @brief Map between domain entities (SQLAlchemy models) and DTOs.
+ * @complexity 3
+ * @layer Application
+ */
+
+// --- PolicyEngine (backend/src/services/clean_release/policy_engine.py)
+/**!
+ * @brief Evaluate artifact/source policies for enterprise clean profile with deterministic outcomes.
+ * @complexity 5
+ * @data_contract Candidate -> PolicyDecision
+ * @invariant Enterprise-clean policy always treats non-registry sources as violations.
+ * @layer Domain
+ * @post PolicyDecision returned with approval status
+ * @pre PolicyRepository is accessible
+ * @side_effect Read-only policy evaluation; no state changes
+ */
+
+// --- CleanPolicyEngine (backend/src/services/clean_release/policy_engine.py)
+/**!
+ * @post Deterministic classification and source validation are available.
+ * @pre Active policy exists and is internally consistent.
+ * @test_contract CandidateEvaluationInput -> PolicyValidationResult|SourceValidationResult
+ * @test_edge external_endpoint -> endpoint not present in enabled internal registry entries
+ * @test_fixture policy_enterprise_clean -> file:backend/tests/fixtures/clean_release/fixtures_clean_release.json
+ * @test_invariant deterministic_classification -> VERIFIED_BY: [policy_valid]
+ * @test_scenario policy_valid -> Enterprise clean policy with matching registry returns ok=True
+ */
+
+// --- PolicyResolutionService (backend/src/services/clean_release/policy_resolution_service.py)
+/**!
+ * @brief Resolve trusted policy and registry snapshots from ConfigManager without runtime overrides.
+ * @complexity 5
+ * @data_contract PolicyRequest -> ResolutionResult
+ * @invariant Trusted snapshot resolution is based only on ConfigManager active identifiers.
+ * @layer Domain
+ * @post ResolutionResult with matched policies
+ * @pre PolicyRepository and Manifest are available
+ * @side_effect Read-only policy evaluation; logs resolution decisions
+ */
+
+// --- resolve_trusted_policy_snapshots (backend/src/services/clean_release/policy_resolution_service.py)
+/**!
+ * @brief Resolve immutable trusted policy and registry snapshots using active config IDs only.
+ * @post Returns immutable policy and registry snapshots; runtime override attempts are rejected.
+ * @pre ConfigManager provides active_policy_id and active_registry_id; repository contains referenced snapshots.
+ * @side_effect None.
+ */
+
+// --- PreparationService (backend/src/services/clean_release/preparation_service.py)
+/**!
+ * @brief Prepare release candidate by policy evaluation and deterministic manifest creation.
+ * @complexity 5
+ * @data_contract PrepareRequest -> PrepareResult
+ * @invariant Candidate preparation always persists manifest and candidate status deterministically.
+ * @layer Domain
+ * @side_effect Persists candidate and manifest
+ */
+
+// --- prepare_candidate_legacy (backend/src/services/clean_release/preparation_service.py)
+/**!
+ * @brief Legacy compatibility wrapper kept for migration period.
+ * @post Delegates to canonical prepare_candidate and preserves response shape.
+ * @pre Same as prepare_candidate.
+ */
+
+// --- PublicationService (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Enforce publication and revocation gates with append-only publication records.
+ * @complexity 5
+ * @invariant Publication records are append-only snapshots; revoke mutates only publication status for targeted record.
+ * @layer Domain
+ */
+
+// --- _get_or_init_publications_store (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Provide in-memory append-only publication storage.
+ * @post Returns publication list attached to repository.
+ * @pre repository is initialized.
+ */
+
+// --- _latest_publication_for_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Resolve latest publication record for candidate.
+ * @post Returns latest record or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- _latest_approval_for_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Resolve latest approval decision from repository decision store.
+ * @post Returns latest decision object or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- publish_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Create immutable publication record for approved candidate.
+ * @post New ACTIVE publication record is appended.
+ * @pre Candidate exists, report belongs to candidate, latest approval is APPROVED.
+ */
+
+// --- revoke_publication (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Revoke existing publication record without deleting history.
+ * @post Target publication status becomes REVOKED and updated record is returned.
+ * @pre publication_id exists in repository publication store.
+ */
+
+// --- ReportBuilder (backend/src/services/clean_release/report_builder.py)
+/**!
+ * @brief Build and persist compliance reports with consistent counter invariants.
+ * @complexity 5
+ * @data_contract Input[ComplianceRun, List[ComplianceViolation]] -> Output[ComplianceReport]
+ * @invariant blocking_violations_count never exceeds violations_count.
+ * @layer Domain
+ * @post Returns immutable report payloads with consistent violation counters and operator summary content.
+ * @pre Compliance run is terminal and repository persistence is available for report storage.
+ * @side_effect Writes report artifacts to repository when persistence helpers are invoked.
+ * @test_contract ComplianceCheckRun,List[ComplianceViolation] -> ComplianceReport
+ * @test_edge missing_operator_summary -> non-terminal run prevents report creation and summary generation
+ * @test_fixture blocked_with_two_violations -> file:backend/tests/fixtures/clean_release/fixtures_clean_release.json
+ * @test_invariant blocking_count_le_total_count -> VERIFIED_BY: [counter_mismatch, empty_violations_for_blocked]
+ */
+
+// --- clean_release_repositories (backend/src/services/clean_release/repositories/__init__.py)
+/**!
+ * @brief Export all clean release repositories.
+ * @complexity 3
+ */
+
+// --- approval_repository (backend/src/services/clean_release/repositories/approval_repository.py)
+/**!
+ * @brief Persist and query approval decisions.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- artifact_repository (backend/src/services/clean_release/repositories/artifact_repository.py)
+/**!
+ * @brief Persist and query candidate artifacts.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- audit_repository (backend/src/services/clean_release/repositories/audit_repository.py)
+/**!
+ * @brief Persist and query audit logs for clean release operations.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- candidate_repository (backend/src/services/clean_release/repositories/candidate_repository.py)
+/**!
+ * @brief Persist and query release candidates.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- compliance_repository (backend/src/services/clean_release/repositories/compliance_repository.py)
+/**!
+ * @brief Persist and query compliance runs, stage runs, and violations.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- ManifestRepositoryModule (backend/src/services/clean_release/repositories/manifest_repository.py)
+/**!
+ * @brief Persist and query distribution manifests.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- ManifestRepository (backend/src/services/clean_release/repositories/manifest_repository.py)
+/**!
+ * @brief Encapsulates database CRUD operations for DistributionManifest entities.
+ * @complexity 3
+ */
+
+// --- policy_repository (backend/src/services/clean_release/repositories/policy_repository.py)
+/**!
+ * @brief Persist and query policy and registry snapshots.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- publication_repository (backend/src/services/clean_release/repositories/publication_repository.py)
+/**!
+ * @brief Persist and query publication records.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- report_repository (backend/src/services/clean_release/repositories/report_repository.py)
+/**!
+ * @brief Persist and query compliance reports.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- RepositoryRelations (backend/src/services/clean_release/repository.py)
+/**!
+ * @brief Provide repository adapter for clean release entities with deterministic access methods.
+ * @complexity 5
+ * @data_contract Entity -> RepositoryOperation
+ * @invariant Repository operations are side-effect free outside explicit save/update calls.
+ * @layer Infrastructure
+ * @post Repository operations exported
+ * @pre In-memory storage initialized
+ * @side_effect Modifies in-memory state on save/update
+ */
+
+// --- CleanReleaseRepository (backend/src/services/clean_release/repository.py)
+/**!
+ * @brief Data access object for clean release lifecycle.
+ */
+
+// --- SourceIsolation (backend/src/services/clean_release/source_isolation.py)
+/**!
+ * @brief Validate that all resource endpoints belong to the approved internal source registry.
+ * @complexity 5
+ * @data_contract SourceURL -> ViolationReport
+ * @invariant Any endpoint outside enabled registry entries is treated as external-source violation.
+ * @layer Domain
+ * @post Source isolation violations identified
+ * @pre Source registry configured
+ * @side_effect None (read-only check)
+ */
+
+// --- ComplianceStages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Define compliance stage order and helper functions for deterministic run-state evaluation.
+ * @complexity 5
+ * @data_contract StagePipeline -> ComplianceResult
+ * @invariant Stage order remains deterministic for all compliance runs.
+ * @layer Domain
+ * @side_effect Registers compliance stages
+ */
+
+// --- build_default_stages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Build default deterministic stage pipeline implementation order.
+ * @post Returns stage instances in mandatory execution order.
+ * @pre None.
+ */
+
+// --- stage_result_map (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Convert stage result list to dictionary by stage name.
+ * @post Returns stage->status dictionary for downstream evaluation.
+ * @pre stage_results may be empty or contain unique stage names.
+ */
+
+// --- missing_mandatory_stages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Identify mandatory stages that are absent from run results.
+ * @post Returns ordered list of missing mandatory stages.
+ * @pre stage_status_map contains zero or more known stage statuses.
+ */
+
+// --- derive_final_status (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Derive final run status from stage results with deterministic blocking behavior.
+ * @post Returns one of PASSED/BLOCKED/ERROR according to mandatory stage outcomes.
+ * @pre Stage statuses correspond to compliance checks.
+ */
+
+// --- ComplianceStageBase (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Define shared contracts and helpers for pluggable clean-release compliance stages.
+ * @complexity 5
+ * @data_contract Context -> StageResult
+ * @invariant Stage execution is deterministic for equal input context.
+ * @layer Domain
+ * @side_effect None (deterministic execution)
+ */
+
+// --- ComplianceStageContext (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Immutable input envelope passed to each compliance stage.
+ */
+
+// --- StageExecutionResult (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Structured stage output containing decision, details and violations.
+ */
+
+// --- ComplianceStage (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Protocol for pluggable stage implementations.
+ */
+
+// --- build_stage_run_record (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Build persisted stage run record from stage result.
+ * @post Returns ComplianceStageRun with deterministic identifiers and timestamps.
+ * @pre run_id and stage_name are non-empty.
+ */
+
+// --- build_violation (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Construct a compliance violation with normalized defaults.
+ * @post Returns immutable-style violation payload ready for persistence.
+ * @pre run_id, stage_name, code and message are non-empty.
+ */
+
+// --- data_purity (backend/src/services/clean_release/stages/data_purity.py)
+/**!
+ * @brief Evaluate manifest purity counters and emit blocking violations for prohibited artifacts.
+ * @complexity 5
+ * @data_contract Manifest -> DataPurityVerdict
+ * @invariant prohibited_detected_count > 0 always yields BLOCKED stage decision.
+ * @layer Domain
+ * @side_effect None (read-only validation)
+ */
+
+// --- DataPurityStage (backend/src/services/clean_release/stages/data_purity.py)
+/**!
+ * @brief Validate manifest summary for prohibited artifacts.
+ * @post Returns PASSED when no prohibited artifacts are detected, otherwise BLOCKED with violations.
+ * @pre context.manifest.content_json contains summary block or defaults to safe counters.
+ */
+
+// --- internal_sources_only (backend/src/services/clean_release/stages/internal_sources_only.py)
+/**!
+ * @brief Verify manifest-declared sources belong to trusted internal registry allowlist.
+ * @complexity 5
+ * @data_contract Sources -> SourceViolationReport
+ * @invariant Any source host outside allowed_hosts yields BLOCKED decision with at least one violation.
+ * @layer Domain
+ * @side_effect None (read-only validation)
+ */
+
+// --- InternalSourcesOnlyStage (backend/src/services/clean_release/stages/internal_sources_only.py)
+/**!
+ * @brief Enforce internal-source-only policy from trusted registry snapshot.
+ * @post Returns PASSED when all hosts are allowed; otherwise BLOCKED and violations captured.
+ * @pre context.registry.allowed_hosts is available.
+ */
+
+// --- manifest_consistency (backend/src/services/clean_release/stages/manifest_consistency.py)
+/**!
+ * @brief Ensure run is bound to the exact manifest snapshot and digest used at run creation time.
+ * @complexity 5
+ * @data_contract RunData -> ConsistencyVerdict
+ * @invariant Digest mismatch between run and manifest yields ERROR with blocking violation evidence.
+ * @layer Domain
+ * @side_effect None (read-only validation)
+ */
+
+// --- ManifestConsistencyStage (backend/src/services/clean_release/stages/manifest_consistency.py)
+/**!
+ * @brief Validate run/manifest linkage consistency.
+ * @post Returns PASSED when digests match, otherwise ERROR with one violation.
+ * @pre context.run and context.manifest are loaded from repository for same run.
+ */
+
+// --- no_external_endpoints (backend/src/services/clean_release/stages/no_external_endpoints.py)
+/**!
+ * @brief Block manifest payloads that expose external endpoints outside trusted schemes and hosts.
+ * @complexity 5
+ * @data_contract Endpoints -> EndpointViolationReport
+ * @invariant Endpoint outside allowed scheme/host always yields BLOCKED stage decision.
+ * @layer Domain
+ * @side_effect None (read-only validation)
+ */
+
+// --- NoExternalEndpointsStage (backend/src/services/clean_release/stages/no_external_endpoints.py)
+/**!
+ * @brief Validate endpoint references from manifest against trusted registry.
+ * @post Returns PASSED when all endpoints are trusted, otherwise BLOCKED with endpoint violations.
+ * @pre context.registry includes allowed hosts and schemes.
+ */
+
+// --- dataset_review (backend/src/services/dataset_review/__init__.py)
+/**!
+ * @brief Provides services for dataset-centered orchestration flow.
+ * @layer Service
+ */
+
+// --- ClarificationEngine (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Manage one-question-at-a-time clarification state, deterministic answer persistence, and readiness/finding updates.
+ * @complexity 4
+ * @data_contract Input[DatasetReviewSession|ClarificationAnswerCommand] -> Output[ClarificationStateResult]
+ * @invariant Only one active clarification question may exist at a time; skipped and expert-review items remain unresolved and visible.
+ * @layer Domain
+ * @post Active clarification payload exposes one highest-priority unresolved question, and each recorded answer is persisted before pointer/readiness mutation.
+ * @pre Target session contains a persisted clarification aggregate in the current ownership scope.
+ * @rationale Original 635-line file exceeded INV_7 (400-line module limit). Extracted pure helpers into _helpers sub-module.
+ * @rejected Keeping all clarification logic in one file because it exceeded the fractal limit.
+ * @side_effect Persists clarification answers, question/session states, and related readiness/finding changes.
+ */
+
+// --- ClarificationQuestionPayload (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Typed active-question payload returned to the API layer.
+ * @complexity 2
+ */
+
+// --- ClarificationStateResult (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Clarification state result carrying the current session, active payload, and changed findings.
+ * @complexity 2
+ */
+
+// --- ClarificationAnswerCommand (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Typed answer command for clarification state mutation.
+ * @complexity 2
+ */
+
+// --- ClarificationHelpers (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Pure helper functions for clarification engine — question selection, counting, normalization, finding upsert, and readiness derivation.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- select_next_open_question (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Select the next unresolved question in deterministic priority order.
+ * @complexity 2
+ */
+
+// --- count_resolved_questions (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Count questions whose answers fully resolved the ambiguity.
+ * @complexity 1
+ */
+
+// --- count_remaining_questions (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Count questions still unresolved or deferred after clarification interaction.
+ * @complexity 1
+ */
+
+// --- normalize_answer_value (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Validate and normalize answer payload based on answer kind and active question options.
+ * @complexity 2
+ */
+
+// --- build_impact_summary (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Build a compact audit note describing how the clarification answer affects session state.
+ * @complexity 1
+ */
+
+// --- upsert_clarification_finding (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Keep one finding per clarification topic aligned with answer outcome and unresolved visibility rules.
+ * @complexity 3
+ */
+
+// --- derive_readiness_state (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Recompute readiness after clarification mutation while preserving unresolved visibility semantics.
+ * @complexity 2
+ */
+
+// --- derive_recommended_action (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Recompute next-action guidance after clarification mutations.
+ * @complexity 2
+ */
+
+// --- SessionEventLoggerModule (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Persist explicit session mutation events for dataset-review audit trails without weakening ownership or approval invariants.
+ * @complexity 4
+ * @data_contract Input[SessionEventPayload] -> Output[SessionEvent]
+ * @layer Domain
+ * @post Every logged event is committed as an explicit, queryable audit record with deterministic event metadata.
+ * @pre Caller provides an owned session scope and an authenticated actor identifier for each persisted mutation event.
+ * @side_effect Inserts persisted session event rows and emits runtime belief-state logs for audit-sensitive mutations.
+ */
+
+// --- SessionEventLoggerImports (backend/src/services/dataset_review/event_logger.py)
+/**!
+ */
+
+// --- SessionEventPayload (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Typed input contract for one persisted dataset-review session audit event.
+ * @complexity 2
+ */
+
+// --- SessionEventLogger (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Persist explicit dataset-review session audit events with meaningful runtime reasoning logs.
+ * @complexity 4
+ * @data_contract Input[SessionEventPayload] -> Output[SessionEvent]
+ * @post Returns the committed session event row with a stable identifier and stored detail payload.
+ * @pre The database session is live and payload identifiers are non-empty.
+ * @side_effect Writes one audit row to persistence and emits logger.reason/logger.reflect traces.
+ */
+
+// --- DatasetReviewOrchestrator (backend/src/services/dataset_review/orchestrator.py)
+/**!
+ * @brief Coordinate dataset review session startup and lifecycle-safe intake recovery for one authenticated user.
+ * @complexity 5
+ * @data_contract Input[SessionCommand] -> Output[DatasetReviewSession | CompiledPreview | DatasetRunContext]
+ * @invariant Launch is blocked unless a current session has no open blocking findings, all launch-sensitive mappings are approved, and a non-stale Superset-generated compiled preview matches the current input fingerprint.
+ * @layer Domain
+ * @post state transitions are persisted atomically and emit observable progress for long-running steps.
+ * @pre session mutations must execute inside a persisted session boundary scoped to one authenticated user.
+ * @rationale Original 1198-line monolith violated INV_7 (400-line module limit). Decomposed into commands and helpers sub-modules while preserving the orchestrator class as the single entry point.
+ * @rejected Keeping all orchestration logic in one file because it exceeded the fractal limit by 3x.
+ * @side_effect creates task records, updates session aggregates, triggers upstream Superset calls, persists audit artifacts.
+ */
+
+// --- OrchestratorCommands (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed command and result dataclasses for dataset review orchestration boundary.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- StartSessionCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for starting a dataset review session.
+ * @complexity 2
+ */
+
+// --- StartSessionResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Session-start result carrying the persisted session and intake recovery metadata.
+ * @complexity 2
+ */
+
+// --- PreparePreviewCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for compiling one Superset-backed session preview.
+ * @complexity 2
+ */
+
+// --- PreparePreviewResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Result contract for one persisted compiled preview attempt.
+ * @complexity 2
+ */
+
+// --- LaunchDatasetCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for launching one dataset-review session into SQL Lab.
+ * @complexity 2
+ */
+
+// --- LaunchDatasetResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Launch result carrying immutable run context and any gate blockers.
+ * @complexity 2
+ */
+
+// --- OrchestratorHelpers (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Pure helper methods extracted from DatasetReviewOrchestrator for INV_7 compliance — snapshot, blockers, fingerprint, recovery bootstrap.
+ * @complexity 4
+ * @layer Domain
+ * @post Helper results are deterministic and do not mutate persistence directly.
+ * @pre Caller provides a loaded session aggregate with hydrated child collections.
+ */
+
+// --- parse_dataset_selection (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Normalize dataset-selection payload into canonical session references.
+ * @complexity 2
+ */
+
+// --- build_initial_profile (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Create the first profile snapshot so exports and detail views remain usable immediately after intake.
+ * @complexity 2
+ */
+
+// --- build_partial_recovery_findings (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Project partial Superset intake recovery into explicit findings without blocking session usability.
+ * @complexity 3
+ * @post Returns warning-level findings that preserve usable but incomplete state.
+ * @pre parsed_context.partial_recovery is true.
+ */
+
+// --- extract_effective_filter_value (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Separate normalized filter payload metadata from the user-facing effective filter value.
+ * @complexity 2
+ */
+
+// --- build_execution_snapshot (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Build effective filters, template params, approvals, and fingerprint for preview and launch gating.
+ * @complexity 4
+ * @post Returns deterministic execution snapshot for current session state without mutating persistence.
+ * @pre Session aggregate includes imported filters, template variables, and current execution mappings.
+ */
+
+// --- build_launch_blockers (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Enforce launch gates from findings, approvals, and current preview truth.
+ * @complexity 3
+ * @post Returns explicit blocker codes for every unmet launch invariant.
+ * @pre execution_snapshot was computed from current session state.
+ */
+
+// --- get_latest_preview (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Resolve the current latest preview snapshot for one session aggregate.
+ * @complexity 2
+ */
+
+// --- compute_preview_fingerprint (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Produce deterministic execution fingerprint for preview truth and staleness checks.
+ * @complexity 1
+ */
+
+// --- SessionRepositoryMutations (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persistence mutation operations for dataset review session aggregates — profile/findings, recovery state, preview, run context.
+ * @complexity 4
+ * @layer Domain
+ * @post Session aggregate writes preserve ownership and version semantics.
+ * @pre All mutations execute within authenticated request or task scope.
+ */
+
+// --- save_profile_and_findings (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist profile state and replace validation findings for an owned session in one transaction.
+ * @complexity 4
+ * @post stored profile matches the current session and findings are replaced by the supplied collection.
+ * @pre session_id belongs to user_id and the supplied profile/findings belong to the same aggregate scope.
+ * @side_effect updates profile rows, deletes stale findings, inserts current findings, and commits the transaction.
+ */
+
+// --- save_recovery_state (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist imported filters, template variables, and initial execution mappings for one owned session.
+ * @complexity 4
+ * @post Recovery state persisted to database.
+ * @pre session_id belongs to user_id.
+ * @side_effect Writes to database.
+ */
+
+// --- save_preview (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist a preview snapshot and mark prior session previews stale.
+ * @complexity 3
+ * @post preview is persisted and the session points to the latest preview identifier.
+ * @pre session_id belongs to user_id and preview is prepared for the same session aggregate.
+ * @side_effect updates prior preview statuses, inserts a preview row, mutates the parent session, and commits.
+ */
+
+// --- save_run_context (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist an immutable launch audit snapshot for an owned session.
+ * @complexity 3
+ * @post run context is persisted and linked as the latest launch snapshot for the session.
+ * @pre session_id belongs to user_id and run_context targets the same aggregate.
+ * @side_effect inserts a run-context row, mutates the parent session pointer, and commits.
+ */
+
+// --- DatasetReviewSessionRepository (backend/src/services/dataset_review/repositories/session_repository.py)
+/**!
+ * @brief Persist and retrieve dataset review session aggregates, including readiness, findings, semantic decisions, clarification state, previews, and run contexts.
+ * @complexity 5
+ * @data_contract Input[SessionMutation] -> Output[PersistedSessionAggregate]
+ * @invariant answers, mapping approvals, preview artifacts, and launch snapshots are never attributed to the wrong user or session.
+ * @layer Domain
+ * @post session aggregate reads are structurally consistent and writes preserve ownership and version semantics.
+ * @pre repository operations execute within authenticated request or task scope.
+ * @rationale Original 627-line file exceeded INV_7 (400-line module limit). Extracted mutation operations into _mutations sub-module.
+ * @rejected Keeping all repository operations in one file because it exceeded the fractal limit.
+ * @side_effect reads and writes SQLAlchemy-backed session aggregates.
+ */
+
+// --- DatasetReviewSessionVersionConflictError (backend/src/services/dataset_review/repositories/session_repository.py)
+/**!
+ * @brief Signal optimistic-lock conflicts for dataset review session mutations.
+ * @complexity 2
+ */
+
+// --- SemanticSourceResolver (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ * @brief Resolve and rank semantic candidates from trusted dictionary-like sources before any inferred fallback.
+ * @complexity 4
+ * @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+ * @layer Domain
+ * @post candidate ranking follows the configured confidence hierarchy and unresolved fuzzy matches remain reviewable.
+ * @pre selected source and target field set must be known.
+ * @side_effect may create conflict findings and semantic candidate records.
+ */
+
+// --- imports (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ */
+
+// --- DictionaryResolutionResult (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ * @brief Carries field-level dictionary resolution output with explicit review and partial-recovery state.
+ * @complexity 2
+ */
+
+// --- GitServiceModule (backend/src/services/git/__init__.py)
+/**!
+ * @brief Composed GitService via multiple inheritance from domain-specific mixins.
+ * @complexity 3
+ * @layer Infrastructure
+ * @rationale Decomposed from monolithic git_service.py (2101 lines) into
+ */
+
+// --- GitService (backend/src/services/git/__init__.py)
+/**!
+ * @brief Composed GitService class providing all Git operations — init, clone, branches, commits, push, pull,
+ * @complexity 3
+ */
+
+// --- GitServiceBase (backend/src/services/git/_base.py)
+/**!
+ * @brief Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool.
+ * @complexity 4
+ * @layer Infrastructure
+ * @rationale Extracted 'git_repos' default into DEFAULT_GIT_REPOS_PATH constant. Fixed typo 'repositorys' → 'repositories' with breaking change warning for existing installations.
+ */
+
+// --- GitServiceBranchMixin (backend/src/services/git/_branch.py)
+/**!
+ * @brief Branch and commit operations for GitService — gitflow branches, list/create/checkout branches, commit changes (all concurrent-safe via per-dashboard locks).
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- GitServiceGiteaMixin (backend/src/services/git/_gitea.py)
+/**!
+ * @brief Gitea API operations for GitService — connection testing, repository CRUD, and pull request creation. Uses shared self._http_client for connection pooling.
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- GitServiceMergeMixin (backend/src/services/git/_merge.py)
+/**!
+ * @brief Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks).
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- GitServiceRemoteMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief GitHub and GitLab provider operations for GitService — repository creation and PR/MR creation. Uses shared self._http_client for connection pooling.
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- GitServiceGithubMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief Mixin providing GitHub API operations for GitService.
+ * @complexity 3
+ */
+
+// --- GitServiceGitlabMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief Mixin providing GitLab API operations for GitService.
+ * @complexity 3
+ */
+
+// --- GitServiceStatusMixin (backend/src/services/git/_status.py)
+/**!
+ * @brief Status, diff, and commit history operations for GitService (all concurrent-safe via per-dashboard locks).
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- GitServiceSyncMixin (backend/src/services/git/_sync.py)
+/**!
+ * @brief Push and pull operations for GitService with origin host auto-alignment (concurrent-safe).
+ * @complexity 4
+ * @layer Infrastructure
+ */
+
+// --- GitServiceUrlMixin (backend/src/services/git/_url.py)
+/**!
+ * @brief URL helper mixin for GitService — parse, normalize, align, and strip credentials from Git URLs.
+ * @complexity 3
+ * @layer Infrastructure
+ */
+
+// --- health_service (backend/src/services/health_service.py)
+/**!
+ * @brief Business logic for aggregating dashboard health status from validation records.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- HealthService (backend/src/services/health_service.py)
+/**!
+ * @brief Aggregate latest dashboard validation state and manage persisted health report lifecycle.
+ * @complexity 4
+ * @data_contract Input[Session, Optional[Any]] -> Output[HealthSummaryResponse|bool]
+ * @post Exposes health summary aggregation and validation report deletion operations.
+ * @pre Service is constructed with a live SQLAlchemy session and optional config manager.
+ * @side_effect Maintains in-memory dashboard metadata caches and may coordinate cleanup through collaborators.
+ */
+
+// --- llm_prompt_templates (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Provide default LLM prompt templates and normalization helpers for runtime usage.
+ * @complexity 2
+ * @invariant All required prompt template keys are always present after normalization.
+ * @layer Domain
+ */
+
+// --- DEFAULT_LLM_PROMPTS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default prompt templates used by documentation, dashboard validation, and git commit generation.
+ * @complexity 2
+ */
+
+// --- DEFAULT_LLM_PROVIDER_BINDINGS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default provider binding per task domain.
+ * @complexity 2
+ */
+
+// --- DEFAULT_LLM_ASSISTANT_SETTINGS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default planner settings for assistant chat intent model/provider resolution.
+ * @complexity 2
+ */
+
+// --- normalize_llm_settings (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Ensure llm settings contain stable schema with prompts section and default templates.
+ * @complexity 3
+ * @post Returned dict contains prompts with all required template keys.
+ * @pre llm_settings is dictionary-like value or None.
+ */
+
+// --- is_multimodal_model (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Heuristically determine whether model supports image input required for dashboard validation.
+ * @complexity 3
+ * @deprecated Use the explicit `db_provider.is_multimodal` flag instead (see migration 9f8e7d6c5b4a).
+ * @rationale Added import warnings + warnings.warn(DeprecationWarning) to is_multimodal_model as a deprecation shim.
+ */
+
+// --- resolve_bound_provider_id (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Resolve provider id configured for a task binding with fallback to default provider.
+ * @complexity 3
+ * @post Returns configured provider id or fallback id/empty string when not defined.
+ * @pre llm_settings is normalized or raw dict from config.
+ */
+
+// --- render_prompt (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Render prompt template using deterministic placeholder replacement with graceful fallback.
+ * @complexity 3
+ * @post Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.
+ * @pre template is a string and variables values are already stringifiable.
+ */
+
+// --- llm_provider (backend/src/services/llm_provider.py)
+/**!
+ * @brief Service for managing LLM provider configurations with encrypted API keys.
+ * @complexity 3
+ * @layer Domain
+ */
+
+// --- mask_api_key (backend/src/services/llm_provider.py)
+/**!
+ * @brief Mask an API key for safe display, showing first 4 and last 4 characters.
+ * @complexity 2
+ * @post Returns "****" for very short keys; "{first 2}...{last 2}" for <=8 chars;
+ * @pre api_key is a plaintext string or None.
+ */
+
+// --- is_masked_or_placeholder (backend/src/services/llm_provider.py)
+/**!
+ * @brief Predicate: True when api_key is None, empty, "********", or contains "...".
+ * @complexity 2
+ * @post Returns True only for non-real-key values.
+ * @pre api_key can be None.
+ */
+
+// --- _require_fernet_key (backend/src/services/llm_provider.py)
+/**!
+ * @brief Load and validate the Fernet key used for secret encryption.
+ * @complexity 5
+ * @data_contract Input[ENCRYPTION_KEY:str] -> Output[bytes]
+ * @invariant Encryption initialization never falls back to a hardcoded secret.
+ * @post Returns validated key bytes ready for Fernet initialization.
+ * @pre ENCRYPTION_KEY environment variable must be set to a valid Fernet key.
+ * @side_effect Emits belief-state logs for missing or invalid encryption configuration.
+ */
+
+// --- EncryptionManager (backend/src/services/llm_provider.py)
+/**!
+ * @brief Handles encryption and decryption of sensitive data like API keys.
+ * @complexity 5
+ * @data_contract Input[str] -> Output[str]
+ * @invariant Uses only a validated secret key from environment.
+ * @post Manager exposes reversible encrypt/decrypt operations for persisted secrets.
+ * @pre ENCRYPTION_KEY is configured with a valid Fernet key before instantiation.
+ * @side_effect Initializes Fernet cryptography state from process environment.
+ * @test_contract EncryptionManagerModel ->
+ */
+
+// --- LLMProviderService (backend/src/services/llm_provider.py)
+/**!
+ * @brief Service to manage LLM provider lifecycle.
+ * @complexity 3
+ */
+
+// --- MaintenancePackage (backend/src/services/maintenance/__init__.py)
+/**!
+ * @brief Maintenance Banner service package. Re-exports all public orchestrators and helpers.
+ * @complexity 1
+ * @layer Service
+ */
+
+// --- MaintenanceBannerRenderer (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Banner text rendering and rebuild helpers. Build aggregated markdown from
+ * @complexity 3
+ */
+
+// --- build_banner_text (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Build aggregated banner markdown text from events using settings template.
+ * @complexity 3
+ */
+
+// --- _build_banner_text_for_dashboard (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Build aggregated banner text for a banner based on all active events linked to it.
+ * @complexity 2
+ */
+
+// --- rebuild_banner (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Rebuild aggregated banner text for a banner and update the Superset chart.
+ * @complexity 3
+ */
+
+// --- MaintenanceChartManager (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Chart operations for maintenance banners: create/get banner charts, process
+ * @complexity 3
+ */
+
+// --- ensure_banner_chart (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Get or create a MaintenanceDashboardBanner for a dashboard in the target environment.
+ * @complexity 3
+ */
+
+// --- _process_dashboards_for_start (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Process each dashboard for a start maintenance event: ensure banner chart,
+ * @complexity 3
+ */
+
+// --- _process_states_for_end (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Process each dashboard state for an end maintenance event: if other events
+ * @complexity 3
+ */
+
+// --- MaintenanceDashboardScanner (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Dashboard discovery and filtering helpers for maintenance banner feature.
+ * @complexity 3
+ */
+
+// --- find_affected_dashboards (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Find all dashboard IDs whose datasets reference any of the given tables.
+ * @complexity 3
+ */
+
+// --- _get_linked_dashboards (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Fetch linked dashboards for a dataset from Superset.
+ * @complexity 2
+ * @side_effect Calls Superset API.
+ */
+
+// --- _apply_dashboard_filters (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Apply scope (published/draft/all), excluded, and forced filters from settings.
+ * @complexity 2
+ */
+
+// --- _resolve_dashboard_title (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Resolve dashboard title from Superset by ID.
+ * @complexity 2
+ */
+
+// --- MaintenanceOrchestrators (backend/src/services/maintenance/_orchestrators.py)
+/**!
+ * @brief C4 orchestrators for maintenance event lifecycle: start, end, end-all.
+ * @complexity 4
+ */
+
+// --- build_idempotency_key (backend/src/services/maintenance/_orchestrators.py)
+/**!
+ * @brief Build idempotency key from (tables, start_time, end_time). Sorted lowercased tables, ISO timestamps.
+ * @complexity 2
+ * @post Returns a tuple of (frozenset(str), str|None, str|None) for DB comparison.
+ * @pre tables is a list of strings. start_time is a datetime or None. end_time is a datetime or None.
+ * @rationale message is intentionally excluded from key per spec — different message with same tables/times = same event.
+ */
+
+// --- mapping_service (backend/src/services/mapping_service.py)
+/**!
+ * @brief Orchestrates database fetching and fuzzy matching suggestions.
+ * @complexity 5
+ * @data_contract Input[source_env_id: str, target_env_id: str] -> Output[List[Dict]]
+ * @invariant Suggestions are based on database names.
+ * @layer Service
+ * @post Exposes stateless mapping suggestion orchestration over configured environments.
+ * @pre source/target environment identifiers are provided by caller.
+ * @side_effect Performs remote metadata reads through Superset API clients.
+ */
+
+// --- MappingService (backend/src/services/mapping_service.py)
+/**!
+ * @brief Service for handling database mapping logic.
+ * @complexity 3
+ * @data_contract Input[config_manager] -> Output[List[Dict]]
+ * @post Provides client resolution and mapping suggestion methods.
+ * @pre config_manager exposes get_environments() with environment objects containing id.
+ * @side_effect Instantiates Superset clients and performs upstream metadata reads.
+ */
+
+// --- notifications (backend/src/services/notifications/__init__.py)
+/**!
+ * @brief Notification service package root.
+ * @complexity 1
+ */
+
+// --- providers (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Defines abstract base and concrete implementations for external notification delivery.
+ * @complexity 5
+ * @data_contract Input[target, subject, body, context?] -> Output[bool]
+ * @invariant Sensitive credentials must be handled via encrypted config.
+ * @layer Infrastructure
+ * @post Each provider exposes async send contract returning boolean delivery outcome.
+ * @pre Provider configuration dictionaries are supplied by trusted configuration sources.
+ * @side_effect Performs outbound network I/O to SMTP or HTTP endpoints.
+ */
+
+// --- NotificationProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Abstract base class for all notification providers.
+ * @complexity 2
+ */
+
+// --- SMTPProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via SMTP.
+ * @complexity 3
+ */
+
+// --- TelegramProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via Telegram Bot API.
+ * @complexity 3
+ */
+
+// --- SlackProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via Slack Webhooks or API.
+ * @complexity 3
+ */
+
+// --- service (backend/src/services/notifications/service.py)
+/**!
+ * @brief Orchestrates notification routing based on user preferences and policy context.
+ * @complexity 5
+ * @data_contract NotificationChannelConfig -> NotificationRecipient
+ * @invariant NotificationService maintains singleton pattern for per-channel notifications
+ * @layer Domain
+ * @post Notification dispatched via configured providers
+ * @pre channel_config is loaded
+ * @side_effect Sends notifications via configured providers
+ */
+
+// --- NotificationService (backend/src/services/notifications/service.py)
+/**!
+ * @brief Routes validation reports to appropriate users and channels.
+ * @complexity 4
+ * @data_contract Input[ValidationRecord, Optional[ValidationPolicy], Optional[BackgroundTasks]] -> Output[None]
+ * @post Service can resolve targets and dispatch provider sends without mutating validation records.
+ * @pre Service receives a live DB session and configuration manager with notification payload settings.
+ * @side_effect Reads notification configuration, queries user preferences, and dispatches provider I/O.
+ */
+
+// --- profile_preference_service (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Profile preference persistence — read, update, and normalize user dashboard filter preferences
+ * @complexity 4
+ */
+
+// --- ProfilePreferenceService (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Handles profile preference persistence, validation, and token encryption.
+ * @complexity 4
+ * @post Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.
+ * @pre db session is active.
+ */
+
+// --- get_my_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return current user's persisted preference or default non-configured view.
+ * @post Returned payload belongs to current_user only.
+ * @pre current_user is authenticated.
+ */
+
+// --- get_dashboard_filter_binding (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return only dashboard-filter fields required by dashboards listing hot path.
+ * @post Returns normalized username and profile-default filter toggles without security summary expansion.
+ * @pre current_user is authenticated.
+ */
+
+// --- update_my_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Validate and persist current user's profile preference in self-scoped mode.
+ * @post Preference row for current_user is created/updated when validation passes.
+ * @pre current_user is authenticated and payload is provided.
+ */
+
+// --- _to_preference_payload (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Map ORM preference row to API DTO with token metadata.
+ * @post Returns normalized ProfilePreference object.
+ * @pre preference row can contain nullable optional fields.
+ */
+
+// --- _build_default_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Delegate to ProfileUtils.build_default_preference.
+ * @complexity 1
+ */
+
+// --- _get_preference_row (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return persisted preference row for user or None.
+ * @complexity 2
+ */
+
+// --- _get_or_create_preference_row (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return existing preference row or create new unsaved row.
+ * @complexity 2
+ */
+
+// --- profile_service (backend/src/services/profile_service.py)
+/**!
+ * @brief Composite facade orchestrating profile preference persistence, Superset account lookup,
+ * @complexity 5
+ */
+
+// --- ProfileService (backend/src/services/profile_service.py)
+/**!
+ * @brief Facade that composes ProfilePreferenceService, SupersetLookupService, and
+ * @complexity 4
+ */
+
+// --- ProfileUtils (backend/src/services/profile_utils.py)
+/**!
+ * @brief Pure utility helpers for profile data sanitization, normalization, and secret masking.
+ * @complexity 2
+ */
+
+// --- ProfileValidationError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Domain validation error for profile preference update requests.
+ * @complexity 2
+ */
+
+// --- EnvironmentNotFoundError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Raised when environment_id from lookup request is unknown in app configuration.
+ * @complexity 2
+ */
+
+// --- ProfileAuthorizationError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Raised when caller attempts cross-user preference mutation.
+ * @complexity 2
+ */
+
+// --- sanitize_text (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize optional text into trimmed form or None.
+ * @complexity 1
+ */
+
+// --- sanitize_secret (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize secret input into trimmed form or None.
+ * @complexity 1
+ */
+
+// --- sanitize_username (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize raw username into trimmed form or None for empty input.
+ * @complexity 1
+ */
+
+// --- normalize_username (backend/src/services/profile_utils.py)
+/**!
+ * @brief Apply deterministic trim+lower normalization for actor matching.
+ * @complexity 1
+ */
+
+// --- normalize_start_page (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize supported start page aliases to canonical values.
+ * @complexity 1
+ */
+
+// --- normalize_density (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize supported density aliases to canonical values.
+ * @complexity 1
+ */
+
+// --- mask_secret_value (backend/src/services/profile_utils.py)
+/**!
+ * @brief Build a safe display value for sensitive secrets.
+ * @complexity 1
+ */
+
+// --- validate_update_payload (backend/src/services/profile_utils.py)
+/**!
+ * @brief Validate username/toggle constraints for preference mutation.
+ * @complexity 2
+ * @post Returns validation errors list; empty list means valid.
+ */
+
+// --- build_default_preference (backend/src/services/profile_utils.py)
+/**!
+ * @brief Build non-persisted default preference DTO for unconfigured users.
+ * @complexity 2
+ */
+
+// --- normalize_owner_tokens (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize owners payload into deduplicated lower-cased tokens.
+ * @complexity 2
+ */
+
+// --- rbac_permission_catalog (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Discovers declared RBAC permissions from API routes/plugins and synchronizes them into auth database.
+ * @complexity 2
+ */
+
+// --- HAS_PERMISSION_PATTERN (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Regex pattern for extracting has_permission("resource", "ACTION") declarations.
+ */
+
+// --- ROUTES_DIR (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Absolute directory path where API route RBAC declarations are defined.
+ */
+
+// --- _iter_route_files (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Iterates API route files that may contain RBAC declarations.
+ * @complexity 4
+ * @post Yields Python files excluding test and cache directories.
+ * @pre ROUTES_DIR points to backend/src/api/routes.
+ */
+
+// --- _discover_route_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Extracts explicit has_permission declarations from API route source code.
+ * @complexity 4
+ * @post Returns unique set of (resource, action) pairs declared in route guards.
+ * @pre Route files are readable UTF-8 text files.
+ */
+
+// --- _discover_route_permissions_cached (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Cache route permission discovery because route source files are static during normal runtime.
+ * @complexity 4
+ * @post Returns stable discovered route permission pairs without repeated filesystem scans.
+ * @pre None.
+ */
+
+// --- _discover_plugin_execute_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Derives dynamic task permissions of form plugin:{plugin_id}:EXECUTE from plugin registry.
+ * @complexity 4
+ * @post Returns unique plugin EXECUTE permissions if loader is available.
+ * @pre plugin_loader is optional and may expose get_all_plugin_configs.
+ */
+
+// --- _discover_plugin_execute_permissions_cached (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Cache dynamic plugin EXECUTE permission pairs by normalized plugin id tuple.
+ * @complexity 4
+ * @post Returns stable permission tuple without repeated plugin catalog expansion.
+ * @pre plugin_ids is a deterministic tuple of plugin ids.
+ */
+
+// --- discover_declared_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Builds canonical RBAC permission catalog from routes and plugin registry.
+ * @complexity 4
+ * @post Returns union of route-declared and dynamic plugin EXECUTE permissions.
+ * @pre plugin_loader may be provided for dynamic task plugin permission discovery.
+ */
+
+// --- sync_permission_catalog (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Persists missing RBAC permission pairs into auth database.
+ * @complexity 4
+ * @post Missing permissions are inserted; existing permissions remain untouched.
+ * @pre declared_permissions is an iterable of (resource, action) tuples.
+ * @side_effect Commits auth database transaction when new permissions are added.
+ */
+
+// --- reports (backend/src/services/reports/__init__.py)
+/**!
+ * @brief Report service package root.
+ */
+
+// --- normalizer (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Convert task manager task objects into canonical unified TaskReport entities with deterministic fallback behavior.
+ * @complexity 5
+ * @data_contract ReportRow -> NormalizerInput; session_id -> valid UUID
+ * @invariant Normalizer instance maintains consistent field order
+ * @layer Domain
+ * @post Returns Normalizer output with normalized fields
+ * @pre session is active and valid
+ * @side_effect Read-only database operations
+ */
+
+// --- status_to_report_status (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Normalize internal task status to canonical report status.
+ * @post Always returns one of canonical ReportStatus values.
+ * @pre status may be known or unknown string/enum value.
+ */
+
+// --- build_summary (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Build deterministic user-facing summary from task payload and status.
+ * @post Returns non-empty summary text.
+ * @pre report_status is canonical; plugin_id may be unknown.
+ */
+
+// --- extract_error_context (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Extract normalized error context and next actions for failed/partial reports.
+ * @post Returns ErrorContext for failed/partial when context exists; otherwise None.
+ * @pre task is a valid Task object.
+ */
+
+// --- normalize_task_report (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Convert one Task to canonical TaskReport envelope.
+ * @post Returns TaskReport with required fields and deterministic fallback behavior.
+ * @pre task has valid id and plugin_id fields.
+ * @test_contract NormalizeTaskReport ->
+ */
+
+// --- report_service (backend/src/services/reports/report_service.py)
+/**!
+ * @brief Aggregate, normalize, filter, and paginate task reports for unified list/detail API use cases.
+ * @complexity 5
+ * @data_contract ReportQuery -> ReportRow; session_id -> valid UUID
+ * @invariant ReportService maintains consistent report structure
+ * @layer Domain
+ * @post Returns Report with generated summary
+ * @pre session is active and valid
+ * @side_effect Read-only database operations; logs report generation
+ */
+
+// --- ReportsService (backend/src/services/reports/report_service.py)
+/**!
+ * @brief Service layer for list/detail report retrieval and normalization.
+ * @complexity 5
+ * @data_contract Input[TaskManager, Optional[CleanReleaseRepository], ReportQuery|report_id] -> Output[ReportCollection|ReportDetailView|None]
+ * @invariant Service methods are read-only over task history source.
+ * @post Provides deterministic list/detail report responses.
+ * @pre TaskManager dependency is initialized.
+ * @side_effect Reads task history and optional clean-release repository state without mutating source records.
+ * @test_contract ReportsServiceModel ->
+ */
+
+// --- type_profiles (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Deterministic mapping of plugin/task identifiers to canonical report task types and fallback profile metadata.
+ * @complexity 2
+ */
+
+// --- PLUGIN_TO_TASK_TYPE (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Maps plugin identifiers to normalized report task types.
+ */
+
+// --- TASK_TYPE_PROFILES (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Profile metadata registry for each normalized task type.
+ */
+
+// --- resolve_task_type (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Resolve canonical task type from plugin/task identifier with guaranteed fallback.
+ * @post Always returns one of TaskType enum values.
+ * @pre plugin_id may be None or unknown.
+ * @test_contract ResolveTaskType ->
+ */
+
+// --- get_type_profile (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Return deterministic profile metadata for a task type.
+ * @post Returns a profile dict and never raises for unknown types.
+ * @pre task_type may be known or unknown.
+ * @test_contract GetTypeProfile ->
+ */
+
+// --- ResourceServiceModule (backend/src/services/resource_service.py)
+/**!
+ * @brief Shared service for fetching resource data with Git status and task status
+ * @complexity 5
+ * @data_contract ResourceQuery -> ResourceStatusSummary
+ * @invariant All resources include metadata about their current state
+ * @layer Service
+ * @side_effect Queries multiple backends for status
+ */
+
+// --- ResourceService (backend/src/services/resource_service.py)
+/**!
+ * @brief Provides centralized access to resource data with enhanced metadata
+ * @complexity 3
+ */
+
+// --- security_badge_service (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Builds security summary and permission badges for profile UI — role extraction,
+ * @complexity 4
+ */
+
+// --- SecurityBadgeService (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Builds security summary with role names and permission badges for profile UI display.
+ * @complexity 4
+ * @post build_security_summary returns ProfileSecuritySummary with deterministic sorted permissions.
+ * @pre plugin_loader may be None for degraded permission discovery.
+ */
+
+// --- build_security_summary (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Build read-only security snapshot with role and permission badges.
+ * @post Returns deterministic security projection for profile UI.
+ * @pre current_user is authenticated.
+ */
+
+// --- _collect_user_permission_pairs (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Collect effective permission tuples from current user's roles.
+ * @post Returns unique normalized (resource, ACTION) tuples.
+ * @pre current_user can include role/permission graph.
+ */
+
+// --- _format_permission_key (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Convert normalized permission pair to compact UI key.
+ * @complexity 1
+ */
+
+// --- SqlTableExtractorModule (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Three-phase SQL+Jinja table name extractor for virtual datasets as per FR-003.
+ * @complexity 2
+ */
+
+// --- detect_jinja_spans (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 1: Split raw SQL text into Jinja spans and SQL spans.
+ * @complexity 2
+ * @post Returns a list of (span_type: str, text: str) tuples.
+ * @pre raw_sql is a string (possibly empty).
+ */
+
+// --- extract_tables_from_jinja (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 2: Extract "schema.table" references from Jinja string values.
+ * @complexity 2
+ */
+
+// --- is_string_literal (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Check if a sqlparse Token is a string literal (not a schema.table identifier).
+ * @complexity 1
+ * @post Returns True if the token is a string/Single/Literal.String.
+ * @pre token is a sqlparse Token.
+ */
+
+// --- extract_tables_from_sql_span (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 3: Extract schema.table references from SQL text using regex + sqlparse filtering.
+ * @complexity 2
+ */
+
+// --- extract_tables_from_sql (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Three-phase entry point: extract all schema.table references from raw SQL+Jinja text.
+ * @complexity 2
+ * @post Returns a set of lowercased fully-qualified table names (schema.table format).
+ * @pre raw_sql is a string (possibly empty).
+ */
+
+// --- superset_lookup_service (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Environment-scoped Superset account lookup with degradation fallback for network failures.
+ * @complexity 4
+ * @layer Domain
+ * @rationale Extracted from ProfileService to satisfy INV_7. Superset account lookup has distinct
+ */
+
+// --- SupersetLookupService (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Resolves environments and queries Superset users in selected environment,
+ * @complexity 4
+ */
+
+// --- _resolve_environment (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Resolve environment model from configured environments by id.
+ * @complexity 2
+ * @post Returns environment object when found else None.
+ * @pre environment_id is provided.
+ */
+
+// --- ValidationRunService (backend/src/services/validation_run_service.py)
+/**!
+ * @brief Business logic for validation run queries: list, detail, delete.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- _resolve_task_name (backend/src/services/validation_run_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- ValidationService (backend/src/services/validation_service.py)
+/**!
+ * @brief Business logic for validation task CRUD and trigger-run.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- ValidationTaskService (backend/src/services/validation_service.py)
+/**!
+ * @brief Validation task (policy) CRUD with provider validation and trigger-run.
+ * @complexity 4
+ * @rationale Service-layer class for validation task CRUD with provider validation and trigger-run. Separates API layer concerns from business logic; enables unit testing without HTTP.
+ * @rejected Embedding CRUD in route handlers rejected — would duplicate validation logic across endpoints; centralized service ensures consistent provider/environment validation before persistence.
+ */
+
+// --- _validate_provider (backend/src/services/validation_service.py)
+/**!
+ * @complexity 2
+ * @rationale Centralizes multimodal LLM provider check so all task operations (create, update, trigger) share the same validation gate. Uses LLMProviderService for reuse.
+ * @rejected Duplicating multimodal check in each caller rejected — would create maintenance burden if provider validation rules change or error messages need updating.
+ */
+
+// --- _validate_environment (backend/src/services/validation_service.py)
+/**!
+ * @complexity 1
+ */
+
+// --- _policy_to_response (backend/src/services/validation_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- TestSessionConfig (backend/tests/conftest.py)
+/**!
+ * @brief Shared pytest fixtures and session configuration for backend tests.
+ * @complexity 2
+ * @post Database tables exist before test session executes.
+ * @pre All test modules use sys.path patching to import from src/.
+ * @rationale AUTH_SECRET_KEY/AUTH_DATABASE_URL/DATABASE_URL/DEV_MODE must be set before
+ */
+
+// --- TestArchiveParser (backend/tests/core/migration/test_archive_parser.py)
+/**!
+ * @brief Unit tests for MigrationArchiveParser ZIP extraction contract.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- test_extract_objects_from_zip_collects_all_types (backend/tests/core/migration/test_archive_parser.py)
+/**!
+ * @brief Verify archive parser collects dashboard/chart/dataset YAML objects into typed buckets.
+ * @complexity 2
+ * @test_contract zip_archive_fixture -> typed dashboard/chart/dataset extraction buckets
+ * @test_edge external_fail -> Corrupt archive would fail extraction before typed buckets are returned.
+ * @test_scenario archive_with_supported_objects_extracts_all_types -> One YAML file per supported type lands in matching bucket.
+ */
+
+// --- TestDryRunOrchestrator (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Unit tests for MigrationDryRunService diff and risk computation contracts.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- _load_fixture (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Load canonical migration dry-run fixture payload used by deterministic orchestration assertions.
+ * @complexity 2
+ */
+
+// --- test_migration_dry_run_service_builds_diff_and_risk (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Verify dry-run orchestration returns stable diff summary and required risk codes.
+ * @complexity 2
+ * @test_contract dry_run_result_contract -> {
+ * @test_edge external_fail -> Engine transform stub failure would stop result production.
+ * @test_invariant dry_run_result_contract_matches_fixture -> VERIFIED_BY: [dry_run_builds_diff_and_risk]
+ * @test_scenario dry_run_builds_diff_and_risk -> Stable diff summary and required risk codes are returned.
+ */
+
+// --- test_git_service_get_repo_path_guard (backend/tests/core/test_defensive_guards.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_git_service_get_repo_path_recreates_base_dir (backend/tests/core/test_defensive_guards.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_superset_client_import_dashboard_guard (backend/tests/core/test_defensive_guards.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_git_service_init_repo_reclones_when_path_is_not_a_git_repo (backend/tests/core/test_defensive_guards.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults (backend/tests/core/test_defensive_guards.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_git_service_configure_identity_updates_repo_local_config (backend/tests/core/test_defensive_guards.py)
+/**!
+ * @complexity 2
+ */
+
+// --- TestGitServiceGiteaPr (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Validate Gitea PR creation fallback behavior when configured server URL is stale.
+ * @complexity 2
+ * @invariant A 404 from primary Gitea URL retries once against remote-url host when different.
+ * @layer Domain
+ * @semantics tests, git, gitea, pull_request, fallback
+ */
+
+// --- test_derive_server_url_from_remote_strips_credentials (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Ensure helper returns host base URL and removes embedded credentials.
+ * @complexity 2
+ * @post Result is scheme+host only.
+ * @pre remote_url is an https URL with username/token.
+ */
+
+// --- test_create_gitea_pull_request_retries_with_remote_host_on_404 (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Verify create_gitea_pull_request retries with remote URL host after primary 404.
+ * @complexity 2
+ * @post Method returns success payload from fallback request.
+ * @pre primary server_url differs from remote_url host.
+ */
+
+// --- test_create_gitea_pull_request_returns_branch_error_when_target_missing (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Ensure Gitea 404 on PR creation is mapped to actionable target-branch validation error.
+ * @complexity 2
+ * @post Service raises HTTPException 400 with explicit missing target branch message.
+ * @pre PR create call returns 404 and target branch is absent.
+ */
+
+// --- TestMappingService (backend/tests/core/test_mapping_service.py)
+/**!
+ * @brief Unit tests for the IdMappingService matching UUIDs to integer IDs.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- test_sync_environment_upserts_correctly (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_remote_id_returns_integer (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_remote_ids_batch_returns_dict (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_sync_environment_updates_existing_mapping (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_sync_environment_skips_resources_without_uuid (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_sync_environment_handles_api_error_gracefully (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_remote_id_returns_none_for_missing (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_remote_ids_batch_returns_empty_for_empty_input (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_mapping_service_alignment_with_test_data (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_sync_environment_requires_existing_env (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_sync_environment_deletes_stale_mappings (backend/tests/core/test_mapping_service.py)
+/**!
+ * @complexity 2
+ */
+
+// --- TestMigrationEngine (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Unit tests for MigrationEngine's cross-filter patching algorithms.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- MockMappingService (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Deterministic mapping service double for native filter ID remapping scenarios.
+ * @complexity 2
+ * @invariant Returns mappings only for requested UUID keys present in seeded map.
+ * @invariant_violation resource_type parameter is silently ignored. Lookups are UUID-only; chart and dataset UUIDs share the same namespace. Tests that mix resource types will produce false positives.
+ */
+
+// --- _write_dashboard_yaml (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Serialize dashboard metadata into YAML fixture with json_metadata payload for patch tests.
+ * @complexity 2
+ */
+
+// --- test_patch_dashboard_metadata_replaces_chart_ids (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify native filter target chartId values are remapped via mapping service results.
+ * @complexity 2
+ */
+
+// --- test_patch_dashboard_metadata_replaces_dataset_ids (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify native filter target datasetId values are remapped via mapping service results.
+ * @complexity 2
+ */
+
+// --- test_patch_dashboard_metadata_skips_when_no_metadata (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure dashboard files without json_metadata are left unchanged by metadata patching.
+ * @complexity 2
+ */
+
+// --- test_patch_dashboard_metadata_handles_missing_targets (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify patching updates mapped targets while preserving unmapped native filter IDs.
+ * @complexity 2
+ */
+
+// --- test_extract_chart_uuids_from_archive (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify chart archive scan returns complete local chart id-to-uuid mapping.
+ * @complexity 2
+ */
+
+// --- test_transform_yaml_replaces_database_uuid (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure dataset YAML database_uuid fields are replaced when source UUID mapping exists.
+ * @complexity 2
+ */
+
+// --- test_transform_yaml_ignores_unmapped_uuid (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure transform_yaml leaves dataset files untouched when database_uuid is not mapped.
+ * @complexity 2
+ */
+
+// --- test_transform_zip_end_to_end (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Validate full ZIP transform pipeline remaps datasets and dashboard cross-filter chart IDs.
+ * @complexity 2
+ */
+
+// --- test_transform_zip_invalid_path (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify transform_zip returns False when source archive path does not exist.
+ * @complexity 2
+ */
+
+// --- test_transform_yaml_nonexistent_file (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify transform_yaml raises FileNotFoundError for missing YAML source files.
+ * @complexity 2
+ */
+
+// --- test_clean_release_cli (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Smoke tests for the redesigned clean release CLI.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- test_cli_candidate_register_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify candidate-register command exits successfully for valid required arguments.
+ * @complexity 2
+ */
+
+// --- test_cli_manifest_build_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify candidate-register/artifact-import/manifest-build smoke path succeeds end-to-end.
+ * @complexity 2
+ */
+
+// --- test_cli_compliance_run_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify compliance run/status/violations/report commands complete for prepared candidate.
+ * @complexity 2
+ * @invariant SimpleNamespace substitutes for GlobalSettings — any field rename in GlobalSettings will silently not propagate here; re-verify on GlobalSettings schema changes.
+ */
+
+// --- test_cli_release_gate_commands_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify approve/reject/publish/revoke release-gate commands execute with valid fixtures.
+ * @complexity 2
+ */
+
+// --- TestCleanReleaseTui (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @brief Unit tests for the interactive curses TUI of the clean release process.
+ * @complexity 2
+ * @invariant TUI initializes, handles hotkeys (F5, F10) and safely falls back without TTY.
+ * @layer Tests
+ * @semantics tests, tui, clean-release, curses
+ */
+
+// --- test_headless_fallback (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_tui_initial_render (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_tui_run_checks_f5 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_tui_exit_f10 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_tui_clear_history_f7 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_tui_real_mode_bootstrap_imports_artifacts_catalog (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_clean_release_tui_v2 (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Smoke tests for thin-client TUI action dispatch and blocked transition behavior.
+ * @complexity 2
+ * @layer Domain
+ */
+
+// --- _build_mock_stdscr (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Build deterministic curses screen mock with default terminal geometry and exit key.
+ * @complexity 2
+ */
+
+// --- test_tui_f5_dispatches_run_action (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify F5 key dispatch invokes run_checks exactly once before graceful exit.
+ * @complexity 2
+ */
+
+// --- test_tui_f5_run_smoke_reports_blocked_state (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify blocked compliance state is surfaced after F5-triggered run action.
+ * @complexity 2
+ */
+
+// --- test_tui_non_tty_refuses_startup (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify non-TTY execution returns exit code 2 with actionable stderr guidance.
+ * @complexity 2
+ */
+
+// --- test_tui_f8_blocked_without_facade_binding (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify F8 path reports disabled action instead of mutating hidden facade state.
+ * @complexity 2
+ */
+
+// --- TestApprovalService (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Define approval gate contracts for approve/reject operations over immutable compliance evidence.
+ * @complexity 2
+ * @invariant Approval is allowed only for PASSED report bound to candidate; duplicate approve and foreign report must be rejected.
+ * @layer Tests
+ * @semantics tests, clean-release, approval, lifecycle, gate
+ */
+
+// --- _seed_candidate_with_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Seed candidate and report fixtures for approval gate tests.
+ * @complexity 2
+ * @post Repository contains candidate and report linked by candidate_id.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- test_approve_rejects_blocked_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure approve is rejected when latest report final status is not PASSED.
+ * @complexity 2
+ * @post approve_candidate raises ApprovalGateError.
+ * @pre Candidate has BLOCKED report.
+ */
+
+// --- test_approve_rejects_foreign_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure approve is rejected when report belongs to another candidate.
+ * @complexity 2
+ * @post approve_candidate raises ApprovalGateError.
+ * @pre Candidate exists, report candidate_id differs.
+ */
+
+// --- test_approve_rejects_duplicate_approve (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure repeated approve decision for same candidate is blocked.
+ * @complexity 2
+ * @post Second approve_candidate call raises ApprovalGateError.
+ * @pre Candidate has already been approved once.
+ */
+
+// --- test_reject_persists_decision_without_promoting_candidate_state (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure reject decision is immutable and does not promote candidate to APPROVED.
+ * @complexity 2
+ * @post reject_candidate persists REJECTED decision; candidate status remains unchanged.
+ * @pre Candidate has PASSED report and CHECK_PASSED lifecycle state.
+ */
+
+// --- test_reject_then_publish_is_blocked (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure latest REJECTED decision blocks publication gate.
+ * @complexity 2
+ * @post publish_candidate raises PublicationGateError.
+ * @pre Candidate is rejected for passed report.
+ */
+
+// --- test_candidate_manifest_services (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Test lifecycle and manifest versioning for release candidates.
+ * @complexity 2
+ * @layer Tests
+ */
+
+// --- test_candidate_lifecycle_transitions (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify release candidate allows legal status transitions and rejects forbidden back-transitions.
+ * @complexity 2
+ */
+
+// --- test_manifest_versioning_and_immutability (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify manifest versions increment monotonically and older snapshots remain queryable.
+ * @complexity 2
+ */
+
+// --- _valid_artifacts (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Provide canonical valid artifact payload used by candidate registration tests.
+ * @complexity 2
+ */
+
+// --- test_register_candidate_rejects_duplicate_candidate_id (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify duplicate candidate_id registration is rejected by service invariants.
+ * @complexity 2
+ */
+
+// --- test_register_candidate_rejects_malformed_artifact_input (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify candidate registration rejects artifact payloads missing required fields.
+ * @complexity 2
+ */
+
+// --- test_register_candidate_rejects_empty_artifact_set (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify candidate registration rejects empty artifact collections.
+ * @complexity 2
+ */
+
+// --- test_manifest_service_rebuild_creates_new_version (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify repeated manifest build creates a new incremented immutable version.
+ * @complexity 2
+ */
+
+// --- test_manifest_service_existing_manifest_cannot_be_mutated (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify existing manifest snapshot remains immutable when rebuilding newer manifest version.
+ * @complexity 2
+ */
+
+// --- test_manifest_service_rejects_missing_candidate (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify manifest build fails with missing candidate identifier.
+ * @complexity 2
+ */
+
+// --- TestComplianceExecutionService (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Validate stage pipeline and run finalization contracts for compliance execution.
+ * @complexity 2
+ * @invariant Missing manifest prevents run startup; failed execution cannot finalize as PASSED.
+ * @layer Tests
+ * @semantics tests, clean-release, compliance, pipeline, run-finalization
+ */
+
+// --- _seed_with_candidate_policy_registry (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Build deterministic repository state for run startup tests.
+ * @complexity 2
+ * @post Returns repository with candidate, policy and registry; manifest is optional.
+ * @pre candidate_id and snapshot ids are non-empty.
+ */
+
+// --- test_run_without_manifest_rejected (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure compliance run cannot start when manifest is unresolved.
+ * @complexity 2
+ * @post start_check_run raises ValueError and no run is persisted.
+ * @pre Candidate/policy exist but manifest is missing.
+ */
+
+// --- test_task_crash_mid_run_marks_failed (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure execution crash conditions force FAILED run status.
+ * @complexity 2
+ * @post execute_stages persists run with FAILED status.
+ * @pre Run exists, then required dependency becomes unavailable before execute_stages.
+ */
+
+// --- test_blocked_run_finalization_blocks_report_builder (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure blocked runs require blocking violations before report creation.
+ * @complexity 2
+ * @post finalize keeps BLOCKED and report_builder rejects zero blocking violations.
+ * @pre Manifest contains prohibited artifacts leading to BLOCKED decision.
+ */
+
+// --- TestComplianceTaskIntegration (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify clean release compliance runs execute through TaskManager lifecycle with observable success/failure outcomes.
+ * @complexity 2
+ * @invariant Compliance execution triggered as task produces terminal task status and persists run evidence.
+ * @layer Tests
+ * @semantics tests, clean-release, compliance, task-manager, integration
+ */
+
+// --- _seed_repository (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Prepare deterministic candidate/policy/registry/manifest fixtures for task integration tests.
+ * @complexity 2
+ * @post Returns initialized repository and identifiers for compliance run startup.
+ * @pre with_manifest controls manifest availability.
+ */
+
+// --- CleanReleaseCompliancePlugin (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief TaskManager plugin shim that executes clean release compliance orchestration.
+ * @complexity 2
+ */
+
+// --- _PluginLoaderStub (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Provide minimal plugin loader contract used by TaskManager in integration tests.
+ * @complexity 2
+ * @contract Partial PluginLoader stub. Implements: has_plugin, get_plugin. Stubs (NotImplementedError): list_plugins, get_all_plugins, get_all_plugin_configs.
+ * @invariant has_plugin/get_plugin only acknowledge the seeded compliance plugin id.
+ */
+
+// --- _make_task_manager (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Build TaskManager with mocked persistence services for isolated integration tests.
+ * @complexity 2
+ * @post Returns TaskManager ready for async task execution.
+ */
+
+// --- _wait_for_terminal_task (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Poll task registry until target task reaches terminal status.
+ * @complexity 2
+ * @post Returns task with SUCCESS or FAILED status, otherwise raises TimeoutError.
+ * @pre task_id exists in manager registry.
+ */
+
+// --- test_compliance_run_executes_as_task_manager_task (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify successful compliance execution is observable as TaskManager SUCCESS task.
+ * @complexity 2
+ * @post Task ends with SUCCESS; run is persisted with SUCCEEDED status and task binding.
+ * @pre Candidate, policy and manifest are available in repository.
+ */
+
+// --- test_compliance_run_missing_manifest_marks_task_failed (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify missing manifest startup failure is surfaced as TaskManager FAILED task.
+ * @complexity 2
+ * @post Task ends with FAILED and run history remains empty.
+ * @pre Candidate/policy exist but manifest is absent.
+ */
+
+// --- TestDemoModeIsolation (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Verify demo and real mode namespace isolation contracts before TUI integration.
+ * @complexity 2
+ * @layer Tests
+ * @semantics clean-release, demo-mode, isolation, namespace, repository
+ */
+
+// --- test_resolve_namespace_separates_demo_and_real (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Ensure namespace resolver returns deterministic and distinct namespaces.
+ * @complexity 2
+ * @post Demo and real namespaces are different and stable.
+ * @pre Mode names are provided as user/runtime strings.
+ */
+
+// --- test_build_namespaced_id_prevents_cross_mode_collisions (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Ensure ID generation prevents demo/real collisions for identical logical IDs.
+ * @complexity 2
+ * @post Produced physical IDs differ by namespace prefix.
+ * @pre Same logical candidate id is used in two different namespaces.
+ */
+
+// --- test_create_isolated_repository_keeps_mode_data_separate (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Verify demo and real repositories do not leak state across mode boundaries.
+ * @complexity 2
+ * @post Candidate mutations in one mode are not visible in the other mode.
+ * @pre Two repositories are created for distinct modes.
+ */
+
+// --- TestPolicyResolutionService (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Verify trusted policy snapshot resolution contract and error guards.
+ * @complexity 2
+ * @invariant Resolution uses only ConfigManager active IDs and rejects runtime override attempts.
+ * @layer Tests
+ * @semantics clean-release, policy-resolution, trusted-snapshots, contracts
+ */
+
+// --- _config_manager (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Build deterministic ConfigManager-like stub for tests.
+ * @complexity 2
+ * @invariant Only settings.clean_release.active_policy_id and active_registry_id are populated; any other settings field access raises AttributeError.
+ * @post Returns object exposing get_config().settings.clean_release active IDs.
+ * @pre policy_id and registry_id may be None or non-empty strings.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_missing_profile (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure resolution fails when trusted profile is not configured.
+ * @complexity 2
+ * @post Raises PolicyResolutionError with missing trusted profile reason.
+ * @pre active_policy_id is None.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_missing_registry (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure resolution fails when trusted registry is not configured.
+ * @complexity 2
+ * @post Raises PolicyResolutionError with missing trusted registry reason.
+ * @pre active_registry_id is None and active_policy_id is set.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_rejects_override_attempt (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure runtime override attempt is rejected even if snapshots exist.
+ * @complexity 2
+ * @post Raises PolicyResolutionError with override forbidden reason.
+ * @pre valid trusted snapshots exist in repository and override is provided.
+ */
+
+// --- TestPublicationService (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Define publication gate contracts over approved candidates and immutable publication records.
+ * @complexity 2
+ * @invariant Publish requires approval; revoke requires existing publication; republish after revoke is allowed as a new record.
+ * @layer Tests
+ * @semantics tests, clean-release, publication, revoke, gate
+ */
+
+// --- _seed_candidate_with_passed_report (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Seed candidate/report fixtures for publication gate scenarios.
+ * @complexity 2
+ * @post Repository contains candidate and PASSED report.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- test_publish_without_approval_rejected (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure publish action is blocked until candidate is approved.
+ * @complexity 2
+ * @post publish_candidate raises PublicationGateError.
+ * @pre Candidate has PASSED report but status is not APPROVED.
+ */
+
+// --- test_revoke_unknown_publication_rejected (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure revocation is rejected for unknown publication id.
+ * @complexity 2
+ * @post revoke_publication raises PublicationGateError.
+ * @pre Repository has no matching publication record.
+ */
+
+// --- test_republish_after_revoke_creates_new_active_record (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure republish after revoke is allowed and creates a new ACTIVE record.
+ * @complexity 2
+ * @post New publish call returns distinct publication id with ACTIVE status.
+ * @pre Candidate is APPROVED and first publication has been revoked.
+ */
+
+// --- TestReportAuditImmutability (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Validate report snapshot immutability expectations and append-only audit hook behavior for US2.
+ * @complexity 2
+ * @invariant Built reports are immutable snapshots; audit hooks produce append-only event traces.
+ * @layer Tests
+ * @semantics tests, clean-release, report, audit, immutability, append-only
+ */
+
+// --- _terminal_run (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Build deterministic terminal run fixture for report snapshot tests.
+ * @complexity 2
+ * @post Returns a terminal ComplianceRun suitable for report generation.
+ * @pre final_status is a valid ComplianceDecision value.
+ */
+
+// --- test_report_builder_sets_immutable_snapshot_flag (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Ensure generated report payload is marked immutable and persisted as snapshot.
+ * @complexity 2
+ * @post Built report has immutable=True and repository stores same immutable object.
+ * @pre Terminal run exists.
+ */
+
+// --- test_repository_rejects_report_overwrite_for_same_report_id (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Define immutability contract that report snapshots cannot be overwritten by same identifier.
+ * @complexity 2
+ * @post Second save for same report id is rejected with explicit immutability error.
+ * @pre Existing report with id is already persisted.
+ */
+
+// --- test_audit_hooks_emit_append_only_event_stream (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Verify audit hooks emit one event per action call and preserve call order.
+ * @complexity 2
+ * @post Three calls produce three ordered info entries with molecular prefixes.
+ * @pre Logger backend is patched.
+ */
+
+// --- SupersetCompatibilityMatrixTests (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Verifies Superset preview and SQL Lab endpoint fallback strategy used by dataset-review orchestration.
+ * @complexity 2
+ * @layer Tests
+ * @semantics dataset_review, superset, compatibility_matrix, preview, sql_lab, tests
+ */
+
+// --- make_adapter (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Build an adapter with a mock Superset client and deterministic environment for compatibility tests.
+ * @complexity 2
+ */
+
+// --- test_preview_prefers_supported_client_method_before_network_fallback (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms preview compilation uses a supported client method first when the capability exists.
+ * @complexity 2
+ */
+
+// --- test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms preview fallback walks the compatibility matrix from preferred to legacy endpoints until one returns compiled SQL.
+ * @complexity 2
+ * @fragile Positional call assertion — ordering changes will break this test without indicating a real regression. Prefer content-based assertion.
+ */
+
+// --- test_sql_lab_launch_falls_back_to_legacy_execute_endpoint (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms SQL Lab launch falls back from modern to legacy execute endpoint and preserves canonical session reference extraction.
+ * @complexity 2
+ * @fragile Positional call assertion — ordering changes will break this test without indicating a real regression. Prefer content-based assertion.
+ */
+
+// --- TestAPIKeyAuth (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Contract tests for API key authentication — valid key, invalid, revoked, expired, missing permission,
+ * @complexity 3
+ */
+
+// --- test_no_header_returns_none (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief No X-API-Key header → returns None.
+ * @complexity 2
+ */
+
+// --- test_valid_key_returns_principal (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Valid API key → returns APIKeyPrincipal with correct fields.
+ * @complexity 2
+ */
+
+// --- test_invalid_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Invalid API key → 401.
+ * @complexity 2
+ */
+
+// --- test_revoked_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Revoked (active=False) API key → 401.
+ * @complexity 2
+ */
+
+// --- test_expired_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Expired API key → 401.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_valid (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Valid API key with matching permission → 202.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_wrong_permission (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief API key lacks required permission → 403.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_revoked (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Revoked API key → 401.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_expired (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Expired API key → 401.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_invalid (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Non-existent key → 401.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_environment_scope (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Key scoped to ss-dev, request for ss-prod → 400.
+ * @complexity 2
+ */
+
+// --- test_api_key_auth_environment_scope_ok (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Key scoped to ss-dev, request for ss-dev → 202.
+ * @complexity 2
+ */
+
+// --- test_jwt_precedence (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Both valid API key + valid JWT → JWT takes precedence.
+ * @complexity 2
+ */
+
+// --- TestAPIKeyModel (backend/tests/test_api_key_model.py)
+/**!
+ * @brief Contract tests for the APIKey SQLAlchemy model — creation, hash storage, and field constraints.
+ * @complexity 2
+ * @test_contract APIKey model stores SHA-256 hash and prefix; raw key never persisted.
+ * @test_edge active defaults to True
+ */
+
+// --- clean_db (backend/tests/test_api_key_model.py)
+/**!
+ * @brief In-memory SQLite fixture for APIKey model tests.
+ * @complexity 1
+ */
+
+// --- test_create_api_key (backend/tests/test_api_key_model.py)
+/**!
+ * @brief Create APIKey with required fields and verify defaults.
+ * @complexity 2
+ */
+
+// --- test_key_hash_unique (backend/tests/test_api_key_model.py)
+/**!
+ * @brief key_hash is unique — duplicate raises IntegrityError.
+ * @complexity 2
+ */
+
+// --- test_prefix_length (backend/tests/test_api_key_model.py)
+/**!
+ * @brief prefix is exactly 11 characters.
+ * @complexity 2
+ */
+
+// --- test_active_default_true (backend/tests/test_api_key_model.py)
+/**!
+ * @brief active column defaults to True.
+ * @complexity 2
+ */
+
+// --- TestAPIKeyRoutes (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Contract tests for admin API key CRUD endpoints — list, create (raw key present), revoke, idempotent revoke.
+ * @complexity 3
+ * @test_contract DELETE /api/admin/api-keys/{id} -> 200 with status=revoked
+ * @test_edge missing_permissions -> 422
+ */
+
+// --- test_list_empty (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief No keys → returns empty list.
+ * @complexity 2
+ */
+
+// --- test_list_with_keys (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Keys exist → returns list without raw_key or key_hash fields.
+ * @complexity 2
+ */
+
+// --- test_create_valid (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Valid request → 201 with raw_key, prefix, id.
+ * @complexity 2
+ */
+
+// --- test_create_missing_name (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Missing name → 400 or 422.
+ * @complexity 2
+ */
+
+// --- test_create_empty_permissions (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Empty permissions → 400 or 422.
+ * @complexity 2
+ */
+
+// --- test_revoke_valid (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke existing active key → 200 with status=revoked.
+ * @complexity 2
+ */
+
+// --- test_revoke_already_revoked (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke already revoked key → 404.
+ * @complexity 2
+ */
+
+// --- test_revoke_not_found (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke non-existent key → 404.
+ * @complexity 2
+ */
+
+// --- TestAuth (backend/tests/test_auth.py)
+/**!
+ * @brief Covers authentication service/repository behavior and auth bootstrap helpers.
+ * @complexity 2
+ * @layer Tests
+ */
+
+// --- test_create_admin_creates_user_with_optional_email (backend/tests/test_auth.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_create_admin_is_idempotent_for_existing_user (backend/tests/test_auth.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_ensure_encryption_key_generates_backend_env_file (backend/tests/test_auth.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_ensure_encryption_key_reuses_existing_env_file_value (backend/tests/test_auth.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_ensure_encryption_key_prefers_process_environment (backend/tests/test_auth.py)
+/**!
+ * @complexity 2
+ */
+
+// --- TestConstantsAuditFixes (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Verify Class 5 fix — hardcoded values extracted to named module-level constants.
+ * @complexity 3
+ * @test_edge git_typo_fix -> services/git/_base.py still has "repositorys" at line 148 (bug)
+ */
+
+// --- test_page_size_constant_exists (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief DEFAULT_PAGE_SIZE contract: importable, int > 0 (not yet defined in source).
+ * @complexity 2
+ */
+
+// --- test_llm_analysis_timeout_constants (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Named timeout constants should exist per RATIONALE comment (not yet defined).
+ * @complexity 2
+ */
+
+// --- test_base_dir_constant_replaces_parents (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief BASE_DIR resolves to backend/ root, not __file__-dependent relative path.
+ * @complexity 2
+ */
+
+// --- test_git_service_repositorys_typo_regression (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief services/git/_base.py still has "repositorys" (old typo) at line 148 — known bug.
+ * @complexity 2
+ */
+
+// --- test_git_default_repos_path_constant (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief DEFAULT_GIT_REPOS_PATH should be defined per RATIONALE (not yet defined).
+ * @complexity 2
+ */
+
+// --- test_superset_client_module_loads (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief superset_client._base is importable (no dependency on crashing modules).
+ * @complexity 2
+ */
+
+// --- test_constants_are_immutable (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Module-level constants use int/str types (immutable by convention).
+ * @complexity 2
+ */
+
+// --- TestCoreScheduler (backend/tests/test_core_scheduler.py)
+/**!
+ * @brief Verify SchedulerService load_schedules and translation job add/remove contracts.
+ * @complexity 3
+ * @test_edge add_remove_translation_job — job correctly registered and removed from APScheduler
+ * @test_invariant translation_jobs_persist_across_reload -> VERIFIED_BY: [test_load_schedules_reloads_translation_schedules]
+ */
+
+// --- test_load_schedules_reloads_translation_schedules (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_add_and_remove_translation_job (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_remove_nonexistent_translation_job_no_error (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_add_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_load_schedules_loads_validation_policies (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_trigger_validation_creates_tasks (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_trigger_validation_skips_missing_policy (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_trigger_validation_skips_inactive_policy (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_trigger_validation_skips_no_dashboards (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_remove_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_remove_nonexistent_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_reload_validation_policy_adds_job (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_reload_validation_policy_removes_job_when_policy_gone (backend/tests/test_core_scheduler.py)
+/**!
+ * @complexity 1
+ */
+
+// --- TestDashboardsApi (backend/tests/test_dashboards_api.py)
+/**!
+ * @brief Comprehensive contract-driven tests for Dashboard Hub API
+ * @complexity 2
+ * @layer Tests
+ * @semantics tests, dashboards, api, contract, remediation
+ */
+
+// --- test_get_dashboard_tasks_history_success (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_dashboard_tasks_history_sorting (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_dashboard_thumbnail_env_not_found (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_get_dashboard_thumbnail_202 (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_migrate_dashboards_pre_checks (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_backup_dashboards_pre_checks (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_backup_dashboards_with_schedule (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_task_matches_dashboard_logic (backend/tests/test_dashboards_api.py)
+/**!
+ * @complexity 2
+ */
+
+// --- TestDeprecationAuditFixes (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Verify Class 7 fix — is_multimodal_model should emit DeprecationWarning.
+ * @complexity 3
+ * @rationale The RATIONALE comment in llm_prompt_templates.py says warnings.warn(DeprecationWarning)
+ * @test_edge text_only_model_returns_false -> models with text-only markers return False
+ */
+
+// --- test_is_multimodal_model_emits_warning (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief is_multimodal_model should emit DeprecationWarning (shim not yet implemented).
+ * @complexity 2
+ */
+
+// --- test_multimodal_model_returns_true (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Known multimodal models (gpt-4o, claude-3, gemini) return True.
+ * @complexity 2
+ */
+
+// --- test_text_only_model_returns_false (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Text-only models (embedding, whisper, rerank) return False.
+ * @complexity 2
+ */
+
+// --- test_empty_model_returns_false (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Empty or None model name returns False without error.
+ * @complexity 2
+ */
+
+// --- test_case_insensitive_matching (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Model name matching is case-insensitive.
+ * @complexity 2
+ */
+
+// --- test_deprecation_comment_exists (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief The source module documents the @DEPRECATED rationale in the region header.
+ * @complexity 2
+ */
+
+// --- TestLayoutUtils (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Contract tests for layout utility functions — _estimate_markdown_height.
+ * @complexity 3
+ */
+
+// --- test_empty_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Empty string returns minimum height 19.
+ * @complexity 2
+ */
+
+// --- test_single_line_text (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Short text without padding returns expected computed height.
+ * @complexity 2
+ */
+
+// --- test_content_with_padding (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Content with padding:12 — 24px added to content height.
+ * @complexity 2
+ */
+
+// --- test_very_long_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Very long content (3000 chars) capped at max height 200.
+ * @complexity 2
+ */
+
+// --- test_html_only_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief HTML-only content (no visible text) returns minimum height 19.
+ * @complexity 2
+ */
+
+// --- test_log_persistence (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Unit tests for TaskLogPersistenceService.
+ * @complexity 2
+ * @layer Tests
+ * @semantics test, log, persistence, unit_test
+ */
+
+// --- TestLogPersistence (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test suite for TaskLogPersistenceService.
+ * @complexity 2
+ * @test_data log_entry -> {"task_id": "test-task-1", "level": "INFO", "source": "test_source", "message": "Test message"}
+ */
+
+// --- test_add_logs_single (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding a single log entry.
+ * @complexity 2
+ * @post Log entry persisted to database.
+ * @pre Service and session initialized.
+ */
+
+// --- test_add_logs_batch (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding multiple log entries in batch.
+ * @complexity 2
+ * @post All log entries persisted to database.
+ * @pre Service and session initialized.
+ */
+
+// --- test_add_logs_empty (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding empty log list (should be no-op).
+ * @complexity 2
+ * @post No logs added.
+ * @pre Service initialized.
+ */
+
+// --- test_get_logs_by_task_id (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs by task ID.
+ * @complexity 2
+ * @post Returns logs for the specified task.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_filters (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with level and source filters.
+ * @complexity 2
+ * @post Returns filtered logs.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_pagination (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with pagination.
+ * @complexity 2
+ * @post Returns paginated logs.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_search (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with search query.
+ * @complexity 2
+ * @post Returns logs matching search query.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_log_stats (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving log statistics.
+ * @complexity 2
+ * @post Returns LogStats model with counts by level and source.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_sources (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving unique log sources.
+ * @complexity 2
+ * @post Returns list of unique sources.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_task (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting logs by task ID.
+ * @complexity 2
+ * @post Logs for the task are deleted.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_tasks (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting logs for multiple tasks.
+ * @complexity 2
+ * @post Logs for all specified tasks are deleted.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_tasks_empty (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting with empty list (no-op).
+ * @complexity 2
+ * @post No error, no deletion.
+ * @pre Service initialized.
+ */
+
+// --- TestLogger (backend/tests/test_logger.py)
+/**!
+ * @brief Unit tests for the custom logger CoT JSON formatters and configuration context manager.
+ * @complexity 2
+ * @invariant All required log statements must correctly check the threshold.
+ * @layer Tests
+ * @semantics logging, tests, belief_state, cot, json
+ */
+
+// --- test_belief_scope_success_coherence (backend/tests/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs REFLECT marker on success.
+ * @complexity 2
+ * @post Logs are verified to contain REFLECT marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_reason_not_visible_at_info (backend/tests/test_logger.py)
+/**!
+ * @brief Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.
+ * @complexity 2
+ * @post REASON/REFLECT markers are not captured at INFO level.
+ * @pre belief_scope is available. caplog fixture is used.
+ */
+
+// --- test_cot_json_formatter_output (backend/tests/test_logger.py)
+/**!
+ * @brief Test that CotJsonFormatter produces valid JSON with expected fields.
+ * @complexity 2
+ */
+
+// --- test_cot_json_formatter_plain_message (backend/tests/test_logger.py)
+/**!
+ * @brief Test that CotJsonFormatter wraps plain messages (no extra) with default marker.
+ * @complexity 2
+ */
+
+// --- TestLoggingAuditFixes (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief Verify Class 2 fix — no bare `except: pass` patterns remain in src/.
+ * @complexity 3
+ * @test_edge plugin_loader_uses_logger -> plugin_loader.py uses logger, not print
+ */
+
+// --- _collect_src_files (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief Collect all .py files under src/ excluding test/ and mock/ directories.
+ * @complexity 1
+ */
+
+// --- test_except_pass_replaced_with_log (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief AST audit: bare `except: pass` nodes are absent from src/ source files.
+ * @complexity 2
+ */
+
+// --- test_plugin_loader_uses_logger_not_print (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py (src/core/) uses logger for error/warning, not print().
+ * @complexity 2
+ */
+
+// --- test_plugin_loader_imports_logger (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py imports a logger or _logger for structured reporting.
+ * @complexity 2
+ */
+
+// --- test_plugin_loader_logger_calls_exist (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py references logger.error/warning/info in its code.
+ * @complexity 2
+ */
+
+// --- test_maintenance_api (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Contract tests for Maintenance Banner API endpoints — T016, T025.
+ * @complexity 3
+ */
+
+// --- test_start_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Valid request returns 202 with task_id and maintenance_id.
+ * @complexity 2
+ */
+
+// --- test_start_missing_tables (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Missing tables field returns 422.
+ * @complexity 2
+ */
+
+// --- test_start_end_time_before_start (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief end_time before start_time returns 400.
+ * @complexity 2
+ */
+
+// --- test_start_too_many_tables (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief More than 100 tables returns 422 (Pydantic validation).
+ * @complexity 2
+ */
+
+// --- test_start_idempotency (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Same (tables, start, end) returns already_active.
+ * @complexity 2
+ */
+
+// --- test_end_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Valid maintenance_id returns 202.
+ * @complexity 2
+ */
+
+// --- test_end_not_found (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Non-existent maintenance_id returns 404.
+ * @complexity 2
+ */
+
+// --- test_end_all_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief end-all returns 202.
+ * @complexity 2
+ */
+
+// --- test_list_events (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Returns active and completed events.
+ * @complexity 2
+ */
+
+// --- test_expired_event_auto_ends (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event past end_time with ACTIVE status → create_task called with auto-end params.
+ * @complexity 2
+ */
+
+// --- test_future_end_time_skipped (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event with future end_time → no task created, skipped by < now filter.
+ * @complexity 2
+ */
+
+// --- test_no_end_time_skipped (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event with end_time=None → no task created, skipped by isnot(None) filter.
+ * @complexity 2
+ */
+
+// --- test_list_banners (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Returns list of active banners.
+ * @complexity 2
+ */
+
+// --- test_get_settings (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief GET returns settings.
+ * @complexity 2
+ */
+
+// --- test_put_settings (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief PUT updates settings.
+ * @complexity 2
+ */
+
+// --- test_maintenance_service (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Integration tests for MaintenanceService — T018, T026, T026a.
+ * @complexity 3
+ */
+
+// --- test_basic_key (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Basic idempotency key with tables and times.
+ * @complexity 2
+ */
+
+// --- test_key_without_end_time (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Idempotency key with None end_time.
+ * @complexity 2
+ */
+
+// --- test_key_table_sorting (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Tables are sorted alphabetically in frozenset.
+ * @complexity 2
+ */
+
+// --- test_empty_tables (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Empty tables list returns empty.
+ * @complexity 2
+ */
+
+// --- test_table_based_match (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Table-based dataset matching.
+ * @complexity 2
+ */
+
+// --- test_virtual_dataset_match (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Virtual SQL dataset matching via SqlTableExtractor.
+ * @complexity 2
+ */
+
+// --- test_superset_api_failure (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Superset API failure propagates.
+ * @complexity 2
+ */
+
+// --- test_creates_new_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No existing banner — creates new chart and banner row.
+ * @complexity 2
+ */
+
+// --- test_returns_existing_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Existing active banner — returns it.
+ * @complexity 2
+ */
+
+// --- test_chart_creation_failure (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Chart creation failure propagates.
+ * @complexity 2
+ */
+
+// --- test_single_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Single event — direct substitution.
+ * @complexity 2
+ */
+
+// --- test_multiple_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Multiple events — combined message.
+ * @complexity 2
+ */
+
+// --- test_empty_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Empty events list returns empty string.
+ * @complexity 2
+ */
+
+// --- test_missing_variables (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Missing variables replaced with empty string.
+ * @complexity 2
+ */
+
+// --- test_html_escaping (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Message is HTML-escaped.
+ * @complexity 2
+ */
+
+// --- test_happy_path (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Happy path: event with matching dashboards.
+ * @complexity 2
+ */
+
+// --- test_no_matching_dashboards (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No dashboards match the tables.
+ * @complexity 2
+ */
+
+// --- test_event_not_found (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Event ID not in DB.
+ * @complexity 2
+ */
+
+// --- test_already_processed_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Event already ACTIVE — idempotent.
+ * @complexity 2
+ */
+
+// --- test_rebuild_active_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Active banner with active state — rebuilds text.
+ * @complexity 2
+ */
+
+// --- test_banner_not_found (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Banner ID not found.
+ * @complexity 2
+ */
+
+// --- test_end_active_event_single_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief End event with single active dashboard — banner removed entirely.
+ * @complexity 2
+ */
+
+// --- test_end_event_shared_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Two events, same dashboard — ending one rebuilds banner, doesn't delete.
+ * @complexity 2
+ */
+
+// --- test_end_already_completed_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Already completed event — idempotent.
+ * @complexity 2
+ */
+
+// --- test_end_all_active_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief End all active events.
+ * @complexity 2
+ */
+
+// --- test_no_active_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No active events.
+ * @complexity 2
+ */
+
+// --- test_mixed_active_and_completed (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Mix of active and completed events — only active get ended.
+ * @complexity 2
+ */
+
+// --- TestResourceHubs (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Contract tests for resource hub dashboards/datasets listing and pagination boundary validation.
+ * @complexity 2
+ * @layer Tests
+ * @semantics tests, resource-hubs, dashboards, datasets, pagination, api
+ */
+
+// --- test_dashboards_api (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify GET /api/dashboards contract compliance
+ * @complexity 2
+ * @test_contract dashboards_query -> dashboards payload or not_found response
+ * @test_invariant dashboards_route_contract_stays_observable -> VERIFIED_BY: [dashboards_env_found_returns_payload, dashboards_unknown_env_returns_not_found, dashboards_search_filters_results]
+ * @test_scenario dashboards_search_filters_results -> Search narrows payload to matching dashboard title.
+ */
+
+// --- mock_deps (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Provide dependency override fixture for resource hub route tests.
+ * @complexity 2
+ * @invariant unconstrained mock — no spec= enforced; attribute typos will silently pass
+ * @test_fixture resource_hub_overrides -> INLINE_JSON
+ */
+
+// --- test_get_dashboards_not_found (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint returns 404 for unknown environment identifier.
+ * @complexity 2
+ */
+
+// --- test_get_dashboards_search (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint search filter returns matching subset.
+ * @complexity 2
+ */
+
+// --- test_datasets_api (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify GET /api/datasets contract compliance
+ * @complexity 2
+ * @test_contract datasets_query -> datasets payload or error response
+ * @test_invariant datasets_route_contract_stays_observable -> VERIFIED_BY: [datasets_env_found_returns_payload, datasets_unknown_env_returns_not_found, datasets_search_filters_results, datasets_service_failure_returns_503]
+ * @test_scenario datasets_service_failure_returns_503 -> Backend fetch failure surfaces as HTTP 503.
+ */
+
+// --- test_get_datasets_not_found (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint returns 404 for unknown environment identifier.
+ * @complexity 2
+ */
+
+// --- test_get_datasets_search (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint search filter returns matching dataset subset.
+ * @complexity 2
+ */
+
+// --- test_get_datasets_service_failure (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint surfaces backend fetch failure as HTTP 503.
+ * @complexity 2
+ */
+
+// --- test_pagination_boundaries (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify pagination validation for GET endpoints
+ * @complexity 2
+ * @test_contract pagination_query -> validation error response
+ * @test_edge external_fail -> Validation failure returns HTTP 400 without partial payload.
+ * @test_invariant pagination_limits_apply_to_both_routes -> VERIFIED_BY: [dashboards_zero_page_rejected, dashboards_oversize_page_rejected, datasets_zero_page_rejected, datasets_oversize_page_rejected]
+ * @test_scenario datasets_oversize_page_rejected -> page_size=101 returns HTTP 400.
+ */
+
+// --- test_get_dashboards_pagination_zero_page (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint rejects page=0 with HTTP 400 validation error.
+ * @complexity 2
+ * @test_edge pagination_zero_page -> {page: 0, status: 400}
+ */
+
+// --- test_get_dashboards_pagination_oversize (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint rejects oversized page_size with HTTP 400.
+ * @complexity 2
+ * @test_edge pagination_oversize -> {page_size: 101, status: 400}
+ */
+
+// --- test_get_datasets_pagination_zero_page (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint rejects page=0 with HTTP 400.
+ * @complexity 2
+ * @test_edge pagination_zero_page_datasets -> {page: 0, status: 400}
+ */
+
+// --- test_get_datasets_pagination_oversize (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint rejects oversized page_size with HTTP 400.
+ * @complexity 2
+ * @test_edge pagination_oversize_datasets -> {page_size: 101, status: 400}
+ */
+
+// --- TestSecurityAuditFixes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Verify Class 1 security audit fixes — env-only secrets, crash-early, CORS parsing.
+ * @complexity 3
+ * @rationale AuthConfig constructor is broken due to pydantic-settings v2 Field(env=...) deprecation
+ * @test_edge database_url_postgres_fallback -> POSTGRES_URL is used when DATABASE_URL is unset
+ */
+
+// --- test_missing_secret_key_crashes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig.validate_secret_key raises ValueError when value is empty (crash-early).
+ * @complexity 2
+ */
+
+// --- test_missing_auth_db_url_crashes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig.validate_auth_db_url raises ValueError when URL is empty and DEV_MODE is off.
+ * @complexity 2
+ */
+
+// --- test_auth_db_dev_fallback_works (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief When DEV_MODE=true and AUTH_DATABASE_URL is unset, dev fallback is used without crash.
+ * @complexity 2
+ */
+
+// --- test_allowed_origins_parsing (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief os.getenv("ALLOWED_ORIGINS").split(",") correctly parses comma-separated origins.
+ * @complexity 2
+ */
+
+// --- test_cors_wildcard_default (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief When ALLOWED_ORIGINS is not set, default returns ["*"].
+ * @complexity 2
+ */
+
+// --- test_cors_parsing_single_value (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Single origin returns single-element list.
+ * @complexity 2
+ */
+
+// --- test_cors_parsing_with_trailing_spaces (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Origins with trailing spaces are preserved (no strip).
+ * @complexity 2
+ */
+
+// --- test_database_url_env_override (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief DATABASE_URL env var takes precedence over POSTGRES_URL.
+ * @complexity 2
+ */
+
+// --- test_database_url_postgres_fallback (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief POSTGRES_URL is used when DATABASE_URL is unset.
+ * @complexity 2
+ */
+
+// --- test_database_url_raises_when_both_unset (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief RuntimeError is expected when both DATABASE_URL and POSTGRES_URL are unset (non-dev).
+ * @complexity 2
+ */
+
+// --- test_auth_config_module_contract (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig contract: the class exists, validators are documented.
+ * @complexity 2
+ */
+
+// --- test_sql_table_extractor (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Unit tests for SqlTableExtractor — T017. Verifies three-phase extraction of schema.table references from SQL+Jinja.
+ * @complexity 3
+ * @layer Tests
+ * @test_contract extract_tables_from_sql(str) -> set[str]
+ * @test_edge string_literal_false_positive -> filtered out by sqlparse
+ * @test_fixture jinja_expr -> INLINE_SQL: "SELECT * FROM {{ source('raw', 'sales') }}"
+ */
+
+// --- test_simple_select (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Happy path: simple SELECT with FROM schema.table.
+ * @complexity 2
+ */
+
+// --- test_multiple_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief JOIN with multiple schema-qualified tables.
+ * @complexity 2
+ */
+
+// --- test_empty_input (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Empty string returns empty set.
+ * @complexity 2
+ */
+
+// --- test_no_schema_qualified_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Unqualified table names are NOT matched.
+ * @complexity 2
+ */
+
+// --- test_case_insensitive (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Matching is case-insensitive; result is lowercased.
+ * @complexity 2
+ */
+
+// --- test_string_literal_false_positive (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Date literal like '2026.04.30' must NOT be matched as schema.table.
+ * @complexity 2
+ */
+
+// --- test_jinja_string_concat (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Table reference inside Jinja {{ 'raw.sales' }} as a direct string.
+ * @complexity 2
+ */
+
+// --- test_jinja_set_block (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Table name in Jinja {% set %} block string value.
+ * @complexity 2
+ */
+
+// --- test_mixed_jinja_and_sql (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Mixed Jinja string and plain SQL schema.table references.
+ * @complexity 2
+ */
+
+// --- test_cte_with_schema_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief CTE body with schema-qualified table references.
+ * @complexity 2
+ */
+
+// --- test_jinja_comment_excluded (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Jinja comment {# ... #} content should not produce table extraction (no string patterns inside comments).
+ * @complexity 2
+ */
+
+// --- TestStorageAuditFixes (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief Verify Class 7 typo fix — "repositorys" → "repositories" across all storage/git modules.
+ * @complexity 3
+ * @test_edge git_typo_regression -> No "repositorys" string exists in storage/git source files
+ */
+
+// --- test_repository_typo_fixed (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief FileCategory.REPOSITORY equals "repositories", NOT "repositorys".
+ * @complexity 2
+ */
+
+// --- test_repo_path_default_fixed (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief StorageConfig().repo_path defaults to "repositories".
+ * @complexity 2
+ */
+
+// --- test_storage_model_compiles (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief All storage model classes import without errors.
+ * @complexity 2
+ */
+
+// --- test_backup_category_unchanged (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief FileCategory.BACKUP still equals "backups" (not affected by typo fix).
+ * @complexity 2
+ */
+
+// --- test_storage_config_fields_have_correct_types (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief StorageConfig fields are all strings with correct defaults.
+ * @complexity 2
+ */
+
+// --- TestStorageConfigMigration (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify StorageConfig root_path change from "backups" to "/app/storage",
+ * @complexity 3
+ */
+
+// --- TestStorageConfigDefaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify StorageConfig default field values after the root_path change.
+ * @complexity 2
+ */
+
+// --- test_root_path_default (backend/tests/test_storage_config.py)
+/**!
+ * @brief StorageConfig().root_path must equal "/app/storage" (was "backups").
+ * @complexity 2
+ */
+
+// --- test_root_path_is_string (backend/tests/test_storage_config.py)
+/**!
+ * @brief root_path is always a str (type safety).
+ * @complexity 2
+ */
+
+// --- test_other_defaults_unchanged (backend/tests/test_storage_config.py)
+/**!
+ * @brief Other StorageConfig fields were not affected by the root_path change.
+ * @complexity 2
+ */
+
+// --- test_global_settings_propagates_storage (backend/tests/test_storage_config.py)
+/**!
+ * @brief GlobalSettings().storage.root_path inherits the StorageConfig default.
+ * @complexity 2
+ */
+
+// --- test_override_root_path (backend/tests/test_storage_config.py)
+/**!
+ * @brief Explicit root_path overrides the default.
+ * @complexity 2
+ */
+
+// --- TestConfigManagerDefaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify ConfigManager produces correct defaults when no config.json exists.
+ * @complexity 2
+ */
+
+// --- test_init_falls_to_defaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief ConfigManager(…nonexistent…) loads defaults when both DB and config.json are absent.
+ * @complexity 2
+ * @rationale Full path: _load_config → no DB record → _load_from_legacy_file (absent)
+ * @test_fixture tmp_path + mocked SessionLocal returning no record.
+ */
+
+// --- test_default_config_root_path (backend/tests/test_storage_config.py)
+/**!
+ * @brief _default_config() hardcodes root_path == "/app/storage" via StorageConfig default.
+ * @complexity 2
+ */
+
+// --- test_features_from_env_still_applied (backend/tests/test_storage_config.py)
+/**!
+ * @brief Even without config.json, _apply_features_from_env runs during default init.
+ * @complexity 2
+ */
+
+// --- TestValidatePath (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify ConfigManager.validate_path contract.
+ * @complexity 2
+ */
+
+// --- test_validate_path_creates_directory (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path creates the target directory and returns (True, "OK").
+ * @complexity 2
+ * @test_fixture tmp_path ensures no side effects on real storage.
+ */
+
+// --- test_validate_path_already_exists (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path succeeds when the directory already exists.
+ * @complexity 2
+ */
+
+// --- test_validate_path_nonexistent_root (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path returns False for a path under / (non-writable by non-root).
+ * @complexity 2
+ * @rationale /nonexistent/path cannot be created by a non-root user.
+ */
+
+// --- test_validate_path_read_only_parent (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path returns False when the parent directory is not writable.
+ * @complexity 2
+ */
+
+// --- TestGitPluginConfigIntegration (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify GitPlugin uses shared config_manager from src.dependencies (no config.json fallback).
+ * @complexity 2
+ */
+
+// --- test_git_plugin_uses_shared_config_manager (backend/tests/test_storage_config.py)
+/**!
+ * @brief GitPlugin.__init__ picks up the shared config_manager from src.dependencies.
+ * @complexity 2
+ * @test_fixture mock GitService to avoid real git initialisation.
+ */
+
+// --- test_git_plugin_fallback_creates_new (backend/tests/test_storage_config.py)
+/**!
+ * @brief When from src.dependencies import config_manager fails,
+ * @complexity 2
+ */
+
+// --- TestRegressionGuard (backend/tests/test_storage_config.py)
+/**!
+ * @brief Guard against regressions in existing test contracts and stale assertions.
+ * @complexity 2
+ */
+
+// --- test_existing_test_would_fail (backend/tests/test_storage_config.py)
+/**!
+ * @brief Existing test_storage_audit_fixes.py still asserts root_path=="backups" (WRONG).
+ * @complexity 2
+ * @rationale The sibling test at test_storage_audit_fixes.py:66 contains
+ */
+
+// --- test_storage_settings_endpoint_shape (backend/tests/test_storage_config.py)
+/**!
+ * @brief The API response shape for storage settings is still StorageConfig.
+ * @complexity 2
+ */
+
+// --- test_task_manager (backend/tests/test_task_manager.py)
+/**!
+ * @brief Unit tests for TaskManager lifecycle, CRUD, log buffering, and filtering.
+ * @complexity 2
+ * @invariant TaskManager state changes are deterministic and testable with mocked dependencies.
+ * @layer Core
+ * @semantics task-manager, lifecycle, CRUD, log-buffer, filtering, tests
+ */
+
+// --- _make_manager (backend/tests/test_task_manager.py)
+/**!
+ * @complexity 2
+ */
+
+// --- _cleanup_manager (backend/tests/test_task_manager.py)
+/**!
+ * @complexity 2
+ */
+
+// --- test_task_persistence (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Unit tests for TaskPersistenceService.
+ * @complexity 2
+ * @layer Tests
+ * @semantics test, task, persistence, unit_test
+ * @test_data valid_task -> {"id": "test-uuid-1", "plugin_id": "backup", "status": "PENDING"}
+ */
+
+// --- TestTaskPersistenceHelpers (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test suite for TaskPersistenceService static helper methods.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_none (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with None input.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_dict (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with dict input.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_list (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with list input.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_json_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with JSON string.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_empty_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with empty/null strings.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_plain_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with non-JSON string.
+ * @complexity 2
+ */
+
+// --- test_json_load_if_needed_integer (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with integer.
+ * @complexity 2
+ */
+
+// --- test_parse_datetime_none (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with None.
+ * @complexity 2
+ */
+
+// --- test_parse_datetime_datetime_object (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with datetime object.
+ * @complexity 2
+ */
+
+// --- test_parse_datetime_iso_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with ISO string.
+ * @complexity 2
+ */
+
+// --- test_parse_datetime_invalid_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with invalid string.
+ * @complexity 2
+ */
+
+// --- test_parse_datetime_integer (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with non-string, non-datetime.
+ * @complexity 2
+ */
+
+// --- TestTaskPersistenceService (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test suite for TaskPersistenceService CRUD operations.
+ * @complexity 2
+ * @test_data valid_task -> {"id": "test-uuid-1", "plugin_id": "backup", "status": "PENDING"}
+ */
+
+// --- setup_class (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Setup in-memory test database.
+ * @complexity 2
+ */
+
+// --- teardown_class (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Dispose of test database.
+ * @complexity 2
+ */
+
+// --- setup_method (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Clean task_records table before each test.
+ * @complexity 2
+ */
+
+// --- test_persist_task_new (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting a new task creates a record.
+ * @complexity 2
+ * @post TaskRecord exists in database.
+ * @pre Empty database.
+ */
+
+// --- test_persist_task_update (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test updating an existing task.
+ * @complexity 2
+ * @post Task record updated with new status.
+ * @pre Task already persisted.
+ */
+
+// --- test_persist_task_with_logs (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting a task with log entries.
+ * @complexity 2
+ * @post Logs serialized as JSON in task record.
+ * @pre Task has logs attached.
+ */
+
+// --- test_persist_task_failed_extracts_error (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test that FAILED task extracts last error message.
+ * @complexity 2
+ * @post record.error contains last error message.
+ * @pre Task has FAILED status with ERROR logs.
+ */
+
+// --- test_persist_tasks_batch (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting multiple tasks.
+ * @complexity 2
+ * @post All task records created.
+ * @pre Empty database.
+ */
+
+// --- test_load_tasks (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks from database.
+ * @complexity 2
+ * @post Returns list of Task objects with correct data.
+ * @pre Tasks persisted.
+ */
+
+// --- test_load_tasks_with_status_filter (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks filtered by status.
+ * @complexity 2
+ * @post Returns only tasks matching status filter.
+ * @pre Tasks with different statuses persisted.
+ */
+
+// --- test_load_tasks_with_limit (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks with limit.
+ * @complexity 2
+ * @post Returns at most `limit` tasks.
+ * @pre Multiple tasks persisted.
+ */
+
+// --- test_delete_tasks (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test deleting tasks by ID list.
+ * @complexity 2
+ * @post Specified tasks deleted, others remain.
+ * @pre Tasks persisted.
+ */
+
+// --- test_delete_tasks_empty_list (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test deleting with empty list (no-op).
+ * @complexity 2
+ * @post No error, no changes.
+ * @pre None.
+ */
+
+// --- test_persist_task_with_datetime_in_params (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test json_serializable handles datetime in params.
+ * @complexity 2
+ * @post Params serialized correctly.
+ * @pre Task params contain datetime values.
+ */
+
+// --- test_persist_task_resolves_environment_slug_to_existing_id (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Ensure slug-like environment token resolves to environments.id before persisting task.
+ * @complexity 2
+ * @post task_records.environment_id stores actual environments.id and does not violate FK.
+ * @pre environments table contains env with name convertible to provided slug token.
+ */
+
+// --- TranslateCorrectionTests (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Tests for term correction API endpoints and DictionaryManager correction methods.
+ * @complexity 2
+ * @layer Tests
+ * @semantics tests, translate, corrections, dictionary
+ * @test_contract CorrectionFlow ->
+ */
+
+// --- test_submit_correction_creates_entry (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify that a correction creates a new dictionary entry.
+ * @complexity 2
+ */
+
+// --- test_submit_correction_conflict_detected (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify conflict detection when entry already exists.
+ * @complexity 2
+ */
+
+// --- test_submit_correction_overwrite (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify that correction overwrites existing entry.
+ * @complexity 2
+ */
+
+// --- test_bulk_corrections_atomic (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify bulk corrections are applied atomically.
+ * @complexity 2
+ */
+
+// --- test_api_correction_missing_dict (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify POST corrections without dictionary_id returns 422.
+ * @complexity 2
+ */
+
+// --- test_api_bulk_corrections (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify POST /corrections/bulk works.
+ * @complexity 2
+ */
+
+// --- TestTranslateExecutorFilter (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @brief Verify TranslationExecutor._filter_new_keys contracts — key dedup, empty-set, guard triggers.
+ * @complexity 3
+ * @test_edge null_source_data — None source_data is safely handled
+ * @test_invariant new_key_only_filter -> VERIFIED_BY: [test_no_prior_run_returns_all_rows, test_filters_existing_keys, test_composite_keys]
+ */
+
+// --- test_no_prior_run_returns_all_rows (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_filters_existing_keys (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_composite_keys (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_all_keys_existing_returns_empty (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_empty_key_cols_returns_all_rows (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_null_source_data_handled (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_prior_run_no_records_returns_all (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_key_cols_none_returns_all (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @complexity 1
+ */
+
+// --- TranslateHistoryTests (backend/tests/test_translate_history.py)
+/**!
+ * @brief Tests for run history list/detail endpoints and metrics aggregation.
+ * @complexity 2
+ * @layer Tests
+ * @semantics tests, translate, history, metrics
+ * @test_contract HistoryFlow ->
+ */
+
+// --- test_list_runs_empty (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify runs list returns empty result initially.
+ * @complexity 2
+ */
+
+// --- test_list_runs_with_data (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify runs list returns data when runs exist.
+ * @complexity 2
+ */
+
+// --- test_list_runs_filter_job_id (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify filtering runs by job_id works.
+ * @complexity 2
+ */
+
+// --- test_list_runs_filter_status (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify filtering runs by status works.
+ * @complexity 2
+ */
+
+// --- test_get_run_detail (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify run detail returns config_snapshot, records, events.
+ * @complexity 2
+ */
+
+// --- test_get_job_metrics (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics endpoint returns aggregated data.
+ * @complexity 2
+ */
+
+// --- test_get_all_metrics (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify global metrics endpoint returns data.
+ * @complexity 2
+ */
+
+// --- test_metrics_empty_job (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics for job with no runs returns zeros.
+ * @complexity 2
+ */
+
+// --- test_run_detail_not_found (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify 404 on non-existent run detail.
+ * @complexity 2
+ */
+
+// --- test_list_runs_includes_language_info (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify run list includes target_languages, total_translated, and language_stats.
+ * @complexity 2
+ */
+
+// --- test_metrics_per_language_breakdown (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics endpoint returns per_language_metrics.
+ * @complexity 2
+ */
+
+// --- test_metric_snapshot_stores_per_language (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify MetricSnapshot stores per_language_metrics via prune_expired.
+ * @complexity 2
+ */
+
+// --- test_combined_metrics_live_and_snapshot (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify combined metrics merge live + snapshot per-language data.
+ * @complexity 2
+ */
+
+// --- TranslateJobTests (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Tests for translation job CRUD endpoints and service layer with column validation.
+ * @complexity 2
+ * @layer Tests
+ * @semantics tests, translate, jobs, crud, validation
+ * @test_contract TranslateJobCRUD ->
+ */
+
+// --- valid_job_payload (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Standard valid payload for creating a translation job.
+ * @complexity 2
+ */
+
+// --- MockConfigManager (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Mock ConfigManager for service tests that returns a test environment.
+ * @complexity 2
+ */
+
+// --- db_session (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Create a fresh DB session with transaction rollback for each test.
+ * @complexity 2
+ */
+
+// --- mock_api_deps (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Override FastAPI dependencies (including get_db with in-memory SQLite) for API route tests.
+ * @complexity 2
+ * @rationale Uses the same in-memory SQLite engine as service tests to avoid real PostgreSQL dependency.
+ * @rejected Mocking get_db with MagicMock — the route handlers need a real session for ORM queries.
+ */
+
+// --- client (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief FastAPI TestClient for API route tests.
+ * @complexity 2
+ */
+
+// --- test_create_job_valid (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a valid job payload creates a job successfully.
+ * @complexity 2
+ */
+
+// --- test_create_job_missing_translation_column (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that creating a job with datasource but no translation column raises ValueError.
+ * @complexity 2
+ */
+
+// --- test_create_job_invalid_upsert_strategy (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that an invalid upsert strategy is rejected.
+ * @complexity 2
+ */
+
+// --- test_get_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be retrieved by ID.
+ * @complexity 2
+ */
+
+// --- test_get_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that getting a non-existent job raises ValueError.
+ * @complexity 2
+ */
+
+// --- test_list_jobs (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that listing jobs returns all created jobs.
+ * @complexity 2
+ */
+
+// --- test_list_jobs_with_status_filter (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that listing jobs with a status filter works.
+ * @complexity 2
+ */
+
+// --- test_update_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be updated.
+ * @complexity 2
+ */
+
+// --- test_delete_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be deleted.
+ * @complexity 2
+ */
+
+// --- test_duplicate_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be duplicated.
+ * @complexity 2
+ */
+
+// --- test_duplicate_job_custom_name (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be duplicated with a custom name.
+ * @complexity 2
+ */
+
+// --- test_detect_virtual_columns (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify virtual column detection from column metadata.
+ * @complexity 2
+ */
+
+// --- test_get_dialect_from_database (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify dialect extraction from Superset database records.
+ * @complexity 2
+ */
+
+// --- test_get_dialect_from_database_unsupported (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that unsupported dialects raise ValueError.
+ * @complexity 2
+ */
+
+// --- test_api_create_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify POST /api/translate/jobs returns 201 with valid payload.
+ * @complexity 2
+ */
+
+// --- test_api_list_jobs (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify GET /api/translate/jobs returns 200.
+ * @complexity 2
+ */
+
+// --- test_api_get_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify GET non-existent job returns 404.
+ * @complexity 2
+ */
+
+// --- test_api_delete_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify DELETE non-existent job returns 404.
+ * @complexity 2
+ */
+
+// --- test_api_duplicate_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify duplicating a non-existent job returns 404.
+ * @complexity 2
+ */
+
+// --- test_api_create_job_422_missing_name (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify POST with missing required fields returns 422.
+ * @complexity 2
+ */
+
+// --- test_api_datasource_columns_missing_env (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify datasource columns endpoint without env_id returns 422.
+ * @complexity 2
+ */
+
+// --- test_api_datasource_columns_bad_env (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify datasource columns with unknown env returns 400.
+ * @complexity 2
+ */
+
+// --- test_api_update_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify PUT non-existent job returns 404.
+ * @complexity 2
+ */
+
+// --- TranslateSchedulerTests (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Tests for TranslationScheduler CRUD and APScheduler integration.
+ * @complexity 2
+ * @layer Tests
+ * @semantics tests, translate, scheduler
+ * @test_contract ScheduleFlow ->
+ */
+
+// --- test_create_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule creation with valid params.
+ * @complexity 2
+ */
+
+// --- test_update_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule update.
+ * @complexity 2
+ */
+
+// --- test_delete_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule deletion.
+ * @complexity 2
+ */
+
+// --- test_enable_disable_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify enable/disable toggle.
+ * @complexity 2
+ */
+
+// --- test_get_schedule_not_found (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify ValueError on getting non-existent schedule.
+ * @complexity 2
+ */
+
+// --- test_list_active_schedules (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify listing only active schedules.
+ * @complexity 2
+ */
+
+// --- test_get_next_executions (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify next execution time computation.
+ * @complexity 2
+ */
+
+// --- test_get_next_executions_invalid (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify invalid cron returns empty list.
+ * @complexity 2
+ */
+
+// --- TestTranslateSchedulerExecution (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @brief Verify execute_scheduled_translation contracts — trigger_type dispatch, baseline expiry fallback.
+ * @complexity 3
+ * @test_edge execution_error_handled — run marked FAILED, schedule tracking updated
+ * @test_invariant trigger_type_dispatch -> VERIFIED_BY: [test_new_key_only_mode, test_baseline_expired_fallback, test_full_mode_default]
+ */
+
+// --- test_new_key_only_mode (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_baseline_expired_fallback (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_full_mode_default (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_inactive_schedule_skips (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_schedule_not_found_skips (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_baseline_expired_full_mode (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_execution_error_handled (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @complexity 1
+ */
+
+// --- TestTranslateSchedulerGuard (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @brief Verify execute_scheduled_translation concurrency guard and stale-PENDING clearance contracts.
+ * @complexity 3
+ * @test_edge multiple_stale_pending_all_cleared — multiple stale PENDING runs → all cleared as FAILED, execution proceeds
+ * @test_invariant stale_pending_clearance -> VERIFIED_BY: [test_stale_pending_cleared_and_proceeds, test_multiple_stale_pending_all_cleared]
+ */
+
+// --- test_concurrent_run_skips (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_recent_pending_run_not_stale (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_stale_pending_cleared_and_proceeds (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @complexity 1
+ */
+
+// --- test_multiple_stale_pending_all_cleared (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @complexity 1
+ */
+
+// --- docker.backend.Dockerfile (docker/backend.Dockerfile)
+/**!
+ * @brief Backend Dockerfile — Python 3.11 slim + Playwright + entrypoint с установкой сертификатов.
+ * @complexity 3
+ * @layer Infrastructure
+ * @post Образ с backend API, Playwright, entrypoint для bootstrap admin и установки сертификатов.
+ * @pre Docker builder context — корень проекта. backend/ и docker/ доступны.
+ */
+
+// --- docker.backend.entrypoint (docker/backend.entrypoint.sh)
+/**!
+ * @brief Container entrypoint — установка корп. сертификатов, Playwright (lazy), bootstrap admin,
+ * @complexity 4
+ */
+
+// --- docker.backend.entrypoint.install_certificates (docker/backend.entrypoint.sh)
+/**!
+ * @brief Устанавливает корпоративные .crt сертификаты из CERTS_PATH в системное хранилище Debian.
+ * @complexity 3
+ * @pre CERTS_PATH указывает на директорию (может быть пуста или не существовать).
+ */
+
+// --- docker.backend.entrypoint.bootstrap_admin (docker/backend.entrypoint.sh)
+/**!
+ * @brief Создание admin пользователя из переменных окружения (идемпотентно).
+ * @complexity 2
+ * @layer Infrastructure
+ * @post Admin пользователь создан в БД (если ещё не существовал).
+ * @pre INITIAL_ADMIN_CREATE=true, INITIAL_ADMIN_USERNAME и INITIAL_ADMIN_PASSWORD заданы.
+ */
+
+// --- docker.backend.entrypoint.install_playwright (docker/backend.entrypoint.sh)
+/**!
+ * @brief Lazy установка Playwright Chromium (~377 MB) при первом запуске.
+ * @complexity 2
+ * @layer Infrastructure
+ * @post Chromium установлен в PLAYWRIGHT_BROWSERS_PATH.
+ * @pre ~/.cache/ms-playwright доступен (можно закешировать volume).
+ */
+
+// --- docker.frontend.Dockerfile (docker/frontend.Dockerfile)
+/**!
+ * @brief Frontend Dockerfile — сборка SvelteKit (node:20) + nginx runtime с опциональным SSL.
+ * @complexity 3
+ * @layer Infrastructure
+ * @post nginx:alpine образ со статикой SvelteKit, entrypoint для выбора HTTP/SSL конфига.
+ * @pre Docker builder context — корень проекта. frontend/ и docker/ доступны.
+ */
+
+// --- docker.frontend.entrypoint (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Entrypoint для nginx-контейнера — установка корп. CA-сертификатов в Alpine,
+ * @complexity 3
+ */
+
+// --- docker.frontend.entrypoint.install_ca_certificates (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Устанавливает .crt файлы из /opt/certs в системное хранилище Alpine.
+ * @complexity 2
+ * @post Сертификаты скопированы в /usr/local/share/ca-certificates/ и добавлены в trust.
+ * @pre /opt/certs может быть пуст или не существовать.
+ */
+
+// --- docker.frontend.entrypoint.select_nginx_config (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Определяет, есть ли сертификаты для SSL, и копирует нужный nginx конфиг.
+ * @complexity 2
+ * @post Если есть оба файла — /etc/nginx/ssl/ создан, server.crt/key скопированы,
+ * @pre /opt/certs/server.crt и /opt/certs/server.key — опциональные SSL-сертификаты.
+ */
+
+// --- docker.nginx.ssl.conf (docker/nginx.ssl.conf)
+/**!
+ * @brief Nginx config с опциональным SSL — HTTP (порт 80) + HTTPS (порт 443).
+ * @complexity 3
+ */
+
+// --- AuthFixture (frontend/e2e/fixtures/auth.fixture.js)
+/**!
+ * @brief Playwright fixture for authenticated browser contexts.
+ * @complexity 2
+ * @ux_state LoginError -> Error banner visible on failed login.
+ */
+
+// --- GlobalSetup (frontend/e2e/fixtures/global-setup.js)
+/**!
+ * @brief Pre-flight check before any E2E tests run.
+ * @complexity 2
+ * @post Exits with 1 if either service is down, else sets ENV vars.
+ * @pre Backend and frontend must be reachable.
+ */
+
+// --- ApiHelper (frontend/e2e/helpers/api.helper.js)
+/**!
+ * @brief Helper for backend API calls in E2E tests (settings CRUD, etc.)
+ * @complexity 2
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::getToken (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiGet (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiPost (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiPut (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiDelete (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- run-enterprise-clean-e2e (frontend/e2e/run-enterprise-clean-e2e.sh)
+/**!
+ * @brief Enterprise Clean E2E Orchestrator — полный протокол тестирования пустого образа перед передачей.
+ * @complexity 5
+ */
+
+// --- EnterpriseCleanSetupE2E (frontend/e2e/tests/enterprise-clean-setup.e2e.js)
+/**!
+ * @brief Stage 1: E2E test for enterprise-clean empty image — first-run setup via StartupEnvironmentWizard.
+@@RATIONALE All 4 tests pass after fixing: (1) button ambiguity — zero-state page and wizard modal both have 'Начать настройку' button, resolved by scoping to wizard modal via .fixed.inset-0.z-50; (2) wizard detection — changed from waitForSelector('text=...') to getByText() with regex for locale-robust matching; (3) form fill — connections.* i18n keys missing in Docker build, switched to placeholder-based locators scoped within wizard; (4) settings navigation — use authPage fixture for consistent login
+@@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues
+ * @complexity 4
+ */
+
+// --- GitE2E (frontend/e2e/tests/git.e2e.js)
+/**!
+ * @brief E2E tests for Git integration — config CRUD, connection test.
+ * @complexity 3
+ * @ux_state ConnectionTested -> Success/failure toast feedback.
+ */
+
+// --- LiveProjectCheckE2E (frontend/e2e/tests/live-project-check.e2e.js)
+/**!
+ * @brief Stage 2: E2E test for live project verification — validates dashboard LLM analysis,
+ * @complexity 4
+ */
+
+// --- LoginE2E (frontend/e2e/tests/login.e2e.js)
+/**!
+ * @brief E2E tests for login/logout flow.
+ * @complexity 3
+ * @ux_state InvalidCredentials -> Error toast or message shown.
+ */
+
+// --- MigrationE2E (frontend/e2e/tests/migration.e2e.js)
+/**!
+ * @brief E2E tests for dataset/environment migration and sync.
+ * @complexity 3
+ * @ux_state MappingsLoaded -> Synchronized resources table populated.
+ */
+
+// --- SettingsE2E (frontend/e2e/tests/settings.e2e.js)
+/**!
+ * @brief E2E tests for Settings page — environments, LLM providers, Git config.
+ * @complexity 3
+ * @ux_state EnvironmentAdded -> New Superset env appears in list.
+ */
+
+// --- SmokeE2E (frontend/e2e/tests/smoke.e2e.js)
+/**!
+ * @brief Golden-path smoke test: login → settings → translate → git → verify.
+ * @complexity 4
+ * @rationale Single sequential test verifies the entire stack without per-test setup overhead.
+ * @ux_state FullCycle -> All key user journeys executed sequentially.
+ */
+
+// --- TranslationE2E (frontend/e2e/tests/translation.e2e.js)
+/**!
+ * @brief E2E tests for the translation job lifecycle: create → preview → accept → run.
+ * @complexity 3
+ * @ux_state JobRunning -> Run object created with PENDING status.
+ */
+
+// --- PlaywrightConfig (frontend/playwright.config.js)
+/**!
+ * @brief Playwright E2E test configuration for ss-tools frontend.
+ * @complexity 3
+ * @invariant All E2E tests run against a fully deployed stack (DB + backend + frontend).
+ * @ux_state ConfigLoaded -> Browser contexts are created with predefined env settings.
+ */
+
+// --- handleValidate:Function (frontend/src/components/DashboardGrid.svelte)
+/**!
+ * @brief Triggers dashboard validation task.
+ */
+
+// --- openGit:Function (frontend/src/components/DashboardGrid.svelte)
+/**!
+ * @brief Opens the Git management modal for a dashboard.
+ */
+
+// --- initializeForm:Function (frontend/src/components/DynamicForm.svelte)
+/**!
+ * @brief Initialize form data with default values from the schema.
+ * @post formData is initialized with default values or empty strings.
+ * @pre schema is provided and contains properties.
+ */
+
+// --- Footer (frontend/src/components/Footer.svelte)
+/**!
+ * @brief Displays the application footer with copyright information.
+ * @complexity 3
+ * @layer UI
+ * @semantics footer, layout, copyright
+ */
+
+// --- updateMapping:Function (frontend/src/components/MappingTable.svelte)
+/**!
+ * @brief Updates a mapping for a specific source database.
+ * @post Parent callback receives normalized mapping payload.
+ * @pre sourceUuid and targetUuid are provided.
+ */
+
+// --- getSuggestion:Function (frontend/src/components/MappingTable.svelte)
+/**!
+ * @brief Finds a suggestion for a source database.
+ * @post Returns matching suggestion object or undefined.
+ * @pre sourceUuid is provided.
+ */
+
+// --- MissingMappingModal (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Prompts the user to provide a database mapping when one is missing during migration.
+ * @complexity 3
+ * @invariant Modal blocks migration progress until resolved or cancelled.
+ * @layer Feature
+ * @semantics modal, mapping, prompt, migration
+ */
+
+// --- resolve:Function (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Resolves the missing mapping via callback prop.
+ * @post Parent callback receives mapping payload and modal closes.
+ * @pre selectedTargetUuid must be set.
+ */
+
+// --- cancel:Function (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Cancels the mapping resolution modal.
+ * @post Parent cancel callback is invoked and modal is hidden.
+ * @pre Modal is open.
+ */
+
+// --- Navbar (frontend/src/components/Navbar.svelte)
+/**!
+ * @brief Main navigation bar for the application.
+ * @complexity 3
+ * @layer UI
+ * @semantics navbar, navigation, header, layout
+ * @ux_state Authenticated -> User identity and logout action are rendered.
+ */
+
+// --- PasswordPrompt (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief A modal component to prompt the user for database passwords when a migration task is paused.
+ * @complexity 3
+ * @layer UI
+ * @semantics password, prompt, modal, input, security
+ */
+
+// --- handleSubmit:Function (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief Validates and forwards passwords to resume the task.
+ * @post Parent resume callback receives passwords payload.
+ * @pre All database passwords must be entered.
+ */
+
+// --- handleCancel:Function (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief Cancels the password prompt.
+ * @post Parent cancel callback is invoked and show is set to false.
+ * @pre Modal is open.
+ */
+
+// --- handleSort:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Toggles sort direction or changes sort column.
+ * @post sortColumn and sortDirection state updated.
+ * @pre column name is provided.
+ */
+
+// --- handleSelectionChange:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Handles individual checkbox changes.
+ * @post selectedIds array updated.
+ * @pre dashboard ID and checked status provided.
+ */
+
+// --- handleSelectAll:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Handles select all checkbox.
+ * @post selectedIds array updated for all paginated items.
+ * @pre checked status provided.
+ */
+
+// --- goToPage:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Changes current page.
+ * @post currentPage state updated if within valid range.
+ * @pre page index is provided.
+ */
+
+// --- getRepositoryStatusToken:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns normalized repository status token for a dashboard.
+ * @post Returns one of loading|no_repo|synced|changes|behind_remote|ahead_remote|diverged|error.
+ * @pre Dashboard exists.
+ */
+
+// --- isRepositoryReady:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Determines whether git actions can run for a dashboard.
+ */
+
+// --- invalidateRepositoryStatuses:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Marks dashboard statuses as loading so they are refetched.
+ */
+
+// --- resolveRepositoryStatusToken:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Converts git status payload into a stable UI status token.
+ */
+
+// --- loadRepositoryStatuses:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Hydrates repository status map for dashboards in repository mode.
+ */
+
+// --- runBulkGitAction:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Executes git action for selected dashboards with limited parallelism.
+ */
+
+// --- handleBulkSync:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkCommit:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkPull:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkPush:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkDelete:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Removes selected repositories from storage and binding table.
+ */
+
+// --- handleManageSelected:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager for exactly one selected dashboard.
+ */
+
+// --- resolveDashboardRef:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Resolves dashboard slug from payload fields.
+ * @post Returns slug string or null if unavailable.
+ * @pre Dashboard metadata is provided.
+ */
+
+// --- openGitManagerForDashboard:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager for provided dashboard metadata.
+ */
+
+// --- handleInitializeRepositories:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager from bulk actions to initialize selected repository.
+ */
+
+// --- getSortStatusValue:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns sort value for status column based on mode.
+ */
+
+// --- getStatusLabel:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns localized label for status column.
+ */
+
+// --- getStatusBadgeClass:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns badge style for status column.
+ */
+
+// --- TaskHistory (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Displays a list of recent tasks with their status and allows selecting them for viewing logs.
+ * @complexity 3
+ * @layer UI
+ * @semantics task, history, list, status, monitoring
+ * @type {string | undefined} — if set, only shows tasks with this plugin_id (e.g. "superset-migration")
+ */
+
+// --- getStatusColor:Function (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Returns the CSS color class for a given task status.
+ * @post Returns tailwind color class string.
+ * @pre status string is provided.
+ */
+
+// --- onDestroy:Function (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Cleans up the polling interval when the component is destroyed.
+ * @post Polling interval is cleared.
+ * @pre Component is being destroyed.
+ */
+
+// --- TaskList (frontend/src/components/TaskList.svelte)
+/**!
+ * @brief Displays a list of tasks with their status and execution details.
+ * @complexity 3
+ * @layer Component
+ * @semantics tasks, list, status, history
+ */
+
+// --- handleTaskClick:Function (frontend/src/components/TaskList.svelte)
+/**!
+ * @brief Forwards the selected task through a callback prop.
+ * @post Parent callback receives task id and task payload.
+ * @pre taskId is provided.
+ */
+
+// --- TaskLogViewer (frontend/src/components/TaskLogViewer.svelte)
+/**!
+ * @brief Displays task logs inline (in drawer) or as modal. Merges real-time WebSocket logs with polled historical logs.
+ * @complexity 3
+ * @invariant Real-time logs are always appended without duplicates.
+ * @layer UI
+ * @semantics task, log, viewer, inline, realtime
+ * @ux_state Loading -> Default
+ */
+
+// --- connect:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Establishes WebSocket connection with exponential backoff and filter parameters.
+ * @post WebSocket instance created and listeners attached.
+ * @pre selectedTask must be set in the store.
+ */
+
+// --- handleFilterChange:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Handles filter changes and reconnects WebSocket with new parameters.
+ * @post WebSocket reconnected with new filter parameters, logs cleared.
+ * @pre event.detail contains source and level filter values.
+ */
+
+// --- fetchTargetDatabases:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Fetches available databases from target environment for mapping.
+ * @post targetDatabases array populated with available databases.
+ * @pre selectedTask must have to_env parameter set.
+ */
+
+// --- handleMappingResolve:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Resolves missing database mapping and continues migration.
+ * @post Mapping created in backend, task resumed with resolution params.
+ * @pre event.detail contains sourceDbUuid, targetDbUuid, targetDbName.
+ */
+
+// --- handlePasswordResume:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Submits passwords and resumes paused migration task.
+ * @post Task resumed with passwords, connection status restored to connected.
+ * @pre event.detail contains passwords object.
+ */
+
+// --- startDataTimeout:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Starts timeout timer to detect idle connection.
+ * @post waitingForData set to true after 5 seconds if no data received.
+ * @pre connectionStatus is 'connected'.
+ */
+
+// --- resetDataTimeout:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Resets data timeout timer when new data arrives.
+ * @post waitingForData reset to false, new timeout started.
+ * @pre dataTimeout must be set.
+ */
+
+// --- Toast (frontend/src/components/Toast.svelte)
+/**!
+ * @brief Displays transient notifications (toasts) in the bottom-right corner.
+ * @complexity 3
+ * @layer UI
+ * @semantics toast, notification, feedback, ui
+ * @ux_state Visible -> Active toast items render with type-specific emphasis.
+ */
+
+// --- TaskLogViewerTest:Module (frontend/src/components/__tests__/task_log_viewer.test.js)
+/**!
+ * @brief Unit tests for TaskLogViewer component by mounting it and observing the DOM.
+ * @invariant Duplicate logs are never appended. Polling only active for in-progress tasks.
+ * @layer UI (Tests)
+ * @semantics tests, task-log, viewer, mount, components
+ * @test_contract TaskLogViewerPropsAndLogStream -> RenderedLogTimeline
+ * @test_edge duplicate_realtime_entry -> Existing log is not duplicated when repeated in realtime stream.
+ * @test_fixture valid_viewer -> INLINE_JSON
+ * @test_invariant no_duplicate_log_rows -> VERIFIED_BY: [historical_and_realtime_merge, duplicate_realtime_entry]
+ * @test_scenario historical_and_realtime_merge -> Historical logs render and realtime logs append without duplication.
+ */
+
+// --- verifySessionAndAccess:Function (frontend/src/components/auth/ProtectedRoute.svelte)
+/**!
+ * @brief Validates session and optional permission gate before allowing protected content render.
+ * @data_contract Input[AuthState, requiredPermission, fallbackPath] -> Output[RouteDecision{login_redirect|fallback_redirect|grant}]
+ * @post hasRouteAccess=true only when user identity is valid and permission check (if provided) passes.
+ * @pre auth store is initialized and can provide token/user state; navigation is available.
+ * @side_effect Mutates auth loading/user state, performs API I/O to /auth/me, and may redirect.
+ */
+
+// --- handleCreateBackup:Function (frontend/src/components/backups/BackupManager.svelte)
+/**!
+ * @brief Triggers a new backup task for the selected environment.
+ * @post A new task is created on the backend.
+ * @pre selectedEnvId must be a valid environment ID.
+ * @return {Promise}
+ * @side_effect Dispatches a toast notification.
+ */
+
+// --- handleUpdateSchedule:Function (frontend/src/components/backups/BackupManager.svelte)
+/**!
+ * @brief Updates the backup schedule for the selected environment.
+ * @post Environment config is updated on the backend.
+ * @pre selectedEnvId must be set.
+ */
+
+// --- loadBranches:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Загружает список веток для дашборда.
+ * @post branches обновлен.
+ * @pre dashboardId is provided.
+ */
+
+// --- handleSelect:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Handles branch selection from dropdown.
+ * @post handleCheckout is called with selected branch.
+ * @pre event contains branch name.
+ */
+
+// --- handleCheckout:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Переключает текущую ветку.
+ * @param {string} branchName - Имя ветки.
+ * @post currentBranch обновлен, родительский callback вызван.
+ */
+
+// --- handleCreate:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Создает новую ветку.
+ * @post Новая ветка создана и загружена; showCreate reset.
+ * @pre newBranchName is not empty.
+ */
+
+// --- loadHistory:Function (frontend/src/components/git/CommitHistory.svelte)
+/**!
+ * @brief Fetch commit history from the backend.
+ * @post history state is updated.
+ * @pre dashboardId is valid.
+ */
+
+// --- handleGenerateMessage:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Generates a commit message using LLM.
+ */
+
+// --- loadStatus:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Загружает текущий статус репозитория и diff.
+ * @pre dashboardId должен быть валидным.
+ */
+
+// --- handleCommit:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Создает коммит с указанным сообщением.
+ * @post Коммит создан и модальное окно закрыто.
+ * @pre message не должно быть пустым.
+ */
+
+// --- loadStatus:Watcher (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ */
+
+// --- normalizeEnvStage:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Normalize environment stage with legacy production fallback.
+ * @post Returns DEV/PREPROD/PROD.
+ */
+
+// --- resolveEnvUrl:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Resolve environment URL from consolidated or git-specific payload shape.
+ * @post Returns stable URL string.
+ */
+
+// --- loadEnvironments:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Fetch available environments from API.
+ * @post environments state is populated.
+ * @side_effect Updates environments state.
+ */
+
+// --- handleDeploy:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Trigger deployment to selected environment.
+ * @post Deploy request finishes and modal closes on success.
+ * @pre selectedEnv must be set.
+ * @side_effect Triggers API call, closes modal, shows toast.
+ */
+
+// --- GitInitPanel (frontend/src/components/git/GitInitPanel.svelte)
+/**!
+ * @brief Git initialization panel: select config, create remote repo, init local repo.
+ * @complexity 3
+ * @layer UI
+ * @ux_state Loading -> Buttons disabled, spinner visible.
+ */
+
+// --- GitManager (frontend/src/components/git/GitManager.svelte)
+/**!
+ * @brief Central Git management UI — thin shell delegating to sub-panels and composable handlers.
+ * @complexity 4
+ * @layer UI
+ * @rationale Decomposed from 1220→~370 lines by extracting sub-panels, utils, and composable handlers per INV_7.
+ * @rejected Keeping all logic inline was rejected because it exceeded 150-line contract limit.
+ * @ux_state MergeDialog -> Recovery overlay.
+ */
+
+// --- GitMergeDialog (frontend/src/components/git/GitMergeDialog.svelte)
+/**!
+ * @brief Unfinished merge recovery dialog: abort, continue, resolve conflicts.
+ * @complexity 3
+ * @layer UI
+ * @ux_state Loading -> Recovery state loading spinner.
+ */
+
+// --- GitOperationsPanel (frontend/src/components/git/GitOperationsPanel.svelte)
+/**!
+ * @brief Git server operations panel: pull, push, and deploy actions.
+ * @complexity 2
+ * @layer UI
+ */
+
+// --- GitReleasePanel (frontend/src/components/git/GitReleasePanel.svelte)
+/**!
+ * @brief Git release panel: promote branches via MR or direct mode.
+ * @complexity 3
+ * @layer UI
+ * @ux_state Advanced -> Expandable branch/reason settings.
+ */
+
+// --- GitWorkspacePanel (frontend/src/components/git/GitWorkspacePanel.svelte)
+/**!
+ * @brief Git workspace panel: sync, commit message input, diff viewer, commit action.
+ * @complexity 3
+ * @layer UI
+ * @ux_state Error -> Toast on failure.
+ */
+
+// --- GitManagerUnfinishedMergeIntegrationTest:Module (frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js)
+/**!
+ * @brief Protect unresolved-merge dialog contract in GitManager pull flow.
+ * @semantics git-manager, unfinished-merge, dialog, integration-test
+ */
+
+// --- UseGitManager (frontend/src/components/git/useGitManager.js)
+/**!
+ * @brief Composable for GitManager handler functions — extracted to reduce component size per INV_7.
+ * @complexity 3
+ * @rationale Extracted handler logic from GitManager (1220→~350 lines) to meet INV_7 <150 line contract limit.
+ */
+
+// --- DocPreview (frontend/src/components/llm/DocPreview.svelte)
+/**!
+ * @brief UI component for previewing generated dataset documentation before saving.
+ * @complexity 3
+ * @layer UI
+ * @type {Object}
+ * @ux_state Loading -> Default
+ */
+
+// --- ProviderConfig (frontend/src/components/llm/ProviderConfig.svelte)
+/**!
+ * @brief UI form for managing LLM provider configurations.
+ * @complexity 3
+ * @layer UI
+ * @ux_state Loading -> Default
+ */
+
+// --- ValidationReport (frontend/src/components/llm/ValidationReport.svelte)
+/**!
+ * @brief Displays the results of an LLM-based dashboard validation task.
+ * @complexity 3
+ * @layer UI
+ */
+
+// --- provider_config_edit_contract_tests:Function (frontend/src/components/llm/__tests__/provider_config.integration.test.js)
+/**!
+ * @brief Validate edit and delete handler wiring plus normalized edit form state mapping.
+ * @post Contract checks ensure edit click cannot degrade into no-op flow.
+ * @pre ProviderConfig component source exists in expected path.
+ */
+
+// --- isDirectory:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Checks if a file object represents a directory.
+ * @param {Object} file - The file object to check.
+ * @post Returns boolean.
+ * @pre file object has mime_type property.
+ * @return {boolean} True if it's a directory, false otherwise.
+ */
+
+// --- formatSize:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Formats file size in bytes into a human-readable string.
+ * @param {number} bytes - The size in bytes.
+ * @post Returns formatted string.
+ * @pre bytes is a number.
+ * @return {string} Formatted size (e.g., "1.2 MB").
+ */
+
+// --- formatDate:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Formats an ISO date string into a localized readable format.
+ * @param {string} dateStr - The date string to format.
+ * @post Returns localized string.
+ * @pre dateStr is a valid date string.
+ * @return {string} Localized date and time.
+ */
+
+// --- handleDownload:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Downloads selected file through authenticated API request.
+ * @post Browser download starts or user sees toast on failure.
+ * @pre file is a non-directory storage entry with category/path.
+ */
+
+// --- handleUpload:Function (frontend/src/components/storage/FileUpload.svelte)
+/**!
+ * @brief Handles the file upload process.
+ * @post The file is uploaded to the server and a success toast is shown.
+ * @pre A file must be selected in the file input.
+ */
+
+// --- handleDrop:Function (frontend/src/components/storage/FileUpload.svelte)
+/**!
+ * @brief Handles the file drop event for drag-and-drop.
+ * @param {DragEvent} event - The drop event.
+ */
+
+// --- LogEntryRow (frontend/src/components/tasks/LogEntryRow.svelte)
+/**!
+ * @brief Renders a single log entry with stacked layout optimized for narrow drawer panels.
+ * @complexity 3
+ * @layer UI
+ * @semantics log, entry, row, ui
+ * @type {Object} log - The log entry object
+ * @ux_state Idle -> Displays log entry with color-coded level and source badges.
+ */
+
+// --- formatTime:Function (frontend/src/components/tasks/LogEntryRow.svelte)
+/**!
+ * @brief Format ISO timestamp to HH:MM:SS
+ */
+
+// --- LogFilterBar (frontend/src/components/tasks/LogFilterBar.svelte)
+/**!
+ * @brief Compact filter toolbar for logs — level, source, and text search in a single dense row.
+ * @complexity 3
+ * @layer UI
+ * @semantics log, filter, ui
+ * @ux_state Active -> Filters applied, clear button visible
+ */
+
+// --- TaskLogPanel (frontend/src/components/tasks/TaskLogPanel.svelte)
+/**!
+ * @brief Combines log filtering and display into a single cohesive light-themed panel.
+ * @complexity 3
+ * @invariant Must always display logs in chronological order and respect auto-scroll preference.
+ * @layer UI
+ * @semantics task, log, panel, filter, list
+ * @ux_state AutoScroll -> Automatically scrolls to bottom on new logs
+ */
+
+// --- TaskResultPanel (frontend/src/components/tasks/TaskResultPanel.svelte)
+/**!
+ * @brief Displays formatted task result summary with status badges and result details.
+ * @complexity 2
+ * @layer UI
+ * @ux_state Loaded -> Task result displayed with status color coding.
+ */
+
+// --- handleRunDebug:Function (frontend/src/components/tools/DebugTool.svelte)
+/**!
+ * @brief Triggers the debug task.
+ * @post Task is started and polling begins.
+ * @pre Required fields are selected.
+ * @return {Promise}
+ */
+
+// --- startPolling:Function (frontend/src/components/tools/DebugTool.svelte)
+/**!
+ * @brief Polls for task completion.
+ * @param {string} taskId - ID of the task.
+ * @post Polls until success/failure.
+ * @pre Task ID is valid.
+ * @return {void}
+ */
+
+// --- MapperTool (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief UI component for mapping dataset column verbose names using Superset SQL Lab or Excel files.
+ * @complexity 3
+ * @layer UI
+ * @semantics mapper, tool, dataset, sqllab, excel
+ */
+
+// --- fetchData:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Fetches environments.
+ * @post envs array is populated.
+ * @pre None.
+ */
+
+// --- handleRunMapper:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Triggers the MapperPlugin task via new sqllab/excel sources.
+ * @post Mapper task is started and selectedTask is updated.
+ * @pre selectedEnv and datasetId are set; source-specific fields are valid.
+ */
+
+// --- handleGenerateDocs:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Triggers the LLM Documentation task.
+ * @post Documentation task is started.
+ * @pre selectedEnv and datasetId are set.
+ */
+
+// --- Counter (frontend/src/lib/Counter.svelte)
+/**!
+ * @brief Simple counter demo component
+ * @complexity 2
+ * @layer UI
+ * @ux_state Incremented -> Count increases immediately after button activation.
+ */
+
+// --- ApiModule (frontend/src/lib/api.js)
+/**!
+ * @brief Handles all communication with the backend API via fetch wrappers with auth, error normalization, and toast feedback.
+ * @complexity 3
+ * @type {any}
+ */
+
+// --- ReportsApiTest (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+ * @complexity 3
+ */
+
+// --- ReportsApiTest:Module (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+ * @invariant Pure functions produce deterministic output. Async wrappers propagate structured errors.
+ * @layer Tests
+ * @semantics tests, reports, api-client, query-string, error-normalization
+ */
+
+// --- TestBuildReportQueryString:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate query string construction from filter options.
+ * @post Correct URLSearchParams string produced.
+ * @pre Options object with various filter fields.
+ */
+
+// --- TestNormalizeApiError:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate error normalization for UI-state mapping.
+ * @post Always returns {message, code, retryable} object.
+ * @pre Various error types (Error, string, object).
+ */
+
+// --- TestGetReportsAsync:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate getReports and getReportDetail with mocked api.fetchApi.
+ * @post Functions call correct endpoints and propagate results/errors.
+ * @pre api.fetchApi is mocked via vi.mock.
+ */
+
+// --- AssistantApi (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, conversation management, and history retrieval.
+ * @complexity 3
+ */
+
+// --- AssistantApi:Module (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, and history retrieval.
+ * @invariant All assistant requests must use requestApi wrapper (no native fetch).
+ * @layer API
+ * @semantics assistant, api, client, chat, confirmation
+ */
+
+// --- sendAssistantMessage:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Send a user message to assistant orchestrator endpoint.
+ * @post Returns assistant response object with deterministic state.
+ * @pre payload.message is a non-empty string.
+ */
+
+// --- buildAssistantSeedMessage:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Compose visible assistant seed text from context label and prompt body.
+ * @post Returns trimmed seed message string for prefilled input.
+ * @pre prompt contains the user-visible request.
+ */
+
+// --- confirmAssistantOperation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Confirm a pending risky assistant operation.
+ * @post Returns execution response (started/success/failed).
+ * @pre confirmationId references an existing pending token.
+ */
+
+// --- cancelAssistantOperation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Cancel a pending risky assistant operation.
+ * @post Operation is cancelled and cannot be executed by this token.
+ * @pre confirmationId references an existing pending token.
+ */
+
+// --- getAssistantHistory:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Retrieve paginated assistant conversation history.
+ * @post Returns a paginated payload with history items.
+ * @pre page/pageSize are positive integers.
+ */
+
+// --- getAssistantConversations:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Retrieve paginated conversation list for assistant sidebar/history switcher.
+ * @post Returns paginated conversation summaries.
+ * @pre page/pageSize are positive integers.
+ */
+
+// --- deleteAssistantConversation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Soft-delete or hard-delete a conversation.
+ * @post Returns success status.
+ * @pre conversationId string is provided.
+ */
+
+// --- DatasetReviewApi (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and session DTO normalization.
+ * @complexity 3
+ */
+
+// --- DatasetReviewApi:Module (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Provide shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and refreshed session DTO normalization.
+ * @layer API
+ * @semantics dataset-review, api, session-version, headers, conflict-handling
+ */
+
+// --- buildDatasetReviewRequestOptions:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Attach optimistic-lock session version header when the current version is known.
+ * @post Returns requestApi-compatible options object.
+ * @pre sessionVersion may be null when no loaded session version exists yet.
+ */
+
+// --- requestDatasetReviewApi:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Proxy dataset review mutations through requestApi with optional optimistic-lock headers.
+ * @post Executes requestApi with X-Session-Version only when a session version is known.
+ * @pre endpoint and method are valid requestApi inputs.
+ */
+
+// --- isDatasetReviewConflictError:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Detect optimistic-lock conflicts from dataset review mutations.
+ * @post Returns true when the mutation failed with 409 conflict semantics.
+ * @pre error may be null or a normalized API error.
+ */
+
+// --- getDatasetReviewConflictMessage:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Return explicit 409-style guidance for stale dataset review mutations.
+ * @post Returns a user-facing conflict message string.
+ * @pre error may be null or a normalized API error.
+ */
+
+// --- extractDatasetReviewVersion:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Resolve the latest session version from refreshed DTO fragments.
+ * @post Returns the newest known session version or null.
+ * @pre payload may be a session summary, a detail payload, or a mutation fragment.
+ */
+
+// --- normalizeDatasetReviewDetail:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Normalize refreshed session-detail DTOs into the legacy route-friendly workspace shape.
+ * @post Returns a shape with flattened summary fields plus refreshed collections and version metadata.
+ * @pre detail may already be legacy-flat or refreshed with nested session/session_version fields.
+ */
+
+// --- MaintenanceApi (frontend/src/lib/api/maintenance.js)
+/**!
+ * @brief API client for Maintenance Banner endpoints. Uses requestApi for all calls.
+ * @complexity 2
+ * @layer Frontend
+ */
+
+// --- frontend/src/lib/api/maintenance.js::startMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::endMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::endAllMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::getSettings (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::updateSettings (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::listEvents (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::listDashboardBanners (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- ReportsApi (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Wrapper-based reports API client for list/detail retrieval through the shared API wrapper.
+ * @complexity 4
+ * @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+ * @pre Shared API wrapper is configured for the current frontend auth/session context.
+ * @side_effect Performs authenticated report HTTP requests through the shared API wrapper.
+ */
+
+// --- ReportsApi:Module (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Wrapper-based reports API client for list/detail retrieval without direct native fetch usage.
+ * @invariant Uses existing api wrapper methods and returns structured errors for UI-state mapping.
+ * @layer Infra
+ * @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+ * @pre Shared API wrapper is configured for the current frontend auth/session context.
+ * @semantics frontend, api_client, reports, wrapper
+ * @side_effect Performs authenticated report HTTP requests through the shared API wrapper.
+ */
+
+// --- buildReportQueryString:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Build query string for reports list endpoint from filter options.
+ * @post Returns URL query string without leading '?'.
+ * @pre options is an object with optional report query fields.
+ */
+
+// --- normalizeApiError:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Convert unknown API exceptions into deterministic UI-consumable error objects.
+ * @post Returns structured error object.
+ * @pre error may be Error/string/object.
+ */
+
+// --- getReports:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Fetch unified report list using existing request wrapper.
+ * @post Returns parsed payload or structured error for UI-state mapping.
+ * @pre valid auth context for protected endpoint.
+ * @test_contract GetReportsApi ->
+ */
+
+// --- getReportDetail:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Fetch one report detail by report_id.
+ * @post Returns parsed detail payload or structured error object.
+ * @pre reportId is non-empty string; valid auth context.
+ */
+
+// --- TranslateApi (frontend/src/lib/api/translate.js)
+/**!
+ * @brief Barrel module re-exporting all translate API functions from domain-split modules.
+ * @complexity 2
+ * @rationale Decomposed from 664->~30 lines by splitting into domain modules per INV_7.
+ * @rejected Keeping all APIs in one file was rejected because it exceeded the 400-line module limit.
+ */
+
+// --- TargetSchemaApiTest (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief Unit tests for checkTargetTableSchema API client fetch wrapper.
+ * @complexity 2
+ * @layer Tests
+ * @test_contract checkTargetTableSchema -> returns schema validation result with all fields
+ * @test_edge success_response -> Returns parsed response with all fields
+ */
+
+// --- test_success (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief Happy path — API returns full validation result.
+ */
+
+// --- test_api_error (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief API error returns fallback response with error message.
+ */
+
+// --- test_error_string_fallback (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief String error is captured as message.
+ */
+
+// --- TranslateCorrectionsApi (frontend/src/lib/api/translate/corrections.js)
+/**!
+ * @brief API client for translation corrections — inline edits, dictionary submission, bulk find-and-replace, CSV download.
+ * @complexity 2
+ */
+
+// --- TranslateDatasourcesApi (frontend/src/lib/api/translate/datasources.js)
+/**!
+ * @brief API client for translation datasources — column fetching, preview, row-level review actions.
+ * @complexity 2
+ */
+
+// --- TranslateDictionariesApi (frontend/src/lib/api/translate/dictionaries.js)
+/**!
+ * @brief API client for translation dictionary CRUD — list, create, update, delete, entries, import.
+ * @complexity 2
+ */
+
+// --- TranslateJobsApi (frontend/src/lib/api/translate/jobs.js)
+/**!
+ * @brief API client for translation job CRUD — list, create, update, delete, duplicate.
+ * @complexity 2
+ */
+
+// --- TranslateRunsApi (frontend/src/lib/api/translate/runs.js)
+/**!
+ * @brief API client for translation run control — trigger, status, history, records, retry, cancel, metrics.
+ * @complexity 2
+ */
+
+// --- TranslateSchedulesApi (frontend/src/lib/api/translate/schedules.js)
+/**!
+ * @brief API client for translation job scheduling — CRUD, enable/disable, next executions.
+ * @complexity 2
+ */
+
+// --- TranslateTargetSchemaApi (frontend/src/lib/api/translate/target-schema.js)
+/**!
+ * @brief API client for target table schema validation.
+ * @complexity 1
+ */
+
+// --- frontend/src/lib/api/translate/target-schema.js::checkTargetTableSchema (frontend/src/lib/api/translate/target-schema.js)
+/**!
+ */
+
+// --- ValidationApi (frontend/src/lib/api/validation.js)
+/**!
+ * @brief API client functions for the Validation section — tasks and runs CRUD.
+ * @complexity 2
+ * @rationale Centralized API module for all validation endpoints — single import point for pages, consistent error handling through shared fetchApi/postApi/deleteApi wrappers, and easy mocking in tests.
+ * @rejected Inline fetch calls in each page rejected — would duplicate base URL construction and auth header logic; centralized module enables consistent error handling and simplifies test mocking.
+ */
+
+// --- buildParams:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @brief Build URLSearchParams from a params object, skipping null/undefined/empty values.
+ * @complexity 1
+ * @param {Record} params
+ */
+
+// --- frontend/src/lib/api/validation.js::buildParams (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchTasks (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- createTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {Record} data
+ */
+
+// --- frontend/src/lib/api/validation.js::createTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- updateTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id @param {Record} data
+ */
+
+// --- frontend/src/lib/api/validation.js::updateTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- deleteTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id @param {boolean} [deleteRuns]
+ */
+
+// --- frontend/src/lib/api/validation.js::deleteTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- triggerRun:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::triggerRun (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- duplicateTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::duplicateTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchRuns:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {{ task_id?: string, dashboard_id?: string, environment_id?: string, status?: string, date_from?: string, date_to?: string, page?: number, page_size?: number }} [params]
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchRuns (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchRunDetail:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchRunDetail (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- deleteRun:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @complexity 1
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::deleteRun (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- PermissionsTest (frontend/src/lib/auth/__tests__/permissions.test.js)
+/**!
+ * @brief Verifies frontend RBAC permission parsing and access checks.
+ * @complexity 3
+ */
+
+// --- PermissionsTest:Module (frontend/src/lib/auth/__tests__/permissions.test.js)
+/**!
+ * @brief Verifies frontend RBAC permission parsing and access checks.
+ * @layer UI (Tests)
+ * @semantics tests, auth, permissions, rbac
+ */
+
+// --- PermissionsModule (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Shared frontend RBAC utilities for route guards, permission checks, and menu visibility based on user roles.
+ * @complexity 3
+ */
+
+// --- Permissions:Module (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Shared frontend RBAC utilities for route guards and menu visibility.
+ * @invariant Admin role always bypasses explicit permission checks.
+ * @layer Domain
+ * @semantics auth, permissions, rbac, roles
+ */
+
+// --- normalizePermissionRequirement:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Convert permission requirement string to canonical resource/action tuple.
+ * @post Returns normalized object with action in uppercase.
+ * @pre Permission can be "resource" or "resource:ACTION" where resource itself may contain ":".
+ */
+
+// --- isAdminUser:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Determine whether user has Admin role.
+ * @post Returns true when at least one role name equals "Admin" (case-insensitive).
+ * @pre user can be null or partially populated.
+ */
+
+// --- hasPermission:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Check if user has a required resource/action permission.
+ * @post Returns true when requirement is empty, user is admin, or matching permission exists.
+ * @pre user contains roles with permissions from /api/auth/me payload.
+ */
+
+// --- AuthStore (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Manages the global authentication state including JWT token, user profile, and login/logout lifecycle.
+ * @complexity 3
+ * @ux_state Unauthenticated -> No valid session, login required
+ */
+
+// --- authStore:Store (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Manages the global authentication state on the frontend.
+ * @layer Feature
+ * @semantics auth, store, svelte, jwt, session
+ */
+
+// --- AuthState:Interface (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Defines the structure of the authentication state.
+ */
+
+// --- frontend/src/lib/auth/store.ts::AuthState (frontend/src/lib/auth/store.ts)
+/**!
+ */
+
+// --- createAuthStore:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Creates and configures the auth store with helper methods.
+ * @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+ * @pre No preconditions - initialization function.
+ * @return {Writable}
+ */
+
+// --- frontend/src/lib/auth/store.ts::createAuthStore (frontend/src/lib/auth/store.ts)
+/**!
+ * @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+ * @pre No preconditions - initialization function.
+ */
+
+// --- setToken:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Updates the store with a new JWT token.
+ * @param {string} token - The JWT access token.
+ * @post Store updated with new token, isAuthenticated set to true.
+ * @pre token must be a valid JWT string.
+ */
+
+// --- setUser:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Sets the current user profile data.
+ * @param {any} user - The user profile object.
+ * @post Store updated with user, isAuthenticated true, loading false.
+ * @pre User object must contain valid profile data.
+ */
+
+// --- logout:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Clears authentication state and storage.
+ * @post Auth token removed from localStorage, store reset to initial state.
+ * @pre User is currently authenticated.
+ */
+
+// --- setLoading:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Updates the loading state.
+ * @param {boolean} loading - Loading status.
+ * @post Store loading state updated.
+ * @pre None.
+ */
+
+// --- AssistantClarificationCard (frontend/src/lib/components/assistant/AssistantClarificationCard.svelte)
+/**!
+ * @brief Render the active dataset-review clarification queue inside AssistantChatPanel so users can answer, skip, defer, and resume questions without leaving the assistant workspace.
+ * @complexity 3
+ * @data_contract Input[{sessionId, disabled}] -> Output[{clarification_state|clarification_session|current_question|session}] via onupdated callback.
+ * @layer UI
+ * @post Clarification queue state is readable in-chat and answer mutations refresh the active question state without requiring a dedicated dialog.
+ * @pre sessionId belongs to the current dataset review workspace and the assistant drawer is open for session-scoped work.
+ * @semantics assistant, clarification, dataset-review, mixed-initiative, resumable
+ * @side_effect Reads and mutates clarification state through dataset orchestration APIs.
+ * @ux_feedback Save, skip, resume, and feedback results surface inline without hiding the queue context.
+ * @ux_reactivity Uses $props, $state, $derived, and $effect only; no legacy reactive syntax.
+ * @ux_recovery Users can resume the queue, provide a custom answer, or mark the item for expert review from the same assistant surface.
+ * @ux_state Completed -> No active question remains and resume plus feedback actions stay available.
+ */
+
+// --- readJson:Function (frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js)
+/**!
+ * @brief Read and parse JSON fixture file from disk.
+ * @post Returns parsed object representation.
+ * @pre filePath points to existing UTF-8 JSON file.
+ */
+
+// --- AssistantClarificationIntegrationTest:Module (frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js)
+/**!
+ * @brief Verify AssistantChatPanel hosts the resumable dataset-review clarification flow inside the assistant drawer and refreshes workspace session state after answering.
+ * @layer UI (Tests)
+ * @semantics assistant, clarification, integration-test, dataset-review, mixed-initiative
+ */
+
+// --- AssistantFirstMessageIntegrationTest:Module (frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js)
+/**!
+ * @brief Verify first optimistic user message stays visible while a new conversation request is pending.
+ * @invariant Starting a new conversation must not trigger history reload that overwrites the first local user message.
+ * @layer UI (Tests)
+ * @semantics assistant, integration-test, optimistic-message, conversation-race
+ */
+
+// --- assistant_first_message_tests:Function (frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js)
+/**!
+ * @brief Guard optimistic first-message UX against history reload race in new conversation flow.
+ * @post First user message remains visible before pending send request resolves.
+ * @pre Assistant panel renders with open state and mocked network dependencies.
+ */
+
+// --- CompiledSQLPreview (frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte)
+/**!
+ * @brief Present the exact Superset-generated compiled SQL preview, expose readiness or staleness clearly, and preserve readable recovery paths when preview generation fails.
+ * @complexity 3
+ * @data_contract Input -> Dataset review preview payload { sessionId, preview, previewState }; Output -> onupdated({ preview, preview_state }) route-shell refresh payload and onjump({ target }) recovery navigation signal.
+ * @layer UI
+ * @post Users can distinguish missing, pending, ready, stale, and error preview states and can trigger only Superset-backed preview generation.
+ * @pre Session id is available and preview state comes from the current ownership-scoped session detail payload.
+ * @semantics dataset-review, compiled-sql-preview, superset-preview, stale-state, diagnostics
+ * @side_effect Requests preview generation through dataset orchestration APIs and updates route shell preview state when Superset responds.
+ * @ux_feedback Preview refresh updates status pill, timestamps, and inline generation feedback.
+ * @ux_reactivity Uses $props, $state, and $derived only; no legacy reactive syntax.
+ * @ux_recovery Users can retry preview generation and jump back to mapping review when diagnostics point to execution-input issues.
+ * @ux_state Error -> Show readable Superset compilation diagnostics and preserve remediation action.
+ */
+
+// --- ExecutionMappingReview (frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte)
+/**!
+ * @brief Review imported-filter to template-variable mappings, surface effective values and blockers, and require explicit approval for warning-sensitive execution inputs before preview or launch.
+ * @complexity 3
+ * @data_contract Input -> Dataset review execution payload { sessionId, mappings[], importedFilters[], templateVariables[] }; Output -> onupdated({ mapping | mappings, preview_state }) route-shell refresh payload.
+ * @layer UI
+ * @post Users can review effective mapping values, approve warning-sensitive transformations, or manually override them while unresolved required-value blockers remain visible.
+ * @pre Session id, execution mappings, imported filters, and template variables belong to the current ownership-scoped session payload.
+ * @semantics dataset-review, execution-mapping, warning-approval, manual-override, required-values
+ * @side_effect Persists mapping approvals or manual overrides through dataset orchestration APIs and may invalidate the current preview truth for the route shell.
+ * @ux_feedback Mapping approvals and manual overrides expose inline success, saving, and error feedback per row.
+ * @ux_reactivity Uses $props, $state, and $derived only; no legacy reactive syntax.
+ * @ux_recovery Users can replace transformed values manually instead of approving them as-is and can retry failed mutations in place.
+ * @ux_state Approved -> All launch-sensitive mappings are approved or no explicit approval is required.
+ */
+
+// --- LaunchConfirmationPanel (frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte)
+/**!
+ * @brief Summarize final execution context, surface launch blockers explicitly, and confirm only a gate-complete SQL Lab launch request.
+ * @complexity 3
+ * @data_contract Input -> Dataset review launch payload { sessionId, session, findings[], mappings[], preview, previewState, latestRunContext }; Output -> onupdated({ launch_result, preview_state }) workspace refresh payload and onjump({ target }) remediation navigation signal.
+ * @layer UI
+ * @post Users can see why launch is blocked or confirm a run-ready launch with explicit SQL Lab handoff evidence.
+ * @pre Session detail, mappings, findings, preview state, and latest run context belong to the current ownership-scoped session payload.
+ * @semantics dataset-review, launch-confirmation, run-gates, sql-lab, audited-execution
+ * @side_effect Submits the launch request through dataset orchestration APIs and updates the workspace with returned run context state.
+ * @ux_feedback Launch button, blocker list, and success state all reflect current gate truth instead of generic confirmation copy.
+ * @ux_reactivity Uses $props, $state, and $derived only; no legacy reactive syntax.
+ * @ux_recovery Blocked launch state provides jump paths back to mapping review, preview generation, or validation remediation.
+ * @ux_state Submitted -> SQL Lab handoff and audited run context reference are shown after launch request succeeds.
+ */
+
+// --- SemanticLayerReview (frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte)
+/**!
+ * @brief Surface field-level semantic decisions with provenance, confidence, candidate acceptance, and manual override safeguards for US2 review flow.
+ * @complexity 3
+ * @data_contract Input -> Dataset review session detail { sessionId, fields[], semanticSources[] }; Output -> onupdated(updatedField | { fields: updatedFields }) refresh payload.
+ * @layer UI
+ * @post Users can review the current semantic value, accept a candidate, apply manual override, and lock or unlock field state without violating backend provenance rules.
+ * @pre Session id is available and semantic field entries come from the current ownership-scoped session detail payload.
+ * @semantics dataset-review, semantic-layer, candidate-review, manual-override, field-lock
+ * @side_effect Persists semantic field decisions, lock state, and optional thumbs feedback through dataset orchestration endpoints.
+ * @ux_feedback Save, lock, unlock, and feedback actions expose inline success or error state on the affected field.
+ * @ux_reactivity Uses $props, $state, and $derived only; no legacy reactive syntax.
+ * @ux_recovery Users can cancel local edits, unlock a manual override for re-review, or retry failed mutations in place.
+ * @ux_state Manual -> One field enters local draft mode and persists as locked manual override on save.
+ */
+
+// --- SourceIntakePanel (frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte)
+/**!
+ * @brief Collect initial dataset source input through Superset link paste or dataset selection entry paths.
+ * @complexity 3
+ * @layer UI
+ * @semantics dataset-review, intake, superset-link, dataset-selection, validation
+ * @ux_feedback Recognized links are acknowledged before deeper recovery finishes.
+ * @ux_reactivity Uses $props, $state, and $derived only; no legacy reactive syntax.
+ * @ux_recovery Users can correct invalid input in place without resetting the page.
+ * @ux_state Rejected -> Input error shown with corrective hint.
+ */
+
+// --- ValidationFindingsPanel (frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte)
+/**!
+ * @brief Present validation findings grouped by severity with explicit resolution and actionability signals.
+ * @complexity 3
+ * @layer UI
+ * @semantics dataset-review, findings, severity, readiness, actionability
+ * @ux_feedback Resolving or approving an item updates readiness state immediately.
+ * @ux_reactivity Uses $props and $derived only; no legacy reactive syntax.
+ * @ux_recovery Users can jump from a finding directly to the relevant remediation area.
+ * @ux_state Informational -> Low-priority findings are collapsed or secondary.
+ */
+
+// --- SourceIntakePanelUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js)
+/**!
+ * @brief Verify source intake entry paths, validation feedback, and submit payload behavior for US1.
+ * @layer UI
+ * @semantics dataset-review, source-intake, ux-tests, validation, recovery
+ * @test_contract SourceIntakePanelProps -> ObservableIntakeUX
+ * @test_edge external_fail -> Submit callback failure is rendered inline.
+ * @test_invariant intake_contract_remains_observable -> VERIFIED_BY: [invalid_superset_link_shows_rejected_state, recognized_superset_link_submits_payload, dataset_selection_mode_changes_cta]
+ * @test_scenario dataset_selection_mode_changes_cta -> Dataset selection path switches CTA and payload source kind.
+ * @ux_state Rejected -> Invalid source input remains local and exposes recovery guidance.
+ */
+
+// --- DatasetReviewUs2WorkspaceUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js)
+/**!
+ * @brief Verify US2 dataset review surfaces keep semantic review actionable, route clarification through AssistantChatPanel, and preserve explicit preview/mapping gates.
+ * @layer UI
+ * @semantics dataset-review, semantics, assistant, workspace, ux-tests, mapping-review
+ * @test_edge external_fail -> Failed request surfaces inline recovery message.
+ * @test_scenario mapping_review_marks_row_focused_and_requires_explicit_approval -> Mapping review keeps warning approvals explicit and highlightable.
+ */
+
+// --- DatasetReviewUs3UxTests:Module (frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js)
+/**!
+ * @brief Verify US3 mapping review, Superset preview, and launch confirmation UX contracts.
+ * @layer UI
+ * @semantics dataset-review, execution, mapping, preview, launch, ux-tests
+ * @test_contract Us3ExecutionProps -> ObservableExecutionUx
+ * @test_edge invalid_type -> Mixed values stringify without crashing.
+ * @test_invariant execution_gates_remain_visible -> VERIFIED_BY: [mapping_review_approves_warning_sensitive_row, preview_panel_requests_superset_compilation_and_renders_sql, launch_panel_blocks_then_submits_sql_lab_launch]
+ * @test_scenario launch_panel_blocks_then_submits_sql_lab_launch -> Launch lists gates first and shows audited handoff after success.
+ * @ux_state Blocked -> Launch panel lists blockers instead of allowing hidden bypass.
+ */
+
+// --- ValidationFindingsPanelUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js)
+/**!
+ * @brief Verify grouped findings visibility, empty state, and remediation jump behavior for US1.
+ * @layer UI
+ * @semantics dataset-review, findings, severity, jump, ux-tests
+ * @test_contract FindingsPanelProps -> ObservableFindingsUX
+ * @test_edge external_fail -> Jump callback remains optional.
+ * @test_invariant findings_groups_remain_actionable -> VERIFIED_BY: [blocking_warning_info_groups_render, jump_action_maps_area_to_workspace_target, empty_findings_show_success_state]
+ * @test_scenario empty_findings_show_success_state -> Empty list shows ready feedback.
+ * @ux_state Informational -> Informational notes stay readable without competing with blockers.
+ */
+
+// --- HealthMatrix (frontend/src/lib/components/health/HealthMatrix.svelte)
+/**!
+ * @brief Visual grid summary representing dashboard health status counts.
+ * @complexity 3
+ * @layer UI
+ * @type {{
+ * @ux_reactivity Uses $derived to keep aggregate totals consistent with the count props.
+ * @ux_state Error -> Displays an error message with a retry option.
+ */
+
+// --- PolicyForm (frontend/src/lib/components/health/PolicyForm.svelte)
+/**!
+ * @brief Form for creating and editing validation policies.
+ * @complexity 3
+ * @layer UI
+ * @post Form submission forwards the current draft to onSave and cancel delegates dismissal to the parent callback without mutating external state directly.
+ * @pre Parent provides callable onSave/onCancel handlers and an environments collection that may be empty but remains array-like.
+ * @type {{ policy: any, environments: any[], onSave: (p: any) => void, onCancel: () => void }}
+ * @ux_feedback Error -> Invalid field or submit failures keep the draft visible for correction.
+ * @ux_reactivity Uses $state for mutable form data and $derived values for window health checks.
+ * @ux_state Submitting -> Disables inputs and shows a loading state.
+ */
+
+// --- ScheduleAtAGlance (frontend/src/lib/components/health/ScheduleAtAGlance.svelte)
+/**!
+ * @brief Compact weekly schedule widget showing active validation tasks with day grid, time windows, and cross-referenced health status.
+ * @complexity 3
+ * @type {{ healthItems: Array<{task_id?: string, status: string}>, selectedEnvId?: string, appTimezone?: string }}
+ * @ux_feedback Click on policy row navigates to validation task edit page
+ * @ux_reactivity Props -> healthItems, selectedEnvId. LocalState -> tasks, loading, error
+ * @ux_state Error -> Compact error banner with retry
+ * @ux_test Ready -> {mock: fetchTasks returns 1 task, expected: grid + policy list + nextUpcoming}
+ */
+
+// --- Sidebar (frontend/src/lib/components/layout/Sidebar.svelte)
+/**!
+ * @brief Persistent left sidebar with grouped sections (Resources/Operations/System), expand/collapse, health indicators, RBAC filtering, profile footer.
+ * @complexity 4
+ * @layer UI
+ * @ux_feedback Profile footer shows user avatar and username.
+ * @ux_recovery Click outside on mobile closes overlay.
+ * @ux_state MobileOpen -> Overlay and sidebar visible until dismissed.
+ */
+
+// --- disconnectWebSocket:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Disconnects the active WebSocket connection
+ * @post ws is closed and set to null
+ * @pre ws may or may not be initialized
+ * @ux_state Loading -> Default
+ */
+
+// --- loadRecentTasks:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Load recent tasks for list mode display
+ * @post recentTasks array populated with task list
+ * @pre User is on task drawer or api is ready.
+ */
+
+// --- selectTask:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Select a task from list to view details
+ * @post drawer state updated to show task details
+ * @pre task is a valid task object
+ */
+
+// --- goBackToList:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Return to task list view from task details
+ * @post Drawer switches to list view and reloads tasks
+ * @pre Drawer is open and activeTaskId is set
+ * @ux_state Loading -> Default
+ */
+
+// --- SidebarNavigationTest:Module (frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js)
+/**!
+ * @brief Verifies RBAC-based sidebar sections and category visibility.
+ * @layer UI (Tests)
+ * @semantics tests, sidebar, navigation, rbac, permissions
+ */
+
+// --- BreadcrumbsContractTest:Module (frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for Breadcrumbs.svelte logic and UX annotations
+ * @layer UI
+ * @ux_state Loading -> Default
+ */
+
+// --- SidebarStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js)
+/**!
+ * @brief Unit tests for Sidebar.svelte component
+ * @layer UI
+ * @ux_state Loading -> Default
+ */
+
+// --- TaskDrawerStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js)
+/**!
+ * @brief Unit tests for TaskDrawer.svelte component
+ * @layer UI
+ * @ux_state Loading -> Default
+ */
+
+// --- TopNavbarStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js)
+/**!
+ * @brief Unit tests for TopNavbar.svelte component
+ * @layer UI
+ * @ux_state Loading -> Default
+ */
+
+// --- PageContracts (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Contract implemented by all Svelte route pages — defines page-level behavior and routing structure.
+ * @complexity 2
+ */
+
+// --- NavigationContracts (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Contract for navigation structure — sidebar sections, route categories, and menu item hierarchy.
+ * @complexity 2
+ */
+
+// --- SidebarNavigation:Module (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Build sidebar navigation sections and categories filtered by user permissions and feature flags.
+ * @invariant Admin role can access all categories and subitems through permission utility.
+ * @layer UI
+ * @semantics navigation, sidebar, rbac, menu, filtering
+ */
+
+// --- isItemAllowed:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Check whether a single menu node can be shown for a given user.
+ * @post Returns true when no permission is required or permission check passes.
+ * @pre item can contain optional requiredPermission/requiredAction.
+ */
+
+// --- isFeatureEnabled:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ */
+
+// --- buildSidebarSections:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Build translated sidebar sections with categories, filtered by RBAC permissions and feature flags.
+ * @post Returns only sections/categories/subitems available for provided user and enabled features.
+ * @pre i18nState provides nav labels; user can be null; features default to {} (all enabled).
+ */
+
+// --- ReportCardTest:Module (frontend/src/lib/components/reports/__tests__/report_card.ux.test.js)
+/**!
+ * @brief Test UX states and transitions for ReportCard component
+ * @invariant Each test asserts at least one observable UX contract outcome.
+ * @layer UI
+ * @semantics reports, ux-tests, card, states, recovery
+ * @test_contract ReportCardInputProps -> ObservableUXOutput
+ * @test_edge missing_optional_fields -> Partial report keeps component interactive and emits select.
+ * @test_fixture valid_report_card -> INLINE_JSON
+ * @test_invariant report_card_state_is_observable -> VERIFIED_BY: [ready_state_shows_summary_status_type, empty_report_object, random_status]
+ * @test_scenario ready_state_shows_summary_status_type -> Ready state renders summary/status/type labels.
+ */
+
+// --- ReportDetailIntegrationTest:Module (frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js)
+/**!
+ * @brief Validate detail-panel behavior for failed reports and recovery guidance visibility.
+ * @invariant Failed report detail exposes actionable next actions when available.
+ * @layer UI (Tests)
+ * @semantics tests, reports, detail, recovery-guidance, integration
+ */
+
+// --- ReportDetailUxTest:Module (frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js)
+/**!
+ * @brief Test UX states and recovery for ReportDetailPanel component
+ * @invariant Detail UX tests keep placeholder-safe rendering and recovery visibility verifiable.
+ * @layer UI
+ * @semantics reports, ux-tests, detail, diagnostics, recovery
+ */
+
+// --- [EXT:frontend:ReportTypeProfiles]Test:Module (frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js)
+/**!
+ * @brief Validate report type profile mapping and unknown fallback behavior.
+ * @invariant Unknown task_type always resolves to the fallback profile.
+ * @layer UI (Tests)
+ * @semantics tests, reports, type-profiles, fallback
+ */
+
+// --- ReportsFilterPerformanceTest:Module (frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js)
+/**!
+ * @brief Guard test for report filter responsiveness on moderate in-memory dataset.
+ * @layer UI (Tests)
+ * @semantics tests, reports, performance, filtering
+ */
+
+// --- ReportsListTest:Module (frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js)
+/**!
+ * @brief Test ReportsList component iteration and event forwarding.
+ * @layer UI
+ * @semantics reports, list, ux-tests, events, iteration
+ * @test_contract ReportsListProps -> rendered cards and forwarded select events
+ * @test_fixture reports_list_examples -> INLINE_JSON
+ * @test_invariant report_iteration_and_select_contract -> VERIFIED_BY: [renders_report_cards_for_each_item, renders_empty_list_container, forwards_select_event]
+ * @test_scenario forwards_select_event -> Child click forwards select payload to parent listener.
+ */
+
+// --- ReportsPageTest:Module (frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js)
+/**!
+ * @brief Integration-style checks for unified mixed-type reports rendering expectations.
+ * @invariant Mixed fixture includes all supported report types in one list.
+ * @layer UI (Tests)
+ * @semantics tests, reports, integration, mixed-types, rendering
+ */
+
+// --- ReportTypeProfiles:Module (frontend/src/lib/components/reports/reportTypeProfiles.js)
+/**!
+ * @brief Deterministic mapping from report task_type to visual profile with one fallback.
+ */
+
+// --- getReportTypeProfile:Function (frontend/src/lib/components/reports/reportTypeProfiles.js)
+/**!
+ * @brief Resolve visual profile by task type with guaranteed fallback.
+ * @post Returns one profile object.
+ * @pre taskType may be known/unknown/empty.
+ * @test_contract GetReportTypeProfileModel ->
+ */
+
+// --- ApiKeysTab (frontend/src/lib/components/settings/ApiKeysTab.svelte)
+/**!
+ * @brief API Key management tab — list, generate (one-time reveal), and revoke API keys.
+ * @complexity 3
+ * @layer UI
+ * @ux_feedback Toast on generate success/error, revoke success/error
+ * @ux_reactivity Props -> $props(), LocalState -> $state(keys, isLoading, error)
+ * @ux_recovery Retry button on load error
+ * @ux_state Revealing -> Warning panel with raw key and copy button
+ */
+
+// --- BulkCorrectionSidebar (frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte)
+/**!
+ * @brief Component component: lib/components/translate/BulkCorrectionSidebar.svelte
+ * @complexity 3
+ * @type {'closed'|'collecting'|'reviewing'|'submitting'|'submitted'}
+ * @ux_feedback Toast on success/error; count badge on toggle button
+ * @ux_recovery Remove individual items; retry submission
+ * @ux_state submitted -> Success feedback
+ */
+
+// --- BulkReplaceModal (frontend/src/lib/components/translate/BulkReplaceModal.svelte)
+/**!
+ * @brief Modal dialog for bulk find-and-replace on translated values within a completed run.
+ * @complexity 3
+ * @layer UI
+ * @type {'closed'|'configuring'|'previewing'|'preview_error'|'confirming'|'applying'|'applied'|'apply_error'}
+ * @ux_state apply_error -> Apply failed with error message
+ */
+
+// --- CorrectionCell (frontend/src/lib/components/translate/CorrectionCell.svelte)
+/**!
+ * @brief Inline-editable cell for translation run results with edit-save-cancel UX and submit-to-dictionary flow.
+ * @complexity 3
+ * @layer UI
+ * @type {'view'|'editing'|'saving'|'saved'|'submitting_to_dict'|'dict_submitted'|'error'}
+ * @ux_state error -> Error state with retry option
+ */
+
+// --- ScheduleConfig (frontend/src/lib/components/translate/ScheduleConfig.svelte)
+/**!
+ * @brief Component component: lib/components/translate/ScheduleConfig.svelte
+ * @complexity 3
+ * @type {'idle'|'editing'|'enabled'|'disabled'|'no_prior_run_warning'}
+ * @ux_feedback Next-3-executions preview; toast on save/error
+ * @ux_recovery Enable/disable toggle; delete schedule
+ * @ux_state no_prior_run_warning -> No prior manual run, show warning
+ */
+
+// --- TargetSchemaHint (frontend/src/lib/components/translate/TargetSchemaHint.svelte)
+/**!
+ * @brief Подсказка о колонках целевой таблицы + кнопка "Проверить схему".
+ * @complexity 3
+ */
+
+// --- TermCorrectionPopup (frontend/src/lib/components/translate/TermCorrectionPopup.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TermCorrectionPopup.svelte
+ * @complexity 3
+ * @type {'closed'|'selecting'|'editing'|'submitting'|'conflict_detected'|'submitted'}
+ * @ux_feedback Toast on success/error; conflict dialog with action buttons
+ * @ux_recovery Cancel button returns to previous state
+ * @ux_state submitted -> Success feedback
+ */
+
+// --- TranslationMetricsDashboard (frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationMetricsDashboard.svelte
+ * @complexity 3
+ * @type {'loading'|'loaded'|'error'|'empty'}
+ * @ux_feedback Spinner during load; card grid for totals; table for per-job breakdown
+ * @ux_recovery Retry button on error
+ * @ux_state empty -> No metrics data available
+ */
+
+// --- TranslationPreview (frontend/src/lib/components/translate/TranslationPreview.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationPreview.svelte
+ * @complexity 3
+ * @type {'idle'|'loading'|'preview_loaded'|'preview_error'|'accepted'|'stale_config'}
+ * @ux_feedback spinner during preview; visual distinction for LLM vs edited translations; cost warning for large previews.
+ * @ux_recovery retry preview; re-fetch with updated config.
+ * @ux_state stale_config -> Configuration changed since preview was generated
+ */
+
+// --- TranslationRunGlobalIndicator (frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte)
+/**!
+ * @brief Persistent rich progress panel for active translation runs, rendered in root layout.
+ * @complexity 3
+ * @ux_feedback Rich stats during active run; compact auto-dismiss for terminal states
+ * @ux_state cancelled -> Compact gray banner with auto-dismiss after 8s
+ */
+
+// --- TranslationRunProgress (frontend/src/lib/components/translate/TranslationRunProgress.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationRunProgress.svelte
+ * @complexity 3
+ * @type {{ runId: string, onRetry?: () => void, onRetryInsert?: () => void, onComplete?: (statusData: any) => void }}
+ * @ux_feedback progress bar with percentage; batch counter; per-phase counts; cancel button during running/inserting.
+ * @ux_recovery retry on failure states.
+ * @ux_state cancelled -> Run was cancelled
+ */
+
+// --- TranslationRunResult (frontend/src/lib/components/translate/TranslationRunResult.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationRunResult.svelte
+ * @complexity 3
+ * @type {'completed'|'partial'|'failed'|'insert_failed'}
+ * @ux_feedback Tabular statistics; click to copy Superset query ID; collapsible SQL block.
+ * @ux_recovery Retry failed batches; retry insert.
+ * @ux_state insert_failed -> Insert phase failed, retry-insert available
+ */
+
+// --- TargetSchemaHintTest (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Contract-focused unit tests for TargetSchemaHint.svelte component.
+ * @complexity 2
+ * @layer Tests
+ * @test_contract TargetSchemaHint -> idle, checking, complete, error UX states
+ * @test_edge error_state -> Error state shows red border
+ */
+
+// --- test_component_exists (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Verify component file exists.
+ */
+
+// --- test_ux_state_contracts (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component contains required UX state tags.
+ */
+
+// --- test_props_definition (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component accepts required props.
+ */
+
+// --- test_button_check_disabled_logic (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Button disabled logic: canCheck derived checks all required props.
+ */
+
+// --- test_idle_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Idle state shows hint text and check button.
+ */
+
+// --- test_checking_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Checking state shows spinner and disables button.
+ */
+
+// --- test_complete_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Complete state shows result with green/yellow/red indicators.
+ */
+
+// --- test_error_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Error state shows connection error message.
+ */
+
+// --- test_i18n_usage (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component uses i18n _() for all user-facing strings with fallbacks.
+ */
+
+// --- test_abort_controller (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component uses AbortController for request cancellation.
+ */
+
+// --- BulkReplaceModalTests (frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for BulkReplaceModal.svelte component.
+ * @complexity 2
+ * @layer Tests
+ * @test_contract BulkReplaceModal -> configuring, preview, confirm, apply flow
+ * @test_edge applied -> Success state
+ */
+
+// --- CorrectionCellTests (frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for CorrectionCell.svelte component.
+ * @complexity 2
+ * @layer Tests
+ * @test_contract CorrectionCell -> renders value, click-to-edit, save, submit-to-dictionary
+ * @test_edge submit_with_context -> Submit payload includes context_data and usage_notes
+ */
+
+// --- test_component_file_exists:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify component file exists and has required contracts
+ */
+
+// --- TranslateApiTests:Class (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Unit tests for translate API preview functions.
+ */
+
+// --- test_fetchPreview:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify fetchPreview calls postApi with correct endpoint and payload.
+ */
+
+// --- test_approveRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify approveRow calls requestApi with correct action.
+ */
+
+// --- test_editRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify editRow calls requestApi with edit action and translation.
+ */
+
+// --- test_rejectRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify rejectRow calls requestApi with reject action.
+ */
+
+// --- test_acceptPreview:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify acceptPreview calls postApi with correct endpoint.
+ */
+
+// --- test_fetchPreviewRecords:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify fetchPreviewRecords calls fetchApi with correct endpoint.
+ */
+
+// --- test_normalizeTranslateError:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify API errors are normalized consistently.
+ */
+
+// --- I18nModule (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Centralized internationalization management using Svelte stores with Russian and English locale support persisted in LocalStorage.
+ * @complexity 3
+ */
+
+// --- i18n:Module (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Centralized internationalization management using Svelte stores.
+ * @invariant Persistence is handled via LocalStorage.
+ * @layer Infra
+ * @semantics i18n, localization, svelte-store, translation
+ */
+
+// --- locale:Store (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Holds the current active locale string.
+ * @side_effect Writes to LocalStorage on change.
+ */
+
+// --- t:Store (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Derived store providing the translation dictionary.
+ */
+
+// --- _:Function (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Get translation by key path.
+ * @param key - Translation key path (e.g., 'nav.dashboard')
+ * @return Translation string or key if not found
+ */
+
+// --- frontend/src/lib/i18n/index.ts::_ (frontend/src/lib/i18n/index.ts)
+/**!
+ */
+
+// --- StoresModule (frontend/src/lib/stores.js)
+/**!
+ * @brief Global Svelte writable stores for plugins, tasks, and UI page state management.
+ * @complexity 3
+ */
+
+// --- stores_module:Module (frontend/src/lib/stores.js)
+/**!
+ * @brief Global state management using Svelte stores.
+ * @layer UI
+ * @semantics state, stores, svelte, plugins, tasks
+ */
+
+// --- plugins:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the list of available plugins.
+ */
+
+// --- tasks:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the list of tasks.
+ */
+
+// --- selectedPlugin:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the currently selected plugin.
+ */
+
+// --- selectedTask:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the currently selected task.
+ */
+
+// --- currentPage:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the current page.
+ */
+
+// --- taskLogs:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the logs of the currently selected task.
+ */
+
+// --- fetchPlugins:Function (frontend/src/lib/stores.js)
+/**!
+ * @brief Fetches plugins from the API and updates the plugins store.
+ * @post plugins store is updated with data from the API.
+ * @pre None.
+ */
+
+// --- fetchTasks:Function (frontend/src/lib/stores.js)
+/**!
+ * @brief Fetches tasks from the API and updates the tasks store.
+ * @post tasks store is updated with data from the API.
+ * @pre None.
+ */
+
+// --- [EXT:frontend:AssistantChatTest]s (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Unit tests for assistant chat store validating open/close/toggle, conversation binding, session context, and seed message state transitions.
+ * @complexity 3
+ */
+
+// --- [EXT:frontend:AssistantChatTest]:Module (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Validate assistant chat store visibility and conversation binding transitions.
+ * @invariant Each test starts from default closed state.
+ * @layer UI (Tests)
+ * @semantics test, store, assistant, toggle, conversation
+ */
+
+// --- assistantChatStore_tests:Function (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Group store unit scenarios for assistant panel behavior.
+ * @post Open/close/toggle/conversation transitions are validated.
+ * @pre Store can be reset to baseline state in beforeEach hook.
+ */
+
+// --- MockEnvPublic (frontend/src/lib/stores/__tests__/mocks/env_public.js)
+/**!
+ * @complexity 1
+ */
+
+// --- mock_env_public:Module (frontend/src/lib/stores/__tests__/mocks/env_public.js)
+/**!
+ * @brief Mock for $env/static/public SvelteKit module in vitest
+ * @layer UI (Tests)
+ */
+
+// --- EnvironmentMock (frontend/src/lib/stores/__tests__/mocks/environment.js)
+/**!
+ * @brief Mock for $app/environment in vitest, supplying browser, dev, and building flags.
+ * @complexity 2
+ */
+
+// --- EnvironmentMock:Module (frontend/src/lib/stores/__tests__/mocks/environment.js)
+/**!
+ * @brief Mock for $app/environment in tests
+ * @layer UI (Tests)
+ */
+
+// --- NavigationMock (frontend/src/lib/stores/__tests__/mocks/navigation.js)
+/**!
+ * @brief Mock for $app/navigation in vitest, supplying goto, push, replace, prefetch, and prefetchRoutes stubs.
+ * @complexity 2
+ */
+
+// --- NavigationMock:Module (frontend/src/lib/stores/__tests__/mocks/navigation.js)
+/**!
+ * @brief Mock for $app/navigation in tests
+ * @invariant Includes SvelteKit v1-only APIs (push, prefetchRoutes) as compatibility surface for legacy test consumers; keep until all imports migrate to SvelteKit v2-compatible mocks.
+ * @semantics mock, navigation, sveltekit-v1-legacy-surface
+ */
+
+// --- StateMock (frontend/src/lib/stores/__tests__/mocks/state.js)
+/**!
+ * @brief Mock for $app/state page data in vitest route/component tests, supplying default params, route, URL, status, and data.
+ * @complexity 2
+ */
+
+// --- state_mock:Module (frontend/src/lib/stores/__tests__/mocks/state.js)
+/**!
+ * @brief Mock for AppState in vitest route/component tests.
+ * @layer UI (Tests)
+ */
+
+// --- StoresMock (frontend/src/lib/stores/__tests__/mocks/stores.js)
+/**!
+ * @complexity 1
+ */
+
+// --- StoresMock:Module (frontend/src/lib/stores/__tests__/mocks/stores.js)
+/**!
+ * @brief Mock for $app/stores in tests
+ * @invariant Mocks $app/stores which is a SvelteKit v1 module; SvelteKit v2 uses $app/state. Verify no active test files import this mock before removal.
+ * @semantics mock, stores, sveltekit-v1-legacy-surface
+ */
+
+// --- SetupTestsModule (frontend/src/lib/stores/__tests__/setupTests.js)
+/**!
+ * @brief Global vitest test setup with mocks for SvelteKit modules ($app/environment, $app/stores, $app/navigation, localStorage).
+ * @complexity 3
+ */
+
+// --- setupTests:Module (frontend/src/lib/stores/__tests__/setupTests.js)
+/**!
+ * @brief Global test setup with mocks for SvelteKit modules
+ * @layer UI
+ * @ux_state Idle -> Global test environment exposes stable mocked browser services.
+ */
+
+// --- SidebarTest (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Unit tests for sidebar store validating expansion toggles, active item selection, and mobile open/close transitions.
+ * @complexity 3
+ */
+
+// --- SidebarTest:Module (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Unit tests for sidebar store
+ * @invariant Sidebar store transitions must be deterministic across desktop/mobile toggles.
+ * @layer Tests
+ * @semantics sidebar, store, tests, mobile, navigation
+ */
+
+// --- test_sidebar_initial_state:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify initial sidebar store values when no persisted state is available.
+ * @post Default state is { isExpanded: true, activeCategory: 'dashboards', activeItem: '/dashboards', isMobileOpen: false }
+ * @pre No localStorage state
+ * @test Store initializes with default values
+ */
+
+// --- test_toggleSidebar:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify desktop sidebar expansion toggles deterministically.
+ * @post isExpanded is toggled from previous value
+ * @pre Store is initialized
+ * @test toggleSidebar toggles isExpanded state
+ */
+
+// --- test_setActiveItem:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify active-category updates remain deterministic after item selection.
+ * @post activeCategory and activeItem are updated
+ * @pre Store is initialized
+ * @test setActiveItem updates activeCategory and activeItem
+ */
+
+// --- test_mobile_functions:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify mobile sidebar helpers update open-state transitions predictably.
+ * @post isMobileOpen is correctly updated
+ * @pre Store is initialized
+ * @test Mobile functions correctly update isMobileOpen
+ */
+
+// --- TaskDrawerTests (frontend/src/lib/stores/__tests__/taskDrawer.test.js)
+/**!
+ * @brief Unit tests for task drawer store validating open/close, preference-aware opening, resource task mapping, and status-driven cleanup.
+ * @complexity 3
+ */
+
+// --- ActivityTestModule (frontend/src/lib/stores/__tests__/test_activity.js)
+/**!
+ * @brief Unit tests validating activity store derived count and recent task tracking behavior.
+ * @complexity 3
+ */
+
+// --- ActivityTest:Module (frontend/src/lib/stores/__tests__/test_activity.js)
+/**!
+ * @brief Unit tests for activity store
+ */
+
+// --- DatasetReviewSessionTests (frontend/src/lib/stores/__tests__/test_datasetReviewSession.js)
+/**!
+ * @brief Unit tests for dataset review session store: session set/reset, loading, error, dirty flag, and patch operations.
+ * @complexity 3
+ */
+
+// --- DatasetReviewSessionStoreTests:Module (frontend/src/lib/stores/__tests__/test_datasetReviewSession.js)
+/**!
+ * @brief Unit tests for dataset review session store.
+ * @layer UI
+ * @semantics dataset-review, store, session, tests
+ * @ux_state Idle -> Store helpers are exercised without asynchronous UI transitions.
+ */
+
+// --- SidebarTestModule (frontend/src/lib/stores/__tests__/test_sidebar.js)
+/**!
+ * @brief Unit tests for sidebar store validating initial state, toggle, navigation, mobile overlay, and localStorage persistence.
+ * @complexity 3
+ */
+
+// --- SidebarIntegrationTest:Module (frontend/src/lib/stores/__tests__/test_sidebar.js)
+/**!
+ * @brief Unit tests for sidebar store
+ * @layer UI
+ */
+
+// --- TaskDrawerTestModule (frontend/src/lib/stores/__tests__/test_taskDrawer.js)
+/**!
+ * @brief Unit tests for task drawer store validating open/close transitions, preference-aware opening, and resource-task mapping lifecycle.
+ * @complexity 3
+ */
+
+// --- TaskDrawerTest:Module (frontend/src/lib/stores/__tests__/test_taskDrawer.js)
+/**!
+ * @brief Unit tests for task drawer store
+ * @invariant Store state transitions remain deterministic for open/close and task-status mapping.
+ * @layer UI
+ * @semantics task-drawer, store, mapping, tests
+ */
+
+// --- ActivityStore (frontend/src/lib/stores/activity.js)
+/**!
+ * @brief Derived store that counts active running tasks for navbar indicator badge.
+ * @complexity 2
+ */
+
+// --- activity:Store (frontend/src/lib/stores/activity.js)
+/**!
+ * @brief Track active task count for navbar indicator
+ * @layer UI
+ */
+
+// --- AssistantChatStore (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Control assistant chat panel visibility, conversation binding, session context, and seeded prompts.
+ * @complexity 3
+ * @ux_state Open -> Chat panel visible with active conversation
+ */
+
+// --- assistantChat:Store (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Control assistant chat panel visibility and active conversation binding.
+ */
+
+// --- toggleAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Toggle assistant panel visibility.
+ * @post isOpen value inverted.
+ * @pre Store is initialized.
+ */
+
+// --- openAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Open assistant panel.
+ * @post isOpen = true.
+ * @pre Store is initialized.
+ */
+
+// --- openAssistantChatWithContext:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Open assistant panel with dataset review session context and optional seeded prompt/focus target.
+ * @post Assistant drawer opens with session binding and visible focus metadata.
+ * @pre Context payload may be partial.
+ */
+
+// --- closeAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Close assistant panel.
+ * @post isOpen = false.
+ * @pre Store is initialized.
+ */
+
+// --- setAssistantConversationId:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Bind current conversation id in UI state.
+ * @post store.conversationId updated.
+ * @pre conversationId is string-like identifier.
+ */
+
+// --- setAssistantDatasetReviewSessionId:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Bind active dataset review session to assistant state.
+ * @post store.datasetReviewSessionId updated.
+ * @pre session identifier may be null when workspace context is cleared.
+ */
+
+// --- setAssistantSeedMessage:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Stage a seeded assistant prompt for contextual send UX.
+ * @post store.seedMessage updated.
+ * @pre seedMessage can be empty to clear staged draft.
+ */
+
+// --- setAssistantFocusTarget:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Track the workspace entity currently referenced by assistant context.
+ * @post store.focusTarget updated.
+ * @pre focusTarget may be null to clear prior focus.
+ */
+
+// --- DatasetReviewSessionStore (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ * @brief Manage active dataset review session state including loading, local edits, error capture, and reset semantics.
+ * @complexity 4
+ * @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+ * @pre Consumers provide session-shaped payloads and initialize the store before reading derived session fields.
+ * @side_effect Mutates the writable dataset review session store in frontend memory.
+ * @ux_state Error -> Failed to load or update session
+ */
+
+// --- datasetReviewSession:Store (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ * @brief Manage active dataset review session state, including loading, local edits, error capture, and reset semantics for the active review workspace.
+ * @data_contract Input[SessionDetail | Partial | boolean | string | null] -> Output[DatasetReviewSessionStoreState]
+ * @layer UI
+ * @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+ * @pre Consumers provide session-shaped payloads when setting or patching state and initialize the store before reading derived session fields.
+ * @side_effect Mutates the writable dataset review session store in frontend memory.
+ * @ux_reactivity Uses Svelte writable store for session aggregate.
+ * @ux_state LaunchBlocked -> Session remains reviewable while explicit launch blockers are unresolved.
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setLoading (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setError (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setDirty (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::resetSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::patchSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::getSessionUiPhase (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- EnvironmentContextStore (frontend/src/lib/stores/environmentContext.js)
+/**!
+ * @brief Global selected environment context for navigation, safety cues, and environment-based filtering.
+ * @complexity 3
+ * @ux_state Error -> Failed to load environments
+ */
+
+// --- environmentContext:Store (frontend/src/lib/stores/environmentContext.js)
+/**!
+ * @brief Global selected environment context for navigation and safety cues.
+ * @layer UI
+ */
+
+// --- HealthStore (frontend/src/lib/stores/health.js)
+/**!
+ * @brief Manage dashboard health summary state and failing counts for UI badges.
+ * @complexity 3
+ * @ux_state Error -> Error state with retry option
+ */
+
+// --- health_store:Store (frontend/src/lib/stores/health.js)
+/**!
+ * @brief Manage dashboard health summary state and failing counts for UI badges.
+ * @layer UI
+ * @property {Date|null} lastUpdated - Last successful fetch timestamp
+ * @typedef {Object} HealthState
+ * @ux_state Loading -> Default
+ */
+
+// --- frontend/src/lib/stores/health.js::createHealthStore (frontend/src/lib/stores/health.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/health.js::refresh (frontend/src/lib/stores/health.js)
+/**!
+ */
+
+// --- MaintenanceStore (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ * @brief Svelte 5 (Runes) store for maintenance banner state. Auto-polls events every 30s via interval.
+ * @complexity 3
+ * @layer Frontend
+ * @return {object} Maintenance store with runes state and methods.
+ * @ux_reactivity $state for events/settings/banners. Manual setInterval for polling.
+ * @ux_recovery Error toast on failure. Retry via loadEvents/loadSettings.
+ * @ux_state Error -> error state populated with message
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::createMaintenanceStore (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- MaintenanceStore.state (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ * @complexity 1
+ */
+
+// --- MaintenanceStore.methods (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ * @complexity 2
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadEvents (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadDashboardBanners (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadSettings (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::endEvent (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::endAllEvents (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::updateSettings (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::init (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::startPolling (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::stopPolling (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- SidebarStore (frontend/src/lib/stores/sidebar.js)
+/**!
+ * @brief Manage sidebar visibility, expansion state, active navigation item, and mobile overlay.
+ * @complexity 3
+ * @ux_state Toggling -> Expand/collapse animation
+ */
+
+// --- sidebar:Store (frontend/src/lib/stores/sidebar.js)
+/**!
+ * @brief Manage sidebar visibility and navigation state
+ * @invariant isExpanded state is always synced with localStorage
+ * @layer UI
+ * @ux_state Toggling -> Animation plays for 200ms
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::toggleSidebar (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::setActiveItem (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::setMobileOpen (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::closeMobile (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::toggleMobileSidebar (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- TaskDrawerStore (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ * @brief Manage Task Drawer visibility, active task binding, and resource-to-task mapping.
+ * @complexity 3
+ * @ux_state Open -> Drawer visible with task logs or task list
+ */
+
+// --- taskDrawer:Store (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ * @brief Manage Task Drawer visibility and resource-to-task mapping
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawerForTask (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::setTaskDrawerAutoOpenPreference (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::getTaskDrawerAutoOpenPreference (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawerForTaskIfPreferred (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawer (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::closeDrawer (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::updateResourceTask (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::getTaskForResource (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- TranslationRunStore (frontend/src/lib/stores/translationRun.js)
+/**!
+ * @brief Global store for active translation run progress — survives page navigation.
+ * @complexity 3
+ * @property {boolean} isActive - Derived: true when polling is active
+ * @typedef {Object} TranslationRunState
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::clearOnCompleteCallback (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::startTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::stopTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::resetTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::updateTranslationRunState (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::pollStatus (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- ToastsModule (frontend/src/lib/toasts.js)
+/**!
+ * @brief Manages toast notifications using a Svelte writable store with deduplication and auto-removal.
+ * @complexity 3
+ */
+
+// --- toasts_module:Module (frontend/src/lib/toasts.js)
+/**!
+ * @brief Manages toast notifications using a Svelte writable store.
+ * @layer UI
+ * @semantics notification, toast, feedback, state
+ */
+
+// --- toasts:Data (frontend/src/lib/toasts.js)
+/**!
+ * @brief Writable store containing the list of active toasts.
+ */
+
+// --- addToast:Function (frontend/src/lib/toasts.js)
+/**!
+ * @brief Adds a new toast message.
+ * @param duration (number) - Duration in ms before the toast is removed.
+ * @post New toast is added to the store and scheduled for removal.
+ * @pre message string is provided.
+ */
+
+// --- removeToast:Function (frontend/src/lib/toasts.js)
+/**!
+ * @brief Removes a toast message by ID.
+ * @param id (string) - The ID of the toast to remove.
+ * @post Toast is removed from the store.
+ * @pre id is provided.
+ */
+
+// --- Button (frontend/src/lib/ui/Button.svelte)
+/**!
+ * @brief Standardized button component with variants and loading states.
+ * @complexity 2
+ * @invariant Supports accessible labels and keyboard navigation.
+ * @layer Atom
+ * @semantics button, ui-atom, interactive
+ * @ux_state Loading -> Spinner replaces the leading area and interaction is disabled.
+ */
+
+// --- Card (frontend/src/lib/ui/Card.svelte)
+/**!
+ * @brief Standardized container with padding and elevation.
+ * @complexity 2
+ * @layer Atom
+ * @semantics card, container, ui-atom
+ * @ux_state Titled -> Header row appears above the padded content area.
+ */
+
+// --- Icon (frontend/src/lib/ui/Icon.svelte)
+/**!
+ * @brief Render the shared inline SVG icon set with consistent sizing and stroke props.
+ * @complexity 1
+ * @invariant Icon output remains aria-hidden because labels belong to the interactive parent.
+ * @layer Atom
+ * @semantics icon, ui-atom, svg
+ * @ux_state Fallback -> Unknown icon names resolve to the dashboard glyph.
+ */
+
+// --- Input (frontend/src/lib/ui/Input.svelte)
+/**!
+ * @brief Standardized text input component with label and error handling.
+ * @complexity 2
+ * @invariant Consistent spacing and focus states.
+ * @layer Atom
+ * @semantics input, form-field, ui-atom
+ * @ux_state Disabled -> Native disabled state prevents editing while preserving value visibility.
+ */
+
+// --- LanguageSwitcher (frontend/src/lib/ui/LanguageSwitcher.svelte)
+/**!
+ * @brief Dropdown component to switch between supported languages.
+ * @complexity 1
+ * @layer Atom
+ * @semantics language-switcher, i18n-ui, ui-atom
+ * @ux_state Switching -> Bound locale updates immediately after selection.
+ */
+
+// --- PageHeader (frontend/src/lib/ui/PageHeader.svelte)
+/**!
+ * @brief Standardized page header with title and action area.
+ * @complexity 2
+ * @layer Atom
+ * @semantics page-header, layout-atom
+ * @ux_state WithContext -> Subtitle and action slots expand the header composition.
+ */
+
+// --- Select (frontend/src/lib/ui/Select.svelte)
+/**!
+ * @brief Standardized dropdown selection component.
+ * @complexity 2
+ * @layer Atom
+ * @semantics select, dropdown, form-field, ui-atom
+ * @ux_state Disabled -> Native disabled state prevents selection changes.
+ */
+
+// --- ui:Module (frontend/src/lib/ui/index.ts)
+/**!
+ * @brief Central export point for standardized UI components.
+ * @invariant All components exported here must follow Semantic Protocol.
+ * @layer Atom
+ * @semantics ui, components, library, atomic-design
+ */
+
+// --- UtilsModule (frontend/src/lib/utils.js)
+/**!
+ * @complexity 1
+ */
+
+// --- Utils:Module (frontend/src/lib/utils.js)
+/**!
+ * @brief General utility functions (class merging)
+ * @layer Infra
+ */
+
+// --- frontend/src/lib/utils.js::cn (frontend/src/lib/utils.js)
+/**!
+ */
+
+// --- DebounceModule (frontend/src/lib/utils/debounce.js)
+/**!
+ * @complexity 1
+ */
+
+// --- Debounce:Module (frontend/src/lib/utils/debounce.js)
+/**!
+ * @brief Debounce utility for limiting function execution rate
+ * @layer Infra
+ */
+
+// --- frontend/src/lib/utils/debounce.js::debounce (frontend/src/lib/utils/debounce.js)
+/**!
+ */
+
+// --- onMount:Function (frontend/src/pages/Dashboard.svelte)
+/**!
+ * @brief Fetch plugins when the component mounts.
+ * @post plugins store is populated with available tools.
+ * @pre Component is mounting.
+ */
+
+// --- selectPlugin:Function (frontend/src/pages/Dashboard.svelte)
+/**!
+ * @brief Selects a plugin to display its form.
+ * @param {Object} plugin - The plugin object to select.
+ * @post selectedPlugin store is updated.
+ * @pre plugin object is provided.
+ */
+
+// --- loadSettings:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Loads settings from the backend.
+ * @post settings object is populated with backend data.
+ * @pre Component mounted or refresh requested.
+ */
+
+// --- handleSaveGlobal:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Saves global settings to the backend.
+ * @post Backend global settings are updated.
+ * @pre settings.settings contains valid configuration.
+ */
+
+// --- handleAddOrUpdateEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Adds or updates an environment.
+ * @post Environment list is updated on backend and reloaded locally.
+ * @pre newEnv contains valid environment details.
+ */
+
+// --- handleDeleteEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Deletes an environment.
+ * @param {string} id - The ID of the environment to delete.
+ * @post Environment is removed from backend and list is reloaded.
+ * @pre id of environment to delete is provided.
+ */
+
+// --- handleTestEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Tests the connection to an environment.
+ * @param {string} id - The ID of the environment to test.
+ * @post Connection test result is displayed via toast.
+ * @pre Environment ID is valid.
+ */
+
+// --- editEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Sets the form to edit an existing environment.
+ * @param {Object} env - The environment object to edit.
+ * @post newEnv is populated with env data and editingEnvId is set.
+ * @pre env object is provided.
+ */
+
+// --- resetEnvForm:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Resets the environment form.
+ * @post newEnv is reset to initial state and editingEnvId is cleared.
+ * @pre None.
+ */
+
+// --- ErrorPage (frontend/src/routes/+error.svelte)
+/**!
+ * @brief Global error page displaying HTTP status code and error message with navigation back to dashboard.
+ * @complexity 2
+ * @layer Page
+ * @ux_state Error -> Displays error code and message with "Back to Dashboard" link.
+ */
+
+// --- RootLayout (frontend/src/routes/+layout.svelte)
+/**!
+ * @brief Root layout component providing global UI structure: Sidebar, TopNavbar, Footer, TaskDrawer, Toasts.
+ * @complexity 3
+ * @invariant Sidebar width adapts (ml-60 vs ml-16) based on sidebar expanded state.
+ * @layer Layout
+ * @ux_feedback Toast notifications rendered globally.
+ * @ux_state Authenticated -> Full shell rendered with Sidebar, TopNavbar, Footer, global components.
+ */
+
+// --- RootLayoutConfig:Module (frontend/src/routes/+layout.ts)
+/**!
+ * @brief Root layout configuration (SPA mode)
+ * @layer Infra
+ */
+
+// --- HomePage (frontend/src/routes/+page.svelte)
+/**!
+ * @brief Redirect to preferred start page (dashboards/datasets/reports) based on profile settings, with safe fallback.
+ * @complexity 3
+ * @invariant Redirect target resolves to one of /dashboards, /datasets, /reports.
+ * @layer Page
+ * @ux_feedback Redirects to preferred start page once profile or local fallback is resolved.
+ * @ux_state Loading -> Shows centered spinner while resolving the preferred landing route.
+ */
+
+// --- load:Function (frontend/src/routes/+page.ts)
+/**!
+ * @brief Loads initial plugin data for the dashboard.
+ * @post Returns an object with plugins or an error message.
+ * @pre None.
+ */
+
+// --- frontend/src/routes/+page.ts::load (frontend/src/routes/+page.ts)
+/**!
+ */
+
+// --- openCreateModal:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Initializes state for creating a new role.
+ * @post showModal is true, roleForm is reset.
+ * @pre None.
+ */
+
+// --- openEditModal:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Initializes state for editing an existing role.
+ * @post showModal is true, roleForm is populated.
+ * @pre role object is provided.
+ */
+
+// --- handleSaveRole:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Submits role data (create or update).
+ * @post Role is saved, modal closed, data reloaded.
+ * @pre roleForm contains valid data.
+ */
+
+// --- handleDeleteRole:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Deletes a role after confirmation.
+ * @post Role is deleted if confirmed, data reloaded.
+ * @pre role object is provided.
+ */
+
+// --- handleCreateMapping:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Submits a new AD Group to Role mapping to the backend.
+ * @post A new mapping is created in the database and the table is refreshed.
+ * @pre 'newMapping' object contains valid 'ad_group' and 'role_id'.
+ * @return {Promise}
+ * @side_effect Closes the modal on success, shows alert on failure.
+ */
+
+// --- loadLoggingConfig:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Fetches current logging configuration from the backend.
+ * @post loggingConfig variable is updated with backend data.
+ * @pre Component is mounted and user has active session.
+ * @return {Promise}
+ */
+
+// --- saveLoggingConfig:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Saves logging configuration to the backend.
+ * @post Configuration is saved and feedback is shown.
+ * @pre loggingConfig contains valid values.
+ * @return {Promise}
+ */
+
+// --- LLMReportPage (frontend/src/routes/admin/settings/llm/+page.svelte)
+/**!
+ * @brief Admin settings page for LLM provider configuration.
+ * @complexity 3
+ * @layer UI
+ * @semantics admin, llm, provider, config, prompt
+ * @ux_state Loading -> Default
+ */
+
+// --- handleSaveUser:Function (frontend/src/routes/admin/users/+page.svelte)
+/**!
+ * @brief Submits user data to the backend (create or update).
+ * @post User created or updated, modal closed, data reloaded.
+ * @pre userForm must be valid.
+ * @side_effect Triggers API call to adminService.
+ */
+
+// --- handleDeleteUser:Function (frontend/src/routes/admin/users/+page.svelte)
+/**!
+ * @brief Deletes a user after confirmation.
+ * @param {Object} user - The user to delete.
+ * @post User deleted if confirmed, data reloaded.
+ * @pre user object must be valid.
+ * @side_effect Triggers API call to adminService.
+ */
+
+// --- DashboardHub.normalizeTaskStatus:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize raw task status to stable lowercase token for UI.
+ * @post returns null or normalized token without enum namespace.
+ * @pre status can be enum-like string or null.
+ */
+
+// --- DashboardHub.normalizeValidationStatus:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize validation status to pass/fail/warn/unknown.
+ * @post returns one of pass|fail|warn|unknown.
+ * @pre status can be any scalar.
+ */
+
+// --- DashboardHub.getValidationBadgeClass:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Map validation level to badge class tuple.
+ * @post returns deterministic tailwind class string.
+ * @pre level in pass|fail|warn|unknown.
+ */
+
+// --- DashboardHub.getValidationLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Map normalized validation level to compact UI label.
+ * @post returns uppercase status label.
+ * @pre level in pass|fail|warn|unknown.
+ */
+
+// --- DashboardHub.normalizeOwners:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize owners payload to unique non-empty display labels.
+ * @post Returns owner labels preserving source order.
+ * @pre owners can be null, list of strings, or list of user objects.
+ */
+
+// --- DashboardHub.loadDashboards:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Load full dashboard dataset for current environment and hydrate grid projection.
+ * @post allDashboards, dashboards, pagination and selection state are synchronized.
+ * @pre selectedEnv is not null.
+ * @ux_state Error -> `error` populated when request fails.
+ */
+
+// --- DashboardHub.handleTemporaryShowAll:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Temporarily disable profile-default dashboard filter for current page context.
+ * @post Next request is sent with override_show_all=true.
+ * @pre Dashboards list is loaded in dashboards_main context.
+ */
+
+// --- DashboardHub.handleRestoreProfileFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Re-enable persisted profile-default filtering after temporary override.
+ * @post Next request is sent with override_show_all=false.
+ * @pre Current page is in override mode.
+ */
+
+// --- DashboardHub.formatDate:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Convert ISO timestamp to locale date string.
+ * @post returns formatted date or "-".
+ * @pre value may be null or invalid date string.
+ */
+
+// --- DashboardHub.getGitSummaryLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute stable text label for git state column.
+ * @post returns localized summary string.
+ * @pre dashboard has git projection fields.
+ */
+
+// --- DashboardHub.getLlmSummaryLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute normalized LLM validation summary label.
+ * @post returns UNKNOWN fallback for missing status.
+ * @pre dashboard may have null lastTask.
+ */
+
+// --- DashboardHub.getColumnCellValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Resolve comparable/filterable display value for any grid column.
+ * @post returns non-empty scalar display value.
+ * @pre column belongs to filterable column set.
+ */
+
+// --- DashboardHub.getFilterOptions:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Build unique sorted value list for a column filter dropdown.
+ * @post returns de-duplicated sorted options.
+ * @pre allDashboards is hydrated.
+ */
+
+// --- DashboardHub.getVisibleFilterOptions:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Apply in-dropdown search over full filter options.
+ * @post returns subset for current filter popover list.
+ * @pre columnFilterSearch contains search token for column.
+ */
+
+// --- DashboardHub.toggleFilterDropdown:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Toggle active column filter popover.
+ * @post openFilterColumn updated.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.toggleFilterValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Add/remove specific filter value and reapply projection.
+ * @post columnFilters updated and grid reprojected from page 1.
+ * @pre value comes from option list of the same column.
+ */
+
+// --- DashboardHub.clearColumnFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Reset selected values for one column.
+ * @post filter cleared and projection refreshed.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.selectAllColumnFilterValues:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Select all currently visible values in filter popover.
+ * @post column filter equals current visible option set.
+ * @pre visible options computed for current search token.
+ */
+
+// --- DashboardHub.updateColumnFilterSearch:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Update local search token for one filter popover.
+ * @post columnFilterSearch updated immutably.
+ * @pre value is text from input.
+ */
+
+// --- DashboardHub.hasColumnFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Determine if column has active selected values.
+ * @post returns boolean activation marker.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.doesDashboardPassColumnFilters:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Evaluate dashboard row against all active column filters.
+ * @post returns true only when row matches every active filter.
+ * @pre dashboard contains projected values for each filterable column.
+ */
+
+// --- DashboardHub.getSortValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute stable comparable sort key for chosen column.
+ * @post returns string/number key suitable for deterministic comparison.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.handleSort:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Toggle or switch sort order and reapply grid projection.
+ * @post sortColumn/sortDirection updated and page reset to 1.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.getSortIndicator:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Return visual indicator for active/inactive sort header.
+ * @post returns one of ↕ | ↑ | ↓.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.applyGridTransforms:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Apply search + column filters + sort + pagination to grid data.
+ * @post filteredDashboards/dashboards/total/totalPages are synchronized.
+ * @pre allDashboards is current source collection.
+ * @ux_state Loaded -> visible rows reflect all active controls deterministically.
+ */
+
+// --- DashboardHeader (frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte)
+/**!
+ * @brief Top title area, breadcrumb, Git branch selector, and action buttons for dashboard detail.
+ * @complexity 2
+ * @layer UI
+ * @ux_state Idle -> Header with back button, title, Git status badge, and action buttons.
+ */
+
+// --- DashboardProfileOverrideIntegrationTest:Module (frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js)
+/**!
+ * @brief Verifies temporary show-all override and restore-on-return behavior for profile-default dashboard filtering.
+ * @layer UI (Tests)
+ * @semantics tests, dashboards, profile-filter, override, restore
+ * @type {any}
+ */
+
+// --- HealthCenterPage (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Main page for the Dashboard Health Center showing health matrix table with environment filtering.
+ * @complexity 3
+ * @layer Page
+ * @ux_state Error -> Error message displayed inline.
+ */
+
+// --- loadData:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Load health summary rows and environment options for the current filter.
+ * @post `healthData` and `environments` reflect latest backend response.
+ * @pre Page is mounted or environment selection changed.
+ * @side_effect Calls backend API endpoints for health summary and environments.
+ */
+
+// --- handleEnvChange:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Apply environment filter and trigger health summary reload.
+ * @post selectedEnvId is updated and new data load starts.
+ * @pre DOM change event carries target value.
+ */
+
+// --- handleDeleteReport:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Delete one health report row with confirmation and optimistic button lock.
+ * @post Row is removed from backend and page data is reloaded on success.
+ * @pre item contains `record_id` from health summary payload.
+ * @side_effect Calls DELETE health API and emits toast notifications.
+ */
+
+// --- HealthPageIntegrationTest:Module (frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js)
+/**!
+ * @brief Lock dashboard health page contract for slug navigation and report deletion.
+ * @layer UI (Tests)
+ * @semantics health-page, integration-test, slug-link, delete-flow
+ */
+
+// --- DatasetHub (frontend/src/routes/datasets/+page.svelte)
+/**!
+ * @complexity 5
+ */
+
+// --- ColumnsTable (frontend/src/routes/datasets/ColumnsTable.svelte)
+/**!
+ * @brief Table of dataset columns with type chips, description, and inline-edit capability.
+ * @complexity 4
+ * @layer UI
+ * @ux_reactivity Props -> columns, datasetId
+ * @ux_state Editing -> One row in edit mode (textarea), others dimmed.
+ */
+
+// --- DatasetList (frontend/src/routes/datasets/DatasetList.svelte)
+/**!
+ * @brief Renders paginated dataset cards with mapping progress bars, checkboxes, and quick actions.
+ * @complexity 4
+ * @rationale Action buttons switched from bg-primary solid to border-outline style, card padding reduced from p-3 to p-2.5, row gap from gap-3 to gap-2.5 — fixes "huge buttons" visual complaint.
+ * @rejected Solid blue action buttons rejected — too visually heavy on each card line.
+ * @ux_reactivity Props -> datasets, selectedIds, isLoading, error, total, page, totalPages, pageSize, onselect, onaction, onpagechange, onsearch, oncheckbox
+ * @ux_state Empty -> "No datasets found" after search/filter.
+ */
+
+// --- DatasetPreview (frontend/src/routes/datasets/DatasetPreview.svelte)
+/**!
+ * @brief Right panel showing dataset detail: header info, columns table, metrics table, linked dashboards. Presentational.
+ * @complexity 3
+ * @layer UI
+ * @ux_state Error -> Error banner with retry.
+ */
+
+// --- MetricsTable (frontend/src/routes/datasets/MetricsTable.svelte)
+/**!
+ * @brief Table of dataset metrics with expression, description, and inline-edit capability.
+ * @complexity 4
+ * @layer UI
+ * @ux_reactivity Props -> metrics, datasetId
+ * @ux_state Editing -> One row in edit mode.
+ */
+
+// --- StatsBar (frontend/src/routes/datasets/StatsBar.svelte)
+/**!
+ * @brief Compact filter pills showing aggregate counts (All, Without mapping, Mapped, Linked).
+ * @complexity 3
+ * @rationale Converted from card tiles (p-3, text-2xl) to compact pills (rounded-full px-3 py-1 text-sm) to fix oversized buttons complaint.
+ * @rejected Card-tile filter buttons rejected — were too visually heavy at 12px padding + 24px font, dominating the page top.
+ * @ux_reactivity Events -> onfilter(filterKey) emitted on pill click
+ * @ux_state Filtered -> selected pill has filled background; parent reloads with filter param.
+ */
+
+// --- DatasetReviewWorkspaceEntry (frontend/src/routes/datasets/review/+page.svelte)
+/**!
+ * @brief Entry route for Dataset Review Workspace — start a new resumable review session or navigate to existing sessions.
+ * @complexity 3
+ * @layer Page
+ * @ux_recovery User can correct invalid input and retry without losing environment selection.
+ * @ux_state Error -> Inline error shown while keeping intake editable.
+ */
+
+// --- ReviewWorkspaceHeader (frontend/src/routes/datasets/review/ReviewWorkspaceHeader.svelte)
+/**!
+ * @brief Header section for the dataset review workspace with title, description, and status badges.
+ * @complexity 2
+ * @layer UI
+ */
+
+// --- ReviewWorkspaceLeftSidebar (frontend/src/routes/datasets/review/ReviewWorkspaceLeftSidebar.svelte)
+/**!
+ * @brief Left sidebar for dataset review workspace: source info, import status, session summary, clarification focus, primary actions.
+ * @complexity 3
+ * @layer UI
+ */
+
+// --- ReviewWorkspaceRightRail (frontend/src/routes/datasets/review/ReviewWorkspaceRightRail.svelte)
+/**!
+ * @brief Right rail for dataset review workspace: next action, blockers, health counts, exports, SQL preview, launch panel.
+ * @complexity 3
+ * @layer UI
+ */
+
+// --- DatasetReviewWorkspace (frontend/src/routes/datasets/review/[id]/+page.svelte)
+/**!
+ * @brief Main dataset review workspace — thin shell delegating to extracted components.
+ * @complexity 4
+ * @deprecated N/A — active workspace page.
+ * @layer Page
+ * @rationale Decomposed from 1202→~380 lines by extracting helpers, composables, and sidebar/rail/header components per INV_7.
+ * @rejected Keeping all logic inline was rejected — exceeded 150-line contract limit and cyclomatic complexity thresholds.
+ * @replaced_by N/A
+ * @ux_state Review -> 3-column layout.
+ */
+
+// --- DatasetReviewEntryUxTests (frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js)
+/**!
+ * @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+ * @complexity 3
+ * @layer UI
+ * @semantics dataset-review, workspace-entry, resume, source-intake, ux-tests
+ * @test_scenario submits_new_session_without_regression
+ * @ux_state ResumeError -> inline error and retry action remain visible without removing new session flow.
+ */
+
+// --- DatasetReviewEntryUxPageTests (frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js)
+/**!
+ * @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+ * @complexity 3
+ * @layer UI
+ * @semantics dataset-review, workspace-entry, resume, source-intake, ux-tests
+ * @test_scenario submits_new_session_without_regression
+ * @ux_state ResumeError -> inline error and retry action remain visible without removing new session flow.
+ */
+
+// --- ReviewWorkspaceHelpers (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ * @brief Shared helper functions for the dataset review workspace.
+ * @complexity 2
+ * @rationale Extracted from DatasetReviewWorkspace to reduce page script size per INV_7.
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildImportMilestones (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildWorkspaceLaunchBlockers (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantSeedPrompt (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantContextPrompt (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getWorkspaceStateLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getRecommendedActionLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getPrimaryActionCtaLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::mergeCollectionItem (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::stringifyValue (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- UseReviewSession (frontend/src/routes/datasets/review/useReviewSession.js)
+/**!
+ * @brief Composable for dataset review session state management — load, update, export, and clarify.
+ * @complexity 3
+ */
+
+// --- GitDashboardPage (frontend/src/routes/git/+page.svelte)
+/**!
+ * @brief Git integration page for selecting environments and managing dashboard repositories.
+ * @complexity 3
+ * @layer Page
+ * @ux_feedback Toast notifications on API errors.
+ * @ux_recovery User can retry by changing environment or refreshing.
+ * @ux_state Error -> Toast-driven failure feedback preserves filter selection.
+ */
+
+// --- LoginPage (frontend/src/routes/login/+page.svelte)
+/**!
+ * @brief Provides the user interface for local (username/password) and ADFS SSO authentication.
+ * @complexity 3
+ * @invariant Shows both local login form and ADFS SSO button.
+ * @layer Page
+ * @ux_feedback Loading text on submit button while authenticating.
+ * @ux_recovery User can retry login after error.
+ * @ux_state Success -> User authenticated, redirected to homepage.
+ */
+
+// --- MaintenanceBannerPage (frontend/src/routes/maintenance/+page.svelte)
+/**!
+ * @brief Maintenance Banners management page. Composes SettingsPanel and EventsTable from store.
+ * @complexity 3
+ * @layer Page
+ * @ux_feedback Toast via addToast() from $lib/toasts.js
+ * @ux_recovery Refresh via maintenanceStore.loadEvents().
+ * @ux_state Error -> Error toast shown.
+ */
+
+// --- ReactiveDashboardFetch:Block (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Automatically fetch dashboards when the source environment is changed.
+ * @post fetchDashboards is called with the new sourceEnvId.
+ * @pre sourceEnvId is not empty.
+ * @ux_state [Loading] -> Triggered when sourceEnvId changes.
+ */
+
+// --- handleMappingUpdate:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Saves a mapping to the backend.
+ * @post Mapping is saved and local mappings list is updated.
+ * @pre event.detail contains sourceUuid and targetUuid.
+ */
+
+// --- handleViewLogs:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Opens the log viewer for a specific task.
+ * @post logViewer state updated and showLogViewer set to true.
+ * @pre event.detail contains task object.
+ */
+
+// --- handlePasswordPrompt:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Reactive logic to show password prompt when a task is awaiting input.
+ * @post showPasswordPrompt set to true with request data.
+ * @pre selectedTask status is AWAITING_INPUT.
+ */
+
+// --- ReactivePasswordPrompt:Block (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Monitor selected task for input requests and trigger password prompt.
+ * @post showPasswordPrompt is set to true if input_request is database_password.
+ * @pre $selectedTask is not null and status is AWAITING_INPUT.
+ * @ux_state [AwaitingInput] -> Password prompt modal is displayed.
+ */
+
+// --- handleResumeMigration:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Resumes a migration task with provided passwords.
+ * @post resumeTask is called and showPasswordPrompt is hidden on success.
+ * @pre event.detail contains passwords.
+ */
+
+// --- startMigration:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Initiates the migration process by sending the selection to the backend.
+ * @post A migration task is created and selectedTask store is updated.
+ * @pre sourceEnvId and targetEnvId are set and different; at least one dashboard is selected.
+ * @side_effect Resets dryRunResult; updates error state on failure.
+ * @ux_state [Loading] -> [Success] or [Error]
+ */
+
+// --- startDryRun:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Performs a dry-run migration to identify potential risks and changes.
+ * @post dryRunResult is populated with the pre-flight analysis.
+ * @pre source/target environments and selected dashboards are valid.
+ * @ux_feedback User sees summary cards + risk block + JSON details after success.
+ * @ux_recovery User can adjust selection and press Dry Run again.
+ * @ux_state [Loading] -> [Success] or [Error]
+ */
+
+// --- MigrationMappingsPage (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Render and orchestrate mapping management UI for source/target environments with backend persistence.
+ * @complexity 3
+ * @critical_trace Frontend scope; Python belief_scope/logger are not applicable in Svelte runtime. Reflective tracing, when added, must use console prefix [ID][REFLECT].
+ * @data_contract Input(Event: update{sourceUuid,targetUuid}) -> Model(MappingPayload); Output(UIState{environments,databases,mappings,suggestions,status})
+ * @invariant Persisted mapping state in backend remains the source of truth for rendered mapping pairs.
+ * @layer UI
+ * @post UI exposes deterministic Idle/Loading/Error/Success states for environment loading, database fetch, and mapping save.
+ * @pre Translation store and API client are available; route is mounted in authenticated UI shell.
+ * @semantics migration, mapping, environment, fuzzy-matching, persistence
+ * @side_effect Performs network I/O to environment/database/mapping endpoints and mutates local UI state.
+ * @test_contract [Valid source/target env IDs + fetch click] -> [Databases, mappings, suggestions rendered]
+ * @test_edge [external_fail] ->[API request rejection => error state]
+ * @test_fixture [migration_mapping_pair] -> file:backend/tests/fixtures/migration_dry_run_fixture.json
+ * @test_invariant [backend_source_of_truth] -> VERIFIED_BY: [save_mapping_success, fetch_env_fail]
+ * @test_scenario [fetch_env_fail] -> [error banner appears and loading state exits]
+ * @ux_feedback Error panel for failed API calls; success panel for persisted mapping confirmation.
+ * @ux_reactivity Svelte bind/on directives and reactive template branches coordinate state transitions (legacy route; no semantic logic mutation in this task).
+ * @ux_recovery Retry via "fetch databases" action; reselection of environments clears stale arrays.
+ * @ux_state Success -> Render green confirmation panel after mapping save.
+ */
+
+// --- MappingsPageScript:Block (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Define imports, state, and handlers that drive migration mappings page FSM.
+ */
+
+// --- Imports:Block (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ */
+
+// --- UiState:Store (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Maintain local page state for environments, fetched databases, mappings, suggestions, and UX messages.
+ */
+
+// --- belief_scope:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Frontend semantic scope wrapper for CRITICAL trace boundaries without changing business behavior.
+ * @data_contract Input(scopeId:string, run:() => Promise) -> Output(Promise)
+ * @post Executes run exactly once and returns/rejects with the same outcome.
+ * @pre scopeId is non-empty and run is callable.
+ * @side_effect Emits trace logs for semantic scope entrance/exit.
+ */
+
+// --- fetchDatabases:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Fetch both environment database catalogs, existing mappings, and suggested matches.
+ * @data_contract Input({sourceEnvId,targetEnvId}) -> Output({sourceDatabases,targetDatabases,mappings,suggestions})
+ * @post fetchingDbs=false and sourceDatabases/targetDatabases/mappings/suggestions updated or error set.
+ * @pre sourceEnvId and targetEnvId are both selected and non-empty.
+ * @side_effect Concurrent network I/O to environments, mappings, and suggestion endpoints; clears transient messages.
+ */
+
+// --- handleUpdate:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Persist a selected mapping pair and reconcile local mapping list by source database UUID.
+ * @data_contract Input(CustomEvent<{sourceUuid:string,targetUuid:string}>) -> Output(MappingRecord persisted + UI feedback)
+ * @post mapping persisted; local mappings replaced for same source UUID; success or error feedback shown.
+ * @pre event.detail includes sourceUuid/targetUuid and matching source/target database records exist.
+ * @side_effect POST /mappings network I/O; mutates mappings/success/error.
+ */
+
+// --- MappingsPageTemplate (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Mapping page template with environment selectors, database mapping table, and action buttons.
+ * @complexity 2
+ */
+
+// --- ProfilePage (frontend/src/routes/profile/+page.svelte)
+/**!
+ * @brief User profile page for viewing and editing personal preferences and settings.
+ * @complexity 3
+ * @layer Page
+ * @ux_feedback Success toast on profile update.
+ * @ux_state Error -> Error message shown.
+ */
+
+// --- ProfileFixtures:Module (frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js)
+/**!
+ * @brief Shared deterministic fixture inputs for profile page integration tests.
+ * @invariant lookupFailedManualFallback.warning is a hardcoded English string; drift risk if i18n key profile.lookup_error changes without updating this fixture.
+ * @semantics fixtures, profile, ui
+ */
+
+// --- ProfilePreferencesIntegrationTest (frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js)
+/**!
+ * @brief Verifies profile page loads preferences and saves them.
+ * @complexity 3
+ * @layer UI (Tests)
+ * @semantics tests, profile, integration, load, save
+ */
+
+// --- ProfileSettingsStateIntegrationTest (frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js)
+/**!
+ * @brief Verifies profile loads preferences, allows changes, and saves correctly.
+ * @complexity 3
+ * @layer UI (Tests)
+ * @semantics tests, profile, integration, load, change, save
+ */
+
+// --- UnifiedReportsPage (frontend/src/routes/reports/+page.svelte)
+/**!
+ * @brief Unified reports page with task-type and status filtering, list selection, detail panel, and resilient UX states for mixed task types.
+ * @complexity 3
+ * @layer Page
+ * @ux_feedback Selecting a report loads its detail in the right panel.
+ * @ux_recovery Retry and clear-filters actions available.
+ * @ux_state Error -> Inline error with retry preserving filter selections.
+ */
+
+// --- ReportPageContractTest:Module (frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js)
+/**!
+ * @brief Protect the LLM report page from self-triggering screenshot load effects.
+ * @layer UI (Tests)
+ * @semantics llm-report, svelte-effect, screenshot-loading, regression-test
+ */
+
+// --- llm_report_screenshot_effect_contract:Function (frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js)
+/**!
+ * @brief Ensure screenshot loading stays untracked from blob-url mutation state.
+ * @post Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.
+ * @pre Report page source exists.
+ */
+
+// --- SettingsPage (frontend/src/routes/settings/+page.svelte)
+/**!
+ * @brief Consolidated Settings Page shell — thin layout that delegates each tab to its own component.
+ * @complexity 4
+ * @deprecated N/A
+ * @layer Page
+ * @post Page exposes consolidated settings tabs; each tab manages its own state.
+ * @pre Route is loaded in the authenticated UI shell.
+ * @rationale Decomposed from 1451→287 lines by extracting 6 tab components and centralizing state in the page shell. The C4 rating reflects the page's role as tab orchestrator with settings load/save lifecycle.
+ * @rejected Keeping all tab content inline was rejected due to INV_7 violations (single contract exceeded 150 lines, cyclomatic complexity > 10).
+ * @replaced_by N/A
+ * @side_effect Loads settings data on mount.
+ * @ux_feedback Toast on save.
+ * @ux_recovery Refresh button reloads settings.
+ * @ux_state Error -> Error banner with retry.
+ */
+
+// --- frontend/src/routes/settings/+page.ts::load (frontend/src/routes/settings/+page.ts)
+/**!
+ */
+
+// --- FeaturesSettings (frontend/src/routes/settings/FeaturesSettings.svelte)
+/**!
+ * @brief Feature flags configuration tab: enable/disable top-level application features.
+ * @complexity 2
+ * @layer UI
+ * @post User can toggle feature flags.
+ * @pre settings object with features config is provided.
+ */
+
+// --- LlmSettings (frontend/src/routes/settings/LlmSettings.svelte)
+/**!
+ * @brief LLM configuration tab: providers, bindings, prompts for chatbot and validation.
+ * @complexity 3
+ * @layer UI
+ * @post User can configure LLM provider bindings and prompts.
+ * @pre settings object with llm config and llm_providers list is provided.
+ * @ux_feedback Toast on save.
+ * @ux_state Loaded -> Full LLM settings panel with provider config, bindings, and prompts.
+ */
+
+// --- LoggingSettings (frontend/src/routes/settings/LoggingSettings.svelte)
+/**!
+ * @brief Logging configuration tab: log level, task log level, belief state toggle.
+ * @complexity 3
+ * @layer UI
+ * @post User can adjust logging levels and toggle belief state.
+ * @pre settings object with logging config is provided.
+ * @ux_feedback Toast on save.
+ * @ux_state Loaded -> Form controls for logging configuration.
+ */
+
+// --- MigrationMappingsTable (frontend/src/routes/settings/MigrationMappingsTable.svelte)
+/**!
+ * @brief Mappings data table with search, filtering, and pagination for migration sync resources. Isolated from the main MigrationSettings to keep each module < 400 lines.
+ * @complexity 3
+ * @layer UI
+ * @post User can search, filter by environment/type, and paginate through resource mappings.
+ * @pre API client initialized, refreshKey provided by parent.
+ * @ux_reactivity Props -> refreshKey triggers reload via $effect.
+ * @ux_state Empty -> "No mappings" row.
+ */
+
+// --- MigrationSettings (frontend/src/routes/settings/MigrationSettings.svelte)
+/**!
+ * @brief Migration sync configuration tab: cron schedule, sync now, mappings table with filtering and pagination.
+ * @complexity 3
+ * @layer UI
+ * @post User can configure sync schedule, trigger sync, and browse resource mappings.
+ * @pre API client initialized.
+ * @ux_feedback Toast on save/sync/failure.
+ * @ux_state Loaded -> Full migration sync panel with schedule and mappings table.
+ */
+
+// --- StorageSettings (frontend/src/routes/settings/StorageSettings.svelte)
+/**!
+ * @brief Storage configuration tab: root path, backup path, repo path.
+ * @complexity 2
+ * @layer UI
+ * @post User can view and edit storage paths.
+ * @pre settings object with storage config is provided.
+ */
+
+// --- SystemSettings (frontend/src/routes/settings/SystemSettings.svelte)
+/**!
+ * @brief System settings tab: timezone configuration and API key management.
+ * @complexity 3
+ * @post User can select the application timezone and manage API keys.
+ * @pre settings object is provided with app_timezone field.
+ */
+
+// --- SettingsPageUxTest:Module (frontend/src/routes/settings/__tests__/settings_page.ux.test.js)
+/**!
+ * @brief Test UX states and transitions
+ * @layer UI (Tests)
+ * @semantics settings, page, ux-tests, save-flow
+ */
+
+// --- AutomationPage (frontend/src/routes/settings/automation/+page.svelte)
+/**!
+ * @brief Settings page for managing validation policies.
+ * @complexity 3
+ * @layer Page
+ * @ux_reactivity State: $state, Derived: $derived.
+ * @ux_state Loading -> Shows a loading spinner while fetching policies.
+ */
+
+// --- loadConfigs:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Fetches existing git configurations.
+ * @post configs state is populated.
+ * @pre Component is mounted.
+ */
+
+// --- handleTest:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Tests connection to a git server with current form data.
+ * @post testing state is managed; toast shown with result.
+ * @pre newConfig contains valid provider, url, and pat.
+ */
+
+// --- handleSave:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Saves a new git configuration.
+ * @post New config is saved to DB and added to configs list.
+ * @pre newConfig is valid and tested.
+ */
+
+// --- handleEdit:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Populates the form with an existing config to edit.
+ * @param {Object} config - Configuration object to edit.
+ * @post Form is populated and isEditing state is set.
+ */
+
+// --- resetForm:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Resets the configuration form.
+ */
+
+// --- loadGiteaRepos:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Loads repositories from selected Gitea config.
+ * @post giteaRepos state updated.
+ * @pre selectedGiteaConfigId is set.
+ */
+
+// --- handleCreateGiteaRepo:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Creates new repository on selected Gitea server.
+ * @post Repository created and repos list reloaded.
+ * @pre selectedGiteaConfigId and newGiteaRepo.name are set.
+ */
+
+// --- handleDeleteGiteaRepo:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Deletes repository from selected Gitea server.
+ * @post Repository deleted and repos list reloaded.
+ * @pre selectedGiteaConfigId is set.
+ */
+
+// --- GitSettingsPageUxTest:Module (frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js)
+/**!
+ * @brief Test UX states and transitions for the Git Settings page
+ * @layer UI (Tests)
+ * @semantics settings, git, page, ux-tests, form, toast
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::readTabFromUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::writeTabToUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeTab (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeLlmSettings (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::isDashboardValidationBindingValid (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::getProviderById (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeSupersetBaseUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::resolveEnvStage (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- StorageIndexPage (frontend/src/routes/storage/+page.svelte)
+/**!
+ * @brief Redirect to the backups page as the default storage view.
+ * @complexity 2
+ * @invariant Always redirects to /storage/backups.
+ * @layer Page
+ * @ux_state Redirecting -> Immediately transfers the user to /storage/backups.
+ */
+
+// --- BackupsRedirectPage (frontend/src/routes/storage/backups/+page.svelte)
+/**!
+ * @brief Temporary switch to legacy storage browser for backup UX validation.
+ * @complexity 3
+ * @invariant Always redirects to /tools/storage.
+ * @layer Page
+ * @semantics storage, backups, redirect, legacy
+ * @ux_state Redirecting -> Immediately transfers the user to the legacy storage browser.
+ */
+
+// --- fetchEnvironments:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Fetches the list of available environments.
+ * @post environments array is populated, selectedEnvId is set to first env if available.
+ * @pre None.
+ */
+
+// --- fetchDashboards:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Fetches dashboards for a specific environment.
+ * @post dashboards array is populated with metadata for the selected environment.
+ * @pre envId is a valid environment ID.
+ */
+
+// --- filterDashboardsWithRepositories:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Keep only dashboards that already have initialized Git repositories.
+ * @post Returns dashboards with status != NO_REPO.
+ * @pre dashboards list is loaded for selected environment.
+ */
+
+// --- BackupsPage (frontend/src/routes/tools/backups/+page.svelte)
+/**!
+ * @brief Entry point for the Backup Management interface.
+ * @complexity 3
+ * @layer Page
+ * @semantics backup, management, tools, workspace
+ * @ux_state Error -> Nested manager feedback remains contained within the backup workspace.
+ */
+
+// --- DebugToolPage (frontend/src/routes/tools/debug/+page.svelte)
+/**!
+ * @brief Page for system diagnostics and debugging.
+ * @complexity 3
+ * @layer UI
+ * @semantics debug, diagnostics, tool, task-runner
+ * @ux_state Error -> Nested diagnostic failures remain scoped to the debug workspace.
+ */
+
+// --- MapperToolPage (frontend/src/routes/tools/mapper/+page.svelte)
+/**!
+ * @brief Page for the dataset column mapper tool.
+ * @complexity 3
+ * @layer UI
+ * @semantics mapper, column, dataset, tool
+ * @ux_state Error -> Mapping-specific validation or execution failures remain visible without route changes.
+ */
+
+// --- loadFiles:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Fetches the list of files from the server.
+ * @post Updates the `files` array with the latest data.
+ * @pre currentPath is a valid storage path or empty for root.
+ */
+
+// --- resolveStorageQueryFromPath:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Splits UI path into storage API category and category-local subpath.
+ * @post Returns {category, subpath} compatible with /api/storage/files.
+ * @pre uiPath may be empty or start with backups/repositorys.
+ */
+
+// --- handleDelete:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Handles the file deletion process.
+ * @param {CustomEvent} event - The delete event containing category and path.
+ * @post File is deleted and file list is refreshed.
+ * @pre The event contains valid category and path.
+ */
+
+// --- handleNavigate:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Updates the current path and reloads files when navigating into a directory.
+ * @param {CustomEvent} event - The navigation event containing the new path.
+ * @post currentPath is updated and files are reloaded.
+ * @pre The event contains a valid path string.
+ */
+
+// --- navigateUp:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Navigates one level up in the directory structure.
+ * @post currentPath is moved up one directory level.
+ * @pre currentPath is not root.
+ */
+
+// --- updateUploadCategory:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Keeps upload category aligned with the currently viewed top-level folder.
+ * @post uploadCategory is either backups or repositorys.
+ * @pre currentPath can be empty or a slash-delimited path.
+ */
+
+// --- TranslateJobList (frontend/src/routes/translate/+page.svelte)
+/**!
+ * @complexity 3
+ * @type {string} idle | loading | empty | populated | error
+ */
+
+// --- TranslationJobConfig (frontend/src/routes/translate/[id]/+page.svelte)
+/**!
+ * @brief Translation job configuration page - orchestrates form state, datasource loading, LLM settings, run/schedule tabs.
+ * @complexity 4
+ * @deprecated N/A — active page.
+ * @rationale Kept as C4 orchestration due to complex lifecycle: load→configure→validate→save→run→monitor across multiple tabs and API interactions.
+ * @rejected Extracting all sub-tabs into separate page components was rejected due to deep state coupling between datasource selection, column loading, and form validation — would require a global store or excessive prop drilling.
+ * @replaced_by N/A — no replacement.
+ * @type {string} idle | loading | configured | saving | validation_error | datasource_unavailable
+ */
+
+// --- DictionariesPage (frontend/src/routes/translate/dictionaries/+page.svelte)
+/**!
+ * @complexity 3
+ */
+
+// --- DictionaryDetailPage (frontend/src/routes/translate/dictionaries/[id]/+page.svelte)
+/**!
+ * @complexity 3
+ */
+
+// --- TranslateHistoryPage (frontend/src/routes/translate/history/+page.svelte)
+/**!
+ * @complexity 3
+ * @type {'idle'|'loading'|'empty'|'populated'|'detail_open'|'pruned'}
+ */
+
+// --- ValidationTaskList (frontend/src/routes/validation/+page.svelte)
+/**!
+ * @brief Validation task list page with status filter, task cards, and create/duplicate/delete actions.
+ * @complexity 3
+ * @param {string} status
+ * @rationale Card layout chosen over table because tasks have rich metadata (schedule, provider, last run status, environment) that does not fit into table columns without excessive horizontal scrolling.
+ * @rejected Table view for task list rejected — dashboard_id + environment_id + provider_id + schedule + last_run_status creates too many columns for a table; cards show all metadata vertically.
+ * @type {'idle'|'loading'|'empty'|'populated'|'error'|'filtered_empty'}
+ * @ux_state Populated -> Task cards grid
+ */
+
+// --- ValidationTaskConfig (frontend/src/routes/validation/[id]/+page.svelte)
+/**!
+ * @brief Validation task configuration page with Config and History tabs. Handles new and edit modes.
+ * @complexity 4
+ * @rationale 2-tab design separates task configuration from run history — users can edit settings (name, dashboard, provider, schedule) without scrolling past potentially long run history data.
+ * @rejected Single scrollable page with config above history rejected — task config form is long (Basic Info + Dashboard & Environment + LLM Provider + Schedule + Active toggle); history would be pushed far below the fold.
+ * @type {'idle'|'loading'|'configured'|'saving'|'error'|'not_found'}
+ * @ux_feedback Toast notifications on save/run/delete actions
+ * @ux_reactivity Props -> $props(), URL params -> $page.params, LocalState -> $state(...)
+ * @ux_recovery Retry button on load errors, Go Back on not found
+ * @ux_state Configured -> Form with Save/Cancel/Run Now buttons
+ */
+
+// --- ValidationHistory (frontend/src/routes/validation/history/+page.svelte)
+/**!
+ * @brief Validation run history page with filters, metrics summary, and run cards.
+ * @complexity 3
+ * @rationale Filter-driven design with 6 filter dimensions (task, status, dashboard, environment, date from/to) allows users to narrow runs for debugging — essential when hundreds of runs accumulate over time.
+ * @rejected Unfiltered chronological list rejected — users need to filter by task/status/environment to find relevant runs among hundreds; without filters the page is unusable at scale.
+ * @type {'idle'|'loading'|'empty'|'filtered_empty'|'populated'|'error'}
+ * @ux_state Populated -> Metrics grid + run cards + pagination
+ */
+
+// --- GitServiceContractTests (frontend/src/services/__tests__/gitService.test.js)
+/**!
+ * @brief API client tests ensuring correct endpoints are called per contract for Git service operations.
+ * @complexity 3
+ */
+
+// --- gitServiceContractTests:Module (frontend/src/services/__tests__/gitService.test.js)
+/**!
+ * @brief API client tests ensuring correct endpoints are called per contract
+ * @layer Tests
+ * @post Returns promotion metadata
+ * @pre Repo initialized
+ * @semantics git-service, api-client, contract-tests
+ */
+
+// --- AdminService (frontend/src/services/adminService.js)
+/**!
+ * @brief Service for Admin-related API calls including User and Role management, AD group mappings, and logging configuration.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- adminService:Module (frontend/src/services/adminService.js)
+/**!
+ * @brief Service for Admin-related API calls (User and Role management).
+ * @invariant All requests must include valid Admin JWT token (handled by api client).
+ * @layer Service
+ * @semantics admin, users, roles, ad-mappings, api
+ */
+
+// --- getUsers:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all registered users from the backend.
+ * @post Returns an array of user objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getUsers (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of user objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates a new local user.
+ * @param {Object} userData - User details (username, email, password, roles, is_active).
+ * @post New user record created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createUser (frontend/src/services/adminService.js)
+/**!
+ * @post New user record created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- getRoles:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all available system roles.
+ * @post Returns an array of role objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getRoles (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of role objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- getADGroupMappings:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches mappings between AD groups and local roles.
+ * @post Returns an array of AD group mapping objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getADGroupMappings (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of AD group mapping objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createADGroupMapping:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates or updates an AD group to Role mapping.
+ * @param {Object} mappingData - Mapping details (ad_group, role_id).
+ * @post New or updated mapping created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createADGroupMapping (frontend/src/services/adminService.js)
+/**!
+ * @post New or updated mapping created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- updateUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates an existing user.
+ * @param {Object} userData - Updated user data.
+ * @post User record updated in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateUser (frontend/src/services/adminService.js)
+/**!
+ * @post User record updated in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- deleteUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Deletes a user.
+ * @param {string} userId - Target user ID.
+ * @post User record removed from auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::deleteUser (frontend/src/services/adminService.js)
+/**!
+ * @post User record removed from auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates a new role.
+ * @param {Object} roleData - Role details (name, description, permissions).
+ * @post New role created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createRole (frontend/src/services/adminService.js)
+/**!
+ * @post New role created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- updateRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates an existing role.
+ * @param {Object} roleData - Updated role data.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateRole (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- deleteRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Deletes a role.
+ * @param {string} roleId - Target role ID.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::deleteRole (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- getPermissions:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all available permissions.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getPermissions (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- getLoggingConfig:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches current logging configuration.
+ * @return {Promise} - Logging config with level, task_log_level, enable_belief_state.
+ */
+
+// --- frontend/src/services/adminService.js::getLoggingConfig (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- updateLoggingConfig:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates logging configuration.
+ * @param {Object} configData - Logging config (level, task_log_level, enable_belief_state).
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateLoggingConfig (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- GitUtils (frontend/src/services/git-utils.js)
+/**!
+ * @brief Shared utility functions extracted from GitManager.svelte.
+ * @complexity 2
+ */
+
+// --- frontend/src/services/git-utils.js::normalizeEnvStage (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::stageBadgeClass (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolveCurrentEnvironmentId (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::applyGitflowStageDefaults (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::isNumericDashboardRef (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::getSelectedConfig (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolveDefaultConfig (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolvePushProviderLabel (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::extractHttpHost (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::buildSuggestedRepoName (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::tryParseJsonObject (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::extractUnfinishedMergeContext (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- StorageService (frontend/src/services/storageService.js)
+/**!
+ * @brief Frontend API client for file storage management including list, upload, download, and delete operations.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- storageService:Module (frontend/src/services/storageService.js)
+/**!
+ * @brief Frontend API client for file storage management.
+ * @layer Service
+ * @semantics storage, api, client
+ */
+
+// --- getStorageAuthHeaders:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Returns headers with Authorization for storage API calls.
+ * @note Unlike api.js getAuthHeaders, this doesn't set Content-Type
+ * @return {Object} Headers object with Authorization if token exists.
+ */
+
+// --- frontend/src/services/storageService.js::getStorageAuthHeaders (frontend/src/services/storageService.js)
+/**!
+ */
+
+// --- encodeStoragePath:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Encodes a storage-relative path preserving slash separators.
+ * @param {string} path - Relative storage path.
+ * @return {string} Encoded path safe for URL segments.
+ */
+
+// --- frontend/src/services/storageService.js::encodeStoragePath (frontend/src/services/storageService.js)
+/**!
+ */
+
+// --- listFiles:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Fetches the list of files for a given category and subpath.
+ * @param {string} [path] - Optional subpath filter.
+ * @post Returns a promise resolving to an array of StoredFile objects.
+ * @pre category and path should be valid strings if provided.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::listFiles (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a promise resolving to an array of StoredFile objects.
+ * @pre category and path should be valid strings if provided.
+ */
+
+// --- uploadFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Uploads a file to the storage system.
+ * @param {string} [path] - Target subpath.
+ * @post Returns a promise resolving to the metadata of the uploaded file.
+ * @pre file must be a valid File object; category must be specified.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::uploadFile (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a promise resolving to the metadata of the uploaded file.
+ * @pre file must be a valid File object; category must be specified.
+ */
+
+// --- deleteFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Deletes a file or directory from storage.
+ * @param {string} path - Relative path of the item.
+ * @post The specified file or directory is removed from storage.
+ * @pre category and path must identify an existing file or directory.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::deleteFile (frontend/src/services/storageService.js)
+/**!
+ * @post The specified file or directory is removed from storage.
+ * @pre category and path must identify an existing file or directory.
+ */
+
+// --- downloadFileUrl:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Returns the URL for downloading a file.
+ * @note Downloads use browser navigation, so auth is handled via cookies
+ * @param {string} path - Relative path of the file.
+ * @post Returns a valid API URL for file download.
+ * @pre category and path must identify an existing file.
+ * @return {string}
+ */
+
+// --- frontend/src/services/storageService.js::downloadFileUrl (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a valid API URL for file download.
+ * @pre category and path must identify an existing file.
+ */
+
+// --- downloadFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Downloads a file using authenticated fetch and saves it in browser.
+ * @param {string} [filename] - Optional preferred filename.
+ * @post Browser download is triggered or an Error is thrown.
+ * @pre category/path identify an existing file and user has READ permission.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::downloadFile (frontend/src/services/storageService.js)
+/**!
+ * @post Browser download is triggered or an Error is thrown.
+ * @pre category/path identify an existing file and user has READ permission.
+ */
+
+// --- TaskService (frontend/src/services/taskService.js)
+/**!
+ * @brief Service for Task Management API interactions: listing, fetching details, resuming, resolving, and clearing tasks.
+ * @complexity 3
+ * @layer Service
+ */
+
+// --- getTasks:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch a list of tasks with pagination and optional status filter.
+ * @post Returns a promise resolving to a list of tasks.
+ * @pre limit and offset are numbers.
+ */
+
+// --- frontend/src/services/taskService.js::getTasks (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- getTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch details for a specific task.
+ * @post Returns a promise resolving to task details.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::getTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- getTaskLogs:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch logs for a specific task.
+ * @post Returns a promise resolving to a list of log entries.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::getTaskLogs (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- resumeTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Resume a task that is awaiting input (e.g., passwords).
+ * @post Returns a promise resolving to the updated task object.
+ * @pre taskId and passwords must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::resumeTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- resolveTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Resolve a task that is awaiting mapping.
+ * @post Returns a promise resolving to the updated task object.
+ * @pre taskId and resolutionParams must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::resolveTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- clearTasks:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Clear tasks based on status.
+ * @post Returns a promise that resolves when tasks are cleared.
+ * @pre status is a string or null.
+ */
+
+// --- frontend/src/services/taskService.js::clearTasks (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- ToolsService (frontend/src/services/toolsService.js)
+/**!
+ * @brief Service for generic Task API communication used by Tools — run tasks and poll status.
+ * @complexity 2
+ */
+
+// --- runTask:Function (frontend/src/services/toolsService.js)
+/**!
+ * @brief Start a new task for a given plugin.
+ * @post Returns a promise resolving to the task instance.
+ * @pre pluginId and params must be provided.
+ */
+
+// --- frontend/src/services/toolsService.js::runTask (frontend/src/services/toolsService.js)
+/**!
+ */
+
+// --- getTaskStatus:Function (frontend/src/services/toolsService.js)
+/**!
+ * @brief Fetch details for a specific task (to poll status or get result).
+ * @post Returns a promise resolving to task details.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/toolsService.js::getTaskStatus (frontend/src/services/toolsService.js)
+/**!
+ */
+
+// --- BackupTypes (frontend/src/types/backup.ts)
+/**!
+ * @complexity 1
+ */
+
+// --- frontend/src/types/backup.ts::Backup (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- BackupTypes:Module (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- DashboardTypes (frontend/src/types/dashboard.ts)
+/**!
+ * @complexity 1
+ */
+
+// --- DashboardTypes:Module (frontend/src/types/dashboard.ts)
+/**!
+ * @brief TypeScript interfaces for Dashboard entities
+ * @layer Domain
+ */
+
+// --- frontend/src/types/dashboard.ts::DashboardMetadata (frontend/src/types/dashboard.ts)
+/**!
+ */
+
+// --- MaintenanceStoreTests (frontend/tests/maintenance-store.test.ts)
+/**!
+ * @brief Unit tests for MaintenanceStore runes-based store.
+ * @complexity 2
+ */
+
+// --- MaintenanceComponentTests (frontend/tests/maintenance.test.ts)
+/**!
+ * @brief Component tests for MaintenanceEventsTable and DashboardMaintenanceBadge.
+ * @complexity 2
+ */
+
+// --- MergeSpec (merge_spec.py)
+/**!
+ * @complexity 2
+ * @layer Infra
+ */
+
+// --- merge_spec (merge_spec.py)
+/**!
+ * @complexity 2
+ * @layer Infra
+ */
+
+// --- BuildOfflineDockerBundle (scripts/build_offline_docker_bundle.sh)
+/**!
+ * @brief Thin wrapper — delegates to ./build.sh bundle (.tar.xz output)
+ * @complexity 1
+ * @rationale Unified into build.sh to avoid confusion; kept for backward compat.
+ */
+
+// --- venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp::ThreadState (venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp)
+/**!
+ */
+
+// --- venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp::PyFatalError (venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp)
+/**!
+ */
+
diff --git a/docs/api/doxygen_stripped.c b/docs/api/doxygen_stripped.c
new file mode 100644
index 00000000..bd23d951
--- /dev/null
+++ b/docs/api/doxygen_stripped.c
@@ -0,0 +1,18019 @@
+// AXIOM Doc Generator — Generated docs
+// Format: doxygen Mode: stripped Contracts: 3195
+// Usage: run through `jsdoc --pedantic` or `doxygen -W` for validation
+
+// --- SrcRoot (backend/src/__init__.py)
+/**!
+ * @brief Canonical backend package root for application, scripts, and tests.
+ */
+
+// --- src.api (backend/src/api/__init__.py)
+/**!
+ * @brief Backend API package root.
+ */
+
+// --- AuthApi (backend/src/api/auth.py)
+/**!
+ * @brief Authentication API endpoints.
+ * @invariant All auth endpoints must return consistent error codes.
+ * @post FastAPI app instance with auth routes registered.
+ * @pre Python environment and dependencies installed; database available.
+ */
+
+// --- login_for_access_token (backend/src/api/auth.py)
+/**!
+ * @brief Authenticates a user and returns a JWT access token.
+ * @post Returns a Token object on success.
+ * @pre form_data contains username and password.
+ */
+
+// --- read_users_me (backend/src/api/auth.py)
+/**!
+ * @brief Retrieves the profile of the currently authenticated user.
+ * @post Returns the current user's data.
+ * @pre Valid JWT token provided.
+ */
+
+// --- logout (backend/src/api/auth.py)
+/**!
+ * @brief Logs out the current user (placeholder for session revocation).
+ * @post Returns success message.
+ * @pre Valid JWT token provided.
+ */
+
+// --- login_adfs (backend/src/api/auth.py)
+/**!
+ * @brief Initiates the ADFS OIDC login flow.
+ * @post Redirects the user to ADFS.
+ */
+
+// --- auth_callback_adfs (backend/src/api/auth.py)
+/**!
+ * @brief Handles the callback from ADFS after successful authentication.
+ * @post Provisions user JIT and returns session token.
+ */
+
+// --- ApiRoutesModule (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Provide lazy route module loading to avoid heavyweight imports during tests.
+ * @invariant Only names listed in __all__ are importable via __getattr__.
+ * @post Route modules are lazily loadable via __getattr__
+ * @pre FastAPI app initialized, route modules available in package
+ */
+
+// --- Route_Group_Contracts (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Declare the canonical route-module registry used by lazy imports and app router inclusion.
+ */
+
+// --- ApiRoutesGetAttr (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Lazily import route module by attribute name.
+ * @post Returns imported submodule or raises AttributeError.
+ * @pre name is module candidate exposed in __all__.
+ */
+
+// --- RoutesTestsConftest (backend/src/api/routes/__tests__/conftest.py)
+/**!
+ * @brief Shared low-fidelity test doubles for API route test modules.
+ */
+
+// --- AssistantApiTests (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Validate assistant API endpoint logic via direct async handler invocation.
+ * @invariant Every test clears assistant in-memory state before execution.
+ */
+
+// --- _dataset_review_session (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Build minimal owned dataset-review session fixture for assistant scoped routing tests.
+ */
+
+// --- _await_none (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Async helper returning None for planner fallback tests.
+ */
+
+// --- test_unknown_command_returns_needs_clarification (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Unknown command should return clarification state and unknown intent.
+ */
+
+// --- test_capabilities_question_returns_successful_help (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Capability query should return deterministic help response.
+ */
+
+// --- test_assistant_message_request_accepts_dataset_review_session_binding (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Assistant request schema should accept active dataset review session binding for scoped orchestration.
+ */
+
+// --- test_dataset_review_scoped_message_uses_masked_filter_context (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant context should mask imported-filter raw values before assistant-visible metadata is persisted.
+ */
+
+// --- test_dataset_review_scoped_command_returns_confirmation_for_mapping_approval (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant commands should route dataset-review mapping approvals into confirmation workflow with bound session metadata.
+ */
+
+// --- test_dataset_review_scoped_command_routes_field_semantics_update (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant commands should route semantic field updates through explicit confirmation metadata.
+ */
+
+// --- TestAssistantAuthz (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Verify assistant confirmation ownership, expiration, and deny behavior for restricted users.
+ * @invariant Security-sensitive flows fail closed for unauthorized actors.
+ */
+
+// --- _run_async (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Execute async endpoint handler in synchronous test context.
+ * @post Returns coroutine result or raises propagated exception.
+ * @pre coroutine is awaitable endpoint invocation.
+ */
+
+// --- _FakeTask (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Lightweight task model used for assistant authz tests.
+ * @post Returns task with provided id, status, and user_id accessible as attributes.
+ * @pre task_id is non-empty string.
+ */
+
+// --- _FakeConfigManager (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Provide deterministic environment aliases required by intent parsing.
+ * @invariant get_config() is absent; only get_environments() is emulated. Safe only for routes that do not invoke get_config() on the injected ConfigManager — verify against assistant.py route handler code before adding new test cases that use this fake.
+ * @post get_environments() returns two deterministic SimpleNamespace stubs with id/name.
+ * @pre No external config or DB state is required.
+ */
+
+// --- _other_admin_user (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Build second admin principal fixture for ownership tests.
+ * @post Returns alternate admin-like user stub.
+ * @pre Ownership mismatch scenario needs distinct authenticated actor.
+ */
+
+// --- _limited_user (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Build limited principal without required assistant execution privileges.
+ * @post Returns restricted user stub.
+ * @pre Permission denial scenario needs non-admin actor.
+ */
+
+// --- _FakeDb (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief In-memory DB session double constrained to assistant message/confirmation/audit persistence paths.
+ * @invariant query/add/merge are intentionally narrow and must not claim full SQLAlchemy Session semantics.
+ */
+
+// --- _clear_assistant_state (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Reset assistant process-local state between test cases.
+ * @post Assistant in-memory state dictionaries are cleared.
+ * @pre Assistant globals may contain state from prior tests.
+ */
+
+// --- test_confirmation_owner_mismatch_returns_403 (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Confirm endpoint should reject requests from user that does not own the confirmation token.
+ * @post Second actor receives 403 on confirm operation.
+ * @pre Confirmation token is created by first admin actor.
+ */
+
+// --- test_expired_confirmation_cannot_be_confirmed (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Expired confirmation token should be rejected and not create task.
+ * @post Confirm endpoint raises 400 and no task is created.
+ * @pre Confirmation token exists and is manually expired before confirm request.
+ */
+
+// --- test_limited_user_cannot_launch_restricted_operation (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Limited user should receive denied state for privileged operation.
+ * @post Assistant returns denied state and does not execute operation.
+ * @pre Restricted user attempts dangerous deploy command.
+ */
+
+// --- TestCleanReleaseApi (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Contract tests for clean release checks and reports endpoints.
+ * @invariant API returns deterministic payload shapes for checks and reports.
+ */
+
+// --- test_start_check_and_get_status_contract (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate checks start endpoint returns expected identifiers and status endpoint reflects the same run.
+ */
+
+// --- test_get_report_not_found_returns_404 (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate reports endpoint returns 404 for an unknown report identifier.
+ */
+
+// --- test_get_report_success (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate reports endpoint returns persisted report payload for an existing report identifier.
+ */
+
+// --- test_prepare_candidate_api_success (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate candidate preparation endpoint returns prepared status and manifest identifier on valid input.
+ */
+
+// --- TestCleanReleaseLegacyCompat (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Compatibility tests for legacy clean-release API paths retained during v2 migration.
+ */
+
+// --- _seed_legacy_repo (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Seed in-memory repository with minimum trusted data for legacy endpoint contracts.
+ * @post Candidate, policy, registry and manifest are available for legacy checks flow.
+ * @pre Repository is empty.
+ */
+
+// --- test_legacy_prepare_endpoint_still_available (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Verify legacy prepare endpoint remains reachable and returns a status payload.
+ */
+
+// --- test_legacy_checks_endpoints_still_available (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Verify legacy checks start/status endpoints remain available during v2 transition.
+ */
+
+// --- TestCleanReleaseSourcePolicy (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Validate API behavior for source isolation violations in clean release preparation.
+ * @invariant External endpoints must produce blocking violation entries.
+ */
+
+// --- _repo_with_seed_data (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Seed repository with candidate, registry, and active policy for source isolation test flow.
+ */
+
+// --- test_prepare_candidate_blocks_external_source (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Verify candidate preparation is blocked when at least one source host is external to the trusted registry.
+ */
+
+// --- CleanReleaseV2ApiTests (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief API contract tests for redesigned clean release endpoints.
+ */
+
+// --- test_candidate_registration_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate candidate registration endpoint creates a draft candidate with expected identifier contract.
+ */
+
+// --- test_artifact_import_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate artifact import endpoint accepts candidate artifacts and returns success status payload.
+ */
+
+// --- test_manifest_build_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate manifest build endpoint produces manifest payload linked to the target candidate.
+ */
+
+// --- CleanReleaseV2ReleaseApiTests (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief API contract test scaffolding for clean release approval and publication endpoints.
+ */
+
+// --- _seed_candidate_and_passed_report (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Seed repository with approvable candidate and passed report for release endpoint contracts.
+ */
+
+// --- test_release_approve_and_publish_revoke_contract (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Verify approve, publish, and revoke endpoints preserve expected release lifecycle contract.
+ */
+
+// --- test_release_reject_contract (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Verify reject endpoint returns successful rejection decision payload.
+ */
+
+// --- DashboardsApiTests (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Unit tests for dashboards API endpoints.
+ */
+
+// --- test_get_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns a populated response that satisfies the schema contract.
+ * @post Response matches DashboardsResponse schema
+ * @pre env_id exists
+ * @test GET /api/dashboards returns 200 and valid schema
+ */
+
+// --- test_get_dashboards_with_search (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing applies the search filter and returns only matching rows.
+ * @post Filtered result count must match search
+ * @pre search parameter provided
+ * @test GET /api/dashboards filters by search term
+ */
+
+// --- test_get_dashboards_empty (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns an empty payload for an environment without dashboards.
+ */
+
+// --- test_get_dashboards_superset_failure (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing surfaces a 503 contract when Superset access fails.
+ */
+
+// --- test_get_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns 404 when the requested environment does not exist.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test GET /api/dashboards returns 404 if env_id missing
+ */
+
+// --- test_get_dashboards_invalid_pagination (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing rejects invalid pagination parameters with 400 responses.
+ * @post Returns 400 error
+ * @pre page < 1 or page_size > 100
+ * @test GET /api/dashboards returns 400 for invalid page/page_size
+ */
+
+// --- test_get_dashboard_detail_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard detail returns charts and datasets for an existing dashboard.
+ * @test GET /api/dashboards/{id} returns dashboard detail with charts and datasets
+ */
+
+// --- test_get_dashboard_detail_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard detail returns 404 when the requested environment is missing.
+ * @test GET /api/dashboards/{id} returns 404 for missing environment
+ */
+
+// --- test_migrate_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard migration request creates an async task and returns its identifier.
+ * @post Returns task_id and create_task was called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@POST/@SIDE_EFFECT: create_task was called
+ * @pre Valid source_env_id, target_env_id, dashboard_ids
+ * @test POST /api/dashboards/migrate creates migration task
+ */
+
+// --- test_migrate_dashboards_no_ids (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard migration rejects empty dashboard identifier lists.
+ * @post Returns 400 error
+ * @pre dashboard_ids is empty
+ * @test POST /api/dashboards/migrate returns 400 for empty dashboard_ids
+ */
+
+// --- test_migrate_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate migration creation returns 404 when the source environment cannot be resolved.
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- test_backup_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard backup request creates an async backup task and returns its identifier.
+ * @post Returns task_id and create_task was called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@POST/@SIDE_EFFECT: create_task was called
+ * @pre Valid env_id, dashboard_ids
+ * @test POST /api/dashboards/backup creates backup task
+ */
+
+// --- test_backup_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate backup task creation returns 404 when the target environment is missing.
+ * @pre env_id is a valid environment ID
+ */
+
+// --- test_get_database_mappings_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate database mapping suggestions are returned for valid source and target environments.
+ * @post Returns list of database mappings
+ * @pre Valid source_env_id, target_env_id
+ * @test GET /api/dashboards/db-mappings returns mapping suggestions
+ */
+
+// --- test_get_database_mappings_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate database mapping suggestions return 404 when either environment is missing.
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- test_get_dashboard_tasks_history_filters_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard task history returns only related backup and LLM tasks.
+ * @test GET /api/dashboards/{id}/tasks returns backup and llm tasks for dashboard
+ */
+
+// --- test_get_dashboard_thumbnail_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard thumbnail endpoint proxies image bytes and content type from Superset.
+ * @test GET /api/dashboards/{id}/thumbnail proxies image bytes from Superset
+ */
+
+// --- _build_profile_preference_stub (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Creates profile preference payload stub for dashboards filter contract tests.
+ * @post Returns object compatible with ProfileService.get_my_preference contract.
+ * @pre username can be empty; enabled indicates profile-default toggle state.
+ */
+
+// --- _matches_actor_case_insensitive (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Applies trim + case-insensitive owners OR modified_by matching used by route contract tests.
+ * @post Returns True when bound username matches any owner or modified_by.
+ * @pre owners can be None or list-like values.
+ */
+
+// --- test_get_dashboards_profile_filter_contract_owners_or_modified_by (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering matches owner and modifier aliases using normalized Superset actor values.
+ * @post Response includes only matching dashboards and effective_profile_filter metadata.
+ * @pre Current user has enabled profile-default preference and bound username.
+ * @test GET /api/dashboards applies profile-default filter with owners OR modified_by trim+case-insensitive semantics.
+ */
+
+// --- test_get_dashboards_override_show_all_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate override_show_all bypasses profile-default filtering without changing dashboard list semantics.
+ * @post Response remains unfiltered and effective_profile_filter.applied is false.
+ * @pre Profile-default preference exists but override_show_all=true query is provided.
+ * @test GET /api/dashboards honors override_show_all and disables profile-default filter for current page.
+ */
+
+// --- test_get_dashboards_profile_filter_no_match_results_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering returns an empty dashboard page when no actor aliases match the bound user.
+ * @post Response total is 0 with deterministic pagination and active effective_profile_filter metadata.
+ * @pre Profile-default preference is enabled with bound username and all dashboards are non-matching.
+ * @test GET /api/dashboards returns empty result set when profile-default filter is active and no dashboard actors match.
+ */
+
+// --- test_get_dashboards_page_context_other_disables_profile_default (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate non-dashboard page contexts suppress profile-default filtering and preserve unfiltered results.
+ * @post Response remains unfiltered and metadata reflects source_page=other.
+ * @pre Profile-default preference exists but page_context=other query is provided.
+ * @test GET /api/dashboards does not auto-apply profile-default filter outside dashboards_main page context.
+ */
+
+// --- test_get_dashboards_profile_filter_matches_display_alias_without_detail_fanout (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering reuses resolved Superset display aliases without triggering per-dashboard detail fanout.
+ * @post Route matches by alias (`Superset Admin`) and does not call `SupersetClient.get_dashboard` in list filter path.
+ * @pre Profile-default filter is active, bound username is `admin`, dashboard actors contain display labels.
+ * @test GET /api/dashboards resolves Superset display-name alias once and filters without per-dashboard detail calls.
+ */
+
+// --- test_get_dashboards_profile_filter_matches_owner_object_payload_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering accepts owner object payloads once aliases resolve to the bound Superset username.
+ * @post Response keeps dashboards where owner object resolves to bound username alias.
+ * @pre Profile-default preference is enabled and owners list contains dict payloads.
+ * @test GET /api/dashboards profile-default filter matches Superset owner object payloads.
+ */
+
+// --- DatasetReviewApiTests (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify backend US1 dataset review lifecycle, export, parsing, and dictionary-resolution contracts.
+ */
+
+// --- _make_user (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_config_manager (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_us2_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_us3_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_preview_ready_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- dataset_review_api_dependencies (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- test_parse_superset_link_dashboard_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard links recover dataset context and preserve explicit partial-recovery markers.
+ */
+
+// --- test_parse_superset_link_dashboard_slug_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard slug links resolve through dashboard detail endpoints and recover dataset context.
+ */
+
+// --- test_parse_superset_link_dashboard_permalink_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard permalink links no longer fail parsing and preserve permalink filter state for partial recovery.
+ */
+
+// --- test_parse_superset_link_dashboard_permalink_recovers_dataset_from_nested_dashboard_state (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify permalink state with nested dashboard id recovers dataset binding and keeps imported filters.
+ */
+
+// --- test_resolve_from_dictionary_prefers_exact_match (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify trusted dictionary exact matches outrank fuzzy candidates and unresolved fields stay explicit.
+ */
+
+// --- test_orchestrator_start_session_preserves_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify session start persists usable recovery-required state when Superset intake is partial.
+ */
+
+// --- test_orchestrator_start_session_bootstraps_recovery_state (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify session start persists recovered filters, template variables, and initial execution mappings for review workspace bootstrap.
+ */
+
+// --- test_start_session_endpoint_returns_created_summary (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify POST session lifecycle endpoint returns a persisted ownership-scoped summary.
+ */
+
+// --- test_get_session_detail_export_and_lifecycle_endpoints (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify lifecycle get/patch/delete plus documentation and validation exports remain ownership-scoped and usable.
+ */
+
+// --- test_get_clarification_state_returns_empty_payload_when_session_has_no_record (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Clarification state endpoint should return a non-blocking empty payload when the session has no clarification aggregate yet.
+ */
+
+// --- test_us2_clarification_endpoints_persist_answer_and_feedback (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Clarification endpoints should expose one current question, persist the answer before advancement, and store feedback on the answer audit record.
+ */
+
+// --- test_us2_field_semantic_override_lock_unlock_and_feedback (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Semantic field endpoints should apply manual overrides with lock/provenance invariants and persist feedback independently.
+ */
+
+// --- test_us3_mapping_patch_approval_preview_and_launch_endpoints (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief US3 execution endpoints should persist manual overrides, preserve explicit approval semantics, return contract-shaped preview truth, and expose audited launch handoff.
+ */
+
+// --- test_us3_preview_response_propagates_refreshed_session_version_for_launch_follow_up (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Preview response should expose the refreshed session version so the normal preview-then-launch UI flow can satisfy optimistic locking without a forced full reload.
+ */
+
+// --- test_us3_preview_endpoint_returns_failed_preview_without_false_dashboard_not_found_contract_drift (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Preview endpoint should preserve API contract and surface generic upstream preview failures without fabricating dashboard-not-found semantics for non-dashboard 404s.
+ */
+
+// --- test_mutation_endpoints_surface_session_version_conflict_payload (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Dataset review mutation endpoints should return deterministic 409 conflict semantics when optimistic-lock versions are stale.
+ */
+
+// --- test_update_session_surfaces_commit_time_session_version_conflict_payload (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Session lifecycle mutation should return deterministic 409 conflict semantics when commit-time optimistic locking rejects a stale write.
+ */
+
+// --- test_execution_snapshot_includes_recovered_imported_filters_without_template_mapping (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Recovered imported filters with values should flow into preview filter context even when no template variable mapping exists.
+ */
+
+// --- test_execution_snapshot_preserves_mapped_template_variables_and_filter_context (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Mapped template variables should still populate template params while contributing their effective filter context.
+ */
+
+// --- test_execution_snapshot_skips_partial_imported_filters_without_values (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Partial imported filters without raw or normalized values must not emit bogus active preview filters.
+ */
+
+// --- test_us3_launch_endpoint_requires_launch_permission (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Launch endpoint should enforce the contract RBAC permission instead of the generic session-manage permission.
+ */
+
+// --- test_semantic_source_version_propagation_preserves_locked_fields (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Updated semantic source versions should mark unlocked fields reviewable while preserving locked manual values.
+ */
+
+// --- DatasetsApiTests (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Unit tests for datasets API endpoints.
+ * @invariant Endpoint contracts remain stable for success and validation failure paths.
+ */
+
+// --- test_get_datasets_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate successful datasets listing contract for an existing environment.
+ * @post Response matches DatasetsResponse schema
+ * @pre env_id exists
+ * @test GET /api/datasets returns 200 and valid schema
+ */
+
+// --- test_get_datasets_env_not_found (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing returns 404 when the requested environment does not exist.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test GET /api/datasets returns 404 if env_id missing
+ */
+
+// --- test_get_datasets_invalid_pagination (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing rejects invalid pagination parameters with 400 responses.
+ * @post Returns 400 error
+ * @pre page < 1 or page_size > 100
+ * @test GET /api/datasets returns 400 for invalid page/page_size
+ */
+
+// --- test_map_columns_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns request creates an async mapping task and returns its identifier.
+ * @post Returns task_id
+ * @pre Valid env_id, dataset_ids, source_type (sqllab)
+ * @test POST /api/datasets/map-columns creates mapping task
+ */
+
+// --- test_map_columns_invalid_source_type (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects unsupported source types with a 400 contract response.
+ * @post Returns 400 error
+ * @pre source_type is not 'sqllab' or 'xlsx'
+ * @test POST /api/datasets/map-columns returns 400 for invalid source_type
+ */
+
+// --- test_generate_docs_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs request creates an async documentation task and returns its identifier.
+ * @post Returns task_id
+ * @pre Valid env_id, dataset_ids, llm_provider
+ * @test POST /api/datasets/generate-docs creates doc generation task
+ */
+
+// --- test_map_columns_empty_ids (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects empty dataset identifier lists.
+ * @post Returns 400 error
+ * @pre dataset_ids is empty
+ * @test POST /api/datasets/map-columns returns 400 for empty dataset_ids
+ */
+
+// --- test_map_columns_missing_database_id (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects sqllab source without database_id.
+ * @post Returns 400 error
+ * @test POST /api/datasets/map-columns returns 400 for sqllab without database_id
+ */
+
+// --- test_generate_docs_empty_ids (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs rejects empty dataset identifier lists.
+ * @post Returns 400 error
+ * @pre dataset_ids is empty
+ * @test POST /api/datasets/generate-docs returns 400 for empty dataset_ids
+ */
+
+// --- test_generate_docs_env_not_found (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs returns 404 when the requested environment cannot be resolved.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test POST /api/datasets/generate-docs returns 404 for missing env
+ */
+
+// --- test_get_datasets_superset_failure (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing surfaces a 503 contract when Superset access fails.
+ * @post Returns 503 with stable error detail when upstream dataset fetch fails.
+ */
+
+// --- TestGitApi (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief API tests for Git configurations and repository operations.
+ */
+
+// --- DbMock (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief In-memory session double for git route tests with minimal query/filter persistence semantics.
+ * @invariant Supports only the SQLAlchemy-like operations exercised by this test module.
+ */
+
+// --- test_get_git_configs_masks_pat (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate listing git configs masks stored PAT values in API-facing responses.
+ */
+
+// --- test_create_git_config_persists_config (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate creating git config persists supplied server attributes in backing session.
+ */
+
+// --- test_update_git_config_modifies_record (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate updating git config modifies mutable fields while preserving masked PAT semantics.
+ */
+
+// --- SingleConfigDbMock (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ */
+
+// --- test_update_git_config_raises_404_if_not_found (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate updating non-existent git config raises HTTP 404 contract response.
+ */
+
+// --- test_delete_git_config_removes_record (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate deleting existing git config removes record and returns success payload.
+ */
+
+// --- test_test_git_config_validates_connection_successfully (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate test-connection endpoint returns success when provider connectivity check passes.
+ */
+
+// --- MockGitService (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ */
+
+// --- test_test_git_config_fails_validation (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate test-connection endpoint raises HTTP 400 when provider connectivity check fails.
+ */
+
+// --- test_list_gitea_repositories_returns_payload (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate gitea repositories endpoint returns normalized list for GITEA provider configs.
+ */
+
+// --- test_list_gitea_repositories_rejects_non_gitea (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate gitea repositories endpoint rejects non-GITEA providers with HTTP 400.
+ */
+
+// --- test_create_remote_repository_creates_provider_repo (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate remote repository creation endpoint maps provider response into normalized payload.
+ */
+
+// --- test_init_repository_initializes_and_saves_binding (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate repository initialization endpoint creates local repo and persists dashboard binding.
+ */
+
+// --- TestGitStatusRoute (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Validate status endpoint behavior for missing and error repository states.
+ */
+
+// --- test_get_repository_status_returns_no_repo_payload_for_missing_repo (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure missing local repository is represented as NO_REPO payload instead of an API error.
+ * @post Route returns a deterministic NO_REPO status payload.
+ * @pre GitService.get_status raises HTTPException(404).
+ */
+
+// --- test_get_repository_status_propagates_non_404_http_exception (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure HTTP exceptions other than 404 are not masked.
+ * @post Raised exception preserves original status and detail.
+ * @pre GitService.get_status raises HTTPException with non-404 status.
+ */
+
+// --- test_get_repository_diff_propagates_http_exception (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure diff endpoint preserves domain HTTP errors from GitService.
+ * @post Endpoint raises same HTTPException values.
+ * @pre GitService.get_diff raises HTTPException.
+ */
+
+// --- test_get_history_wraps_unexpected_error_as_500 (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure non-HTTP exceptions in history endpoint become deterministic 500 errors.
+ * @post Endpoint returns HTTPException with status 500 and route context.
+ * @pre GitService.get_commit_history raises ValueError.
+ */
+
+// --- test_commit_changes_wraps_unexpected_error_as_500 (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure commit endpoint does not leak unexpected errors as 400.
+ * @post Endpoint raises HTTPException(500) with route context.
+ * @pre GitService.commit_changes raises RuntimeError.
+ */
+
+// --- test_get_repository_status_batch_returns_mixed_statuses (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint returns per-dashboard statuses in one response.
+ * @post Returned map includes resolved status for each requested dashboard ID.
+ * @pre Some repositories are missing and some are initialized.
+ */
+
+// --- test_get_repository_status_batch_marks_item_as_error_on_service_failure (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint marks failed items as ERROR without failing entire request.
+ * @post Failed dashboard status is marked as ERROR.
+ * @pre GitService raises non-HTTP exception for one dashboard.
+ */
+
+// --- test_get_repository_status_batch_deduplicates_and_truncates_ids (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint protects server from oversized payloads.
+ * @post Result contains unique IDs up to configured cap.
+ * @pre request includes duplicate IDs and more than MAX_REPOSITORY_STATUS_BATCH entries.
+ */
+
+// --- test_commit_changes_applies_profile_identity_before_commit (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure commit route configures repository identity from profile preferences before commit call.
+ * @post git_service.configure_identity receives resolved identity and commit proceeds.
+ * @pre Profile preference contains git_username/git_email for current user.
+ */
+
+// --- test_pull_changes_applies_profile_identity_before_pull (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure pull route configures repository identity from profile preferences before pull call.
+ * @post git_service.configure_identity receives resolved identity and pull proceeds.
+ * @pre Profile preference contains git_username/git_email for current user.
+ */
+
+// --- test_get_merge_status_returns_service_payload (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure merge status route returns service payload as-is.
+ * @post Route response contains has_unfinished_merge=True.
+ * @pre git_service.get_merge_status returns unfinished merge payload.
+ */
+
+// --- test_resolve_merge_conflicts_passes_resolution_items_to_service (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure merge resolve route forwards parsed resolutions to service.
+ * @post Service receives normalized list and route returns resolved files.
+ * @pre resolve_data has one file strategy.
+ */
+
+// --- test_abort_merge_calls_service_and_returns_result (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure abort route delegates to service.
+ * @post Route returns aborted status.
+ * @pre Service abort_merge returns aborted status.
+ */
+
+// --- test_continue_merge_passes_message_and_returns_commit (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure continue route passes commit message to service.
+ * @post Route returns committed status and hash.
+ * @pre continue_data.message is provided.
+ */
+
+// --- TestMigrationRoutes (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ * @brief Unit tests for migration API route handlers.
+ */
+
+// --- _mock_env (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ */
+
+// --- _make_sync_config_manager (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ */
+
+// --- TestProfileApi (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies profile API route contracts for preference read/update and Superset account lookup.
+ */
+
+// --- mock_profile_route_dependencies (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Provides deterministic dependency overrides for profile route tests.
+ * @post Dependencies are overridden for current test and restored afterward.
+ * @pre App instance is initialized.
+ */
+
+// --- profile_route_deps_fixture (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Pytest fixture wrapper for profile route dependency overrides.
+ * @post Yields overridden dependencies and clears overrides after test.
+ * @pre None.
+ */
+
+// --- _build_preference_response (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Builds stable profile preference response payload for route tests.
+ * @post Returns ProfilePreferenceResponse object with deterministic timestamps.
+ * @pre user_id is provided.
+ */
+
+// --- test_get_profile_preferences_returns_self_payload (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies GET /api/profile/preferences returns stable self-scoped payload.
+ * @post Response status is 200 and payload contains current user preference.
+ * @pre Authenticated user context is available.
+ */
+
+// --- test_patch_profile_preferences_success (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies PATCH /api/profile/preferences persists valid payload through route mapping.
+ * @post Response status is 200 with saved preference payload.
+ * @pre Valid request payload and authenticated user.
+ */
+
+// --- test_patch_profile_preferences_validation_error (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies route maps domain validation failure to HTTP 422 with actionable details.
+ * @post Response status is 422 and includes validation messages.
+ * @pre Service raises ProfileValidationError.
+ */
+
+// --- test_patch_profile_preferences_cross_user_denied (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies route maps domain authorization guard failure to HTTP 403.
+ * @post Response status is 403 with denial message.
+ * @pre Service raises ProfileAuthorizationError.
+ */
+
+// --- test_lookup_superset_accounts_success (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies lookup route returns success payload with normalized candidates.
+ * @post Response status is 200 and items list is returned.
+ * @pre Valid environment_id and service success response.
+ */
+
+// --- test_lookup_superset_accounts_env_not_found (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies lookup route maps missing environment to HTTP 404.
+ * @post Response status is 404 with explicit message.
+ * @pre Service raises EnvironmentNotFoundError.
+ */
+
+// --- TestReportsApi (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Contract tests for GET /api/reports defaults, pagination, and filtering behavior.
+ * @invariant API response contract contains {items,total,page,page_size,has_next,applied_filters}.
+ */
+
+// --- _make_task (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Build Task fixture with controlled timestamps/status for reports list/detail normalization.
+ */
+
+// --- test_get_reports_default_pagination_contract (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint default pagination and contract keys for mixed task statuses.
+ */
+
+// --- test_get_reports_filter_and_pagination (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint applies task-type/status filters and pagination boundaries.
+ */
+
+// --- test_get_reports_handles_mixed_naive_and_aware_datetimes (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports sorting remains stable when task timestamps mix naive and timezone-aware datetimes.
+ */
+
+// --- test_get_reports_invalid_filter_returns_400 (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint rejects unsupported task type filters with HTTP 400.
+ */
+
+// --- TestReportsDetailApi (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Contract tests for GET /api/reports/{report_id} detail endpoint behavior.
+ * @invariant Detail endpoint tests must keep deterministic assertions for success and not-found contracts.
+ */
+
+// --- test_get_report_detail_success (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Validate report detail endpoint returns report body with diagnostics and next actions for existing task.
+ */
+
+// --- test_get_report_detail_not_found (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Validate report detail endpoint returns 404 when requested report identifier is absent.
+ */
+
+// --- TestReportsOpenapiConformance (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Validate implemented reports payload shape against OpenAPI-required top-level contract fields.
+ * @invariant List and detail payloads include required contract keys.
+ */
+
+// --- _FakeTaskManager (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Minimal task-manager fake exposing static task list for OpenAPI conformance checks.
+ * @invariant get_all_tasks returns seeded tasks unchanged.
+ */
+
+// --- _admin_user (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Provide admin principal fixture required by reports routes in conformance tests.
+ */
+
+// --- _task (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Construct deterministic task fixture consumed by reports list/detail payload assertions.
+ */
+
+// --- test_reports_list_openapi_required_keys (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Verify reports list endpoint includes all required OpenAPI top-level keys.
+ */
+
+// --- test_reports_detail_openapi_required_keys (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Verify reports detail endpoint returns payload containing the report object key.
+ */
+
+// --- test_tasks_logs_module (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Contract testing for task logs API endpoints.
+ */
+
+// --- test_get_task_logs_success (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint returns filtered logs for an existing task.
+ */
+
+// --- test_get_task_logs_not_found (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint returns 404 when the task identifier is missing.
+ */
+
+// --- test_get_task_logs_invalid_limit (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint enforces query validation for limit lower bound.
+ */
+
+// --- test_get_task_log_stats_success (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate log stats endpoint returns success payload for an existing task.
+ */
+
+// --- AdminApi (backend/src/api/routes/admin.py)
+/**!
+ * @brief Admin API endpoints for user and role management.
+ * @invariant All endpoints in this module require 'Admin' role or 'admin' scope.
+ */
+
+// --- list_users (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all registered users.
+ * @post Returns a list of UserSchema objects.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- create_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new local user.
+ * @post New user is created in the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- update_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Updates an existing user.
+ * @post User record is updated in the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- delete_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Deletes a user.
+ * @post User record is removed from the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- list_roles (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all available roles.
+ */
+
+// --- create_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new system role with associated permissions.
+ * @post New Role record is created in auth.db.
+ * @pre Role name must be unique.
+ */
+
+// --- update_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Updates an existing role's metadata and permissions.
+ * @post Role record is updated in auth.db.
+ * @pre role_id must be a valid existing role UUID.
+ */
+
+// --- delete_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Removes a role from the system.
+ * @post Role record is removed from auth.db.
+ * @pre role_id must be a valid existing role UUID.
+ */
+
+// --- list_ad_mappings (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all AD Group to Role mappings.
+ */
+
+// --- create_ad_mapping (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new AD Group mapping.
+ */
+
+// --- AdminApiKeyRoutes (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Admin API endpoints for API key management — list, generate (one-time reveal), and revoke.
+ * @invariant DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.
+ */
+
+// --- ApiKeyCreateRequest (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- ApiKeyCreateResponse (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- ApiKeyListItem (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- ApiKeyRevokeResponse (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- list_api_keys (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief List all API keys — NEVER returns key_hash or raw_key.
+ * @post Returns list of ApiKeyListItem without sensitive fields.
+ * @pre Requires admin:settings WRITE permission.
+ */
+
+// --- create_api_key (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Generate a new API key — returns raw key ONCE, never stored or retrievable again.
+ * @post Creates APIKey row with SHA-256 hash. Returns raw key in response.
+ * @pre Requires admin:settings WRITE permission. name is required, at least one permission.
+ */
+
+// --- revoke_api_key (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Revoke an API key by setting active=False. Preserves row for audit.
+ * @post Sets active=False on the key. Returns 404 if already revoked or not found.
+ * @pre Requires admin:settings WRITE permission.
+ */
+
+// --- AssistantAdminRoutes (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief FastAPI route handlers for assistant admin operations — conversation listing, deletion, history, audit.
+ * @invariant Audit endpoint requires tasks:READ permission.
+ */
+
+// --- list_conversations (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Return paginated conversation list for current user with archived flag and last message preview.
+ * @post Conversations are grouped by conversation_id sorted by latest activity descending.
+ * @pre Authenticated user context and valid pagination params.
+ */
+
+// --- delete_conversation (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Soft-delete or hard-delete a conversation and clear its in-memory trace.
+ * @post Conversation records are removed from DB and CONVERSATIONS cache.
+ * @pre conversation_id belongs to current_user.
+ */
+
+// --- get_history (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Retrieve paginated assistant conversation history for current user.
+ * @post Returns persistent messages and mirrored in-memory snapshot for diagnostics.
+ * @pre Authenticated user is available and page params are valid.
+ */
+
+// --- get_assistant_audit (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Return assistant audit decisions for current user from persistent and in-memory stores.
+ * @post Audit payload is returned in reverse chronological order from DB.
+ * @pre User has tasks:READ permission.
+ */
+
+// --- AssistantCommandParser (backend/src/api/routes/assistant/_command_parser.py)
+/**!
+ * @brief Deterministic RU/EN command text parser that converts user messages into intent payloads.
+ * @invariant Every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+ */
+
+// --- _parse_command (backend/src/api/routes/assistant/_command_parser.py)
+/**!
+ * @brief Deterministically parse RU/EN command text into intent payload.
+ * @invariant every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+ * @post Returns intent dict with domain/operation/entities/confidence/risk fields.
+ * @pre message contains raw user text and config manager resolves environments.
+ */
+
+// --- AssistantDatasetReview (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Dataset review context loading and intent planning for the assistant API.
+ * @invariant Dataset review operations are always scoped to the owner's session.
+ */
+
+// --- _serialize_dataset_review_context (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Build assistant-safe dataset-review context snapshot with masked imported-filter payloads for session-scoped assistant routing.
+ * @post Returns a serializable dictionary containing the complete review context.
+ * @pre session_id is a valid active review session identifier.
+ */
+
+// --- _load_dataset_review_context (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Load owner-scoped dataset-review context for assistant planning and grounded response generation.
+ * @post Returns a loaded context object with session data and findings.
+ * @pre session_id is a valid active review session identifier.
+ */
+
+// --- _extract_dataset_review_target (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Extract structured dataset-review focus target hints embedded in assistant prompts.
+ */
+
+// --- _match_dataset_review_field (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Resolve one semantic field from assistant-visible context by id or user-visible label.
+ */
+
+// --- _extract_quoted_segment (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Extract one quoted assistant command segment after a label token.
+ */
+
+// --- _plan_dataset_review_intent (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Parse session-scoped dataset-review assistant commands before falling back to generic assistant tool routing.
+ */
+
+// --- AssistantDatasetReviewDispatch (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Dispatch and confirmation handling for dataset-review assistant intents.
+ * @invariant Dataset review dispatch requires valid session version for write operations.
+ */
+
+// --- _dataset_review_conflict_http_exception (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Convert dataset-review optimistic-lock conflicts into shared 409 assistant semantics.
+ */
+
+// --- _dispatch_dataset_review_intent (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Route confirmed dataset-review assistant intents through existing backend dataset-review APIs and orchestration boundaries.
+ * @post Returns a structured response with planned actions and confirmations.
+ * @pre context contains valid session data and user intent.
+ */
+
+// --- AssistantDispatch (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Intent dispatch engine, confirmation summary, and clarification text for the assistant API.
+ * @invariant Unsupported operations are rejected via HTTPException(400).
+ */
+
+// --- _clarification_text_for_intent (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Convert technical missing-parameter errors into user-facing clarification prompts.
+ * @post Returned text is human-readable and actionable for target operation.
+ * @pre state was classified as needs_clarification for current intent/error combination.
+ */
+
+// --- _async_confirmation_summary (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Build human-readable confirmation prompt for an intent before execution.
+ * @post Returns a formatted summary string suitable for display to the user.
+ * @pre actions is a non-empty list of planned review actions.
+ */
+
+// --- _dispatch_intent (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Execute parsed assistant intent via existing task/plugin/git services.
+ * @invariant unsupported operations are rejected via HTTPException(400).
+ * @post Returns response text, optional task id, and UI actions for follow-up.
+ * @pre intent operation is known and actor permissions are validated per operation.
+ */
+
+// --- AssistantHistory (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Conversation history, audit trail, and confirmation persistence helpers for the assistant API.
+ * @invariant Failed persistence attempts always rollback before returning.
+ */
+
+// --- _append_history (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Append conversation message to in-memory history buffer.
+ * @invariant every appended entry includes generated message_id and created_at timestamp.
+ * @post Message entry is appended to CONVERSATIONS key list.
+ * @pre user_id and conversation_id identify target conversation bucket.
+ */
+
+// --- _persist_message (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist assistant/user message record to database.
+ * @invariant failed persistence attempts always rollback before returning.
+ * @post Message row is committed or persistence failure is logged.
+ * @pre db session is writable and message payload is serializable.
+ */
+
+// --- _audit (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Append in-memory audit record for assistant decision trace.
+ * @invariant persisted in-memory audit entry always contains created_at in ISO format.
+ * @post ASSISTANT_AUDIT list for user contains new timestamped entry.
+ * @pre payload describes decision/outcome fields.
+ */
+
+// --- _persist_audit (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist structured assistant audit payload in database.
+ * @post Audit row is committed or failure is logged with rollback.
+ * @pre db session is writable and payload is JSON-serializable.
+ */
+
+// --- _persist_confirmation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist confirmation token record to database.
+ * @post Confirmation row exists in persistent storage.
+ * @pre record contains id/user/intent/dispatch/expiry fields.
+ */
+
+// --- _update_confirmation_state (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Update persistent confirmation token lifecycle state.
+ * @post State and consumed_at fields are updated when applicable.
+ * @pre confirmation_id references existing row.
+ */
+
+// --- _load_confirmation_from_db (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Load confirmation token from database into in-memory model.
+ * @post Returns ConfirmationRecord when found, otherwise None.
+ * @pre confirmation_id may or may not exist in storage.
+ */
+
+// --- _ensure_conversation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Resolve active conversation id in memory or create a new one.
+ * @post Returns stable conversation id and updates USER_ACTIVE_CONVERSATION.
+ * @pre user_id identifies current actor.
+ */
+
+// --- _resolve_or_create_conversation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Resolve active conversation using explicit id, memory cache, or persisted history.
+ * @post Returns conversation id and updates USER_ACTIVE_CONVERSATION cache.
+ * @pre user_id and db session are available.
+ */
+
+// --- _cleanup_history_ttl (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Enforce assistant message retention window by deleting expired rows and in-memory records.
+ * @post Messages older than ASSISTANT_MESSAGE_TTL_DAYS are removed from persistence and memory mirrors.
+ * @pre db session is available and user_id references current actor scope.
+ */
+
+// --- _is_conversation_archived (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Determine archived state for a conversation based on last update timestamp.
+ * @post Returns True when conversation inactivity exceeds archive threshold.
+ * @pre updated_at can be null for empty conversations.
+ */
+
+// --- _coerce_query_bool (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Normalize bool-like query values for compatibility in direct handler invocations/tests.
+ * @post Returns deterministic boolean flag.
+ * @pre value may be bool, string, or FastAPI Query metadata object.
+ */
+
+// --- AssistantLlmPlanner (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief LLM-based intent planning, tool catalog construction, and authorization for the assistant API.
+ * @invariant Tool catalog is filtered by user permissions before being sent to LLM.
+ * @post LLM tool catalog filtered and returned
+ * @pre Assistant routes initialized, user authenticated
+ */
+
+// --- _check_any_permission (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Validate user against alternative permission checks (logical OR).
+ * @post Returns on first successful permission; raises 403-like HTTPException otherwise.
+ * @pre checks list contains resource-action tuples.
+ */
+
+// --- _has_any_permission (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Check whether user has at least one permission tuple from the provided list.
+ * @post Returns True when at least one permission check passes.
+ * @pre current_user and checks list are valid.
+ */
+
+// --- _build_tool_catalog (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Build current-user tool catalog for LLM planner with operation contracts and defaults.
+ * @post Returns list of executable tools filtered by permission and runtime availability.
+ * @pre current_user is authenticated; config/db are available.
+ */
+
+// --- _coerce_intent_entities (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Normalize intent entity value types from LLM output to route-compatible values.
+ * @post Returned intent has numeric ids coerced where possible and string values stripped.
+ * @pre intent contains entities dict or missing entities.
+ */
+
+// --- AssistantLlmPlannerIntent (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief LLM-based intent planning and authorization for the assistant API — separated from tool catalog.
+ * @invariant Production deployments always require confirmation.
+ * @post Intent planning registered with confirmation gate
+ * @pre Assistant routes initialized, user authenticated
+ */
+
+// --- _plan_intent_with_llm (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief Use active LLM provider to select best tool/operation from dynamic catalog.
+ * @post Returns normalized intent dict when planning succeeds; otherwise None.
+ * @pre tools list contains allowed operations for current user.
+ */
+
+// --- _authorize_intent (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief Validate user permissions for parsed intent before confirmation/dispatch.
+ * @post Returns if authorized; raises HTTPException(403) when denied.
+ * @pre intent.operation is present for known assistant command domains.
+ */
+
+// --- AssistantResolvers (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Environment, dashboard, provider, and task resolution utilities for the assistant API.
+ * @invariant Resolution functions never raise; they return None on failure.
+ */
+
+// --- _extract_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Extract first regex match group from text by ordered pattern list.
+ * @post Returns first matched token or None.
+ * @pre patterns contain at least one capture group.
+ */
+
+// --- _resolve_env_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve environment identifier/name token to canonical environment id.
+ * @post Returns matched environment id or None.
+ * @pre config_manager provides environment list.
+ */
+
+// --- _is_production_env (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Determine whether environment token resolves to production-like target.
+ * @post Returns True for production/prod synonyms, else False.
+ * @pre config_manager provides environments or token text is provided.
+ */
+
+// --- _resolve_provider_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve provider token to provider id with active/default fallback.
+ * @post Returns provider id or None when no providers configured.
+ * @pre db session can load provider list through LLMProviderService.
+ */
+
+// --- _get_default_environment_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve default environment id from settings or first configured environment.
+ * @post Returns default environment id or None when environment list is empty.
+ * @pre config_manager returns environments list.
+ */
+
+// --- _resolve_dashboard_id_by_ref (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve dashboard id by title or slug reference in selected environment.
+ * @post Returns dashboard id when uniquely matched, otherwise None.
+ * @pre dashboard_ref is a non-empty string-like token.
+ */
+
+// --- _resolve_dashboard_id_entity (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve dashboard id from intent entities using numeric id or dashboard_ref fallback.
+ * @post Returns resolved dashboard id or None when ambiguous/unresolvable.
+ * @pre entities may contain dashboard_id as int/str and optional dashboard_ref.
+ */
+
+// --- _get_environment_name_by_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve human-readable environment name by id.
+ * @post Returns matching environment name or fallback id.
+ * @pre environment id may be None.
+ */
+
+// --- _extract_result_deep_links (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Build deep-link actions to verify task result from assistant chat.
+ * @post Returns zero or more assistant actions for dashboard open/diff.
+ * @pre task object is available.
+ */
+
+// --- _build_task_observability_summary (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Build compact textual summary for completed tasks to reduce "black box" effect.
+ * @post Returns non-empty summary line for known task types or empty string fallback.
+ * @pre task may contain plugin-specific result payload.
+ */
+
+// --- AssistantRoutes (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief FastAPI route handlers for the assistant API — message sending, confirmation, conversation management.
+ * @invariant Risky operations are never executed without valid confirmation token.
+ */
+
+// --- send_message (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Parse assistant command, enforce safety gates, and dispatch executable intent.
+ * @invariant non-safe operations are gated with confirmation before execution from this endpoint.
+ * @post Response state is one of clarification/confirmation/started/success/denied/failed.
+ * @pre Authenticated user is available and message text is non-empty.
+ */
+
+// --- confirm_operation (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Execute previously requested risky operation after explicit user confirmation.
+ * @post Confirmation state becomes consumed and operation result is persisted in history.
+ * @pre confirmation_id exists, belongs to current user, is pending, and not expired.
+ */
+
+// --- cancel_operation (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Cancel pending risky operation and mark confirmation token as cancelled.
+ * @post Confirmation becomes cancelled and cannot be executed anymore.
+ * @pre confirmation_id exists, belongs to current user, and is still pending.
+ */
+
+// --- AssistantSchemas (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Pydantic models, in-memory stores, and permission mappings for the assistant API.
+ * @invariant In-memory stores are module-level singletons shared across the assistant package.
+ */
+
+// --- AssistantMessageRequest (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Input payload for assistant message endpoint.
+ * @invariant message is always non-empty and no longer than 4000 characters.
+ * @post Request object provides message text and optional conversation binding.
+ * @pre message length is within accepted bounds.
+ */
+
+// --- AssistantAction (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief UI action descriptor returned with assistant responses.
+ * @invariant type and label are required for every UI action.
+ * @post Action can be rendered as button on frontend.
+ * @pre type and label are provided by orchestration logic.
+ */
+
+// --- AssistantMessageResponse (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Output payload contract for assistant interaction endpoints.
+ * @invariant created_at and state are always present in endpoint responses.
+ * @post Payload may include task_id/confirmation_id/actions for UI follow-up.
+ * @pre Response includes deterministic state and text.
+ */
+
+// --- ConfirmationRecord (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory confirmation token model for risky operation dispatch.
+ * @invariant state defaults to "pending" and expires_at bounds confirmation validity.
+ * @post Record tracks lifecycle state and expiry timestamp.
+ * @pre intent/dispatch/user_id are populated at confirmation request time.
+ */
+
+// --- CONVERSATIONS (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}
+ */
+
+// --- ASSISTANT_AUDIT (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.
+ */
+
+// --- CleanReleaseApi (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Expose clean release endpoints for candidate preparation and subsequent compliance flow.
+ * @invariant API never reports prepared status if preparation errors are present.
+ * @post Candidate preparation, manifest, and compliance routes expose deterministic API payloads without reporting prepared state on failed preparation.
+ * @pre Clean release repository and preparation service dependencies are configured for the current request scope.
+ */
+
+// --- PrepareCandidateRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate preparation endpoint.
+ */
+
+// --- StartCheckRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for clean compliance check run startup.
+ */
+
+// --- RegisterCandidateRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate registration endpoint.
+ */
+
+// --- ImportArtifactsRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate artifact import endpoint.
+ */
+
+// --- BuildManifestRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for manifest build endpoint.
+ */
+
+// --- CreateComplianceRunRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for compliance run creation with optional manifest pinning.
+ */
+
+// --- register_candidate_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Register a clean-release candidate for headless lifecycle.
+ * @post Candidate is persisted in DRAFT status.
+ * @pre Candidate identifier is unique.
+ */
+
+// --- import_candidate_artifacts_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Import candidate artifacts in headless flow.
+ * @post Artifacts are persisted and candidate advances to PREPARED if it was DRAFT.
+ * @pre Candidate exists and artifacts array is non-empty.
+ */
+
+// --- build_candidate_manifest_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Build immutable manifest snapshot for prepared candidate.
+ * @post Returns created ManifestDTO with incremented version.
+ * @pre Candidate exists and has imported artifacts.
+ */
+
+// --- get_candidate_overview_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return expanded candidate overview DTO for headless lifecycle visibility.
+ * @post Returns CandidateOverviewDTO built from the same repository state used by headless US1 endpoints.
+ * @pre Candidate exists.
+ */
+
+// --- prepare_candidate_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Prepare candidate with policy evaluation and deterministic manifest generation.
+ * @post Returns preparation result including manifest reference and violations.
+ * @pre Candidate and active policy exist in repository.
+ */
+
+// --- start_check (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Start and finalize a clean compliance check run and persist report artifacts.
+ * @post Returns accepted payload with check_run_id and started_at.
+ * @pre Active policy and candidate exist.
+ */
+
+// --- get_check_status (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return terminal/intermediate status payload for a check run.
+ * @post Deterministic payload shape includes checks and violations arrays.
+ * @pre check_run_id references an existing run.
+ */
+
+// --- get_report (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return persisted compliance report by report_id.
+ * @post Returns serialized report object.
+ * @pre report_id references an existing report.
+ */
+
+// --- CleanReleaseV2Api (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Redesigned clean release API for headless candidate lifecycle.
+ * @post Candidate registration, approval, publication, and revocation routes are registered without behavior changes.
+ * @pre Clean release repository dependency is available for candidate lifecycle endpoints.
+ */
+
+// --- ApprovalRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for approval request payload.
+ */
+
+// --- PublishRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for publication request payload.
+ */
+
+// --- RevokeRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for revocation request payload.
+ */
+
+// --- register_candidate (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Register a new release candidate.
+ * @post Candidate is saved in repository.
+ * @pre Payload contains required fields (id, version, source_snapshot_ref, created_by).
+ */
+
+// --- import_artifacts (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Associate artifacts with a release candidate.
+ * @post Artifacts are processed (placeholder).
+ * @pre Candidate exists.
+ */
+
+// --- build_manifest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Generate distribution manifest for a candidate.
+ * @post Manifest is created and saved.
+ * @pre Candidate exists.
+ */
+
+// --- approve_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to record candidate approval.
+ */
+
+// --- reject_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to record candidate rejection.
+ */
+
+// --- publish_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to publish an approved candidate.
+ */
+
+// --- revoke_publication_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to revoke a previous publication.
+ */
+
+// --- DashboardsApi (backend/src/api/routes/dashboards/__init__.py)
+/**!
+ * @brief API endpoints for the Dashboard Hub - listing dashboards with Git and task status
+ * @invariant All dashboard responses include git_status and last_task metadata
+ * @post Dashboard responses are projected into DashboardsResponse DTO.
+ * @pre Valid environment configurations exist in ConfigManager.
+ */
+
+// --- DashboardActionRoutes (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Dashboard action route handlers — migrate, backup.
+ */
+
+// --- migrate_dashboards (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Trigger bulk migration of dashboards from source to target environment
+ * @post Task is created and queued for execution
+ * @pre dashboard_ids is a non-empty list
+ */
+
+// --- backup_dashboards (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Trigger bulk backup of dashboards with optional cron schedule
+ * @post If schedule is provided, a scheduled task is created
+ * @pre dashboard_ids is a non-empty list
+ */
+
+// --- DashboardDetailRoutes (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Dashboard detail, db-mappings, task history, thumbnail route handlers.
+ */
+
+// --- get_database_mappings (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Get database mapping suggestions between source and target environments
+ * @post Returns list of suggested database mappings with confidence scores
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- get_dashboard_detail (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Fetch detailed dashboard info with related charts and datasets
+ * @post Returns dashboard detail payload for overview page
+ * @pre env_id must be valid and dashboard ref (slug or id) must exist
+ */
+
+// --- get_dashboard_tasks_history (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Returns history of backup and LLM validation tasks for a dashboard.
+ * @post Response contains sorted task history (newest first).
+ * @pre dashboard ref (slug or id) is valid.
+ */
+
+// --- get_dashboard_thumbnail (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Proxies Superset dashboard thumbnail with cache support.
+ * @post Returns image bytes or 202 when thumbnail is being prepared by Superset.
+ * @pre env_id must exist.
+ */
+
+// --- DashboardHelpers (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Basic helper functions for dashboard route handlers — slug resolution, filter normalization.
+ */
+
+// --- _find_dashboard_id_by_slug (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard numeric ID by slug using Superset list endpoint.
+ * @post Returns dashboard ID when found, otherwise None.
+ * @pre `dashboard_slug` is non-empty.
+ */
+
+// --- _resolve_dashboard_id_from_ref (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard ID from slug-first reference with numeric fallback.
+ * @post Returns a valid dashboard ID or raises HTTPException(404).
+ * @pre `dashboard_ref` is provided in route path.
+ */
+
+// --- _find_dashboard_id_by_slug_async (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard numeric ID by slug using async Superset list endpoint.
+ * @post Returns dashboard ID when found, otherwise None.
+ * @pre dashboard_slug is non-empty.
+ */
+
+// --- _resolve_dashboard_id_from_ref_async (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard ID from slug-first reference using async Superset client.
+ * @post Returns valid dashboard ID or raises HTTPException(404).
+ * @pre dashboard_ref is provided in route path.
+ */
+
+// --- _normalize_filter_values (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Normalize query filter values to lower-cased non-empty tokens.
+ * @post Returns trimmed normalized list preserving input order.
+ * @pre values may be None or list of strings.
+ */
+
+// --- _dashboard_git_filter_value (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Build comparable git status token for dashboards filtering.
+ * @post Returns one of ok|diff|no_repo|error|pending.
+ * @pre dashboard payload may contain git_status or None.
+ */
+
+// --- DashboardListingRoutes (backend/src/api/routes/dashboards/_listing_routes.py)
+/**!
+ * @brief Dashboard listing route handler for Dashboard Hub.
+ */
+
+// --- get_dashboards (backend/src/api/routes/dashboards/_listing_routes.py)
+/**!
+ * @brief Fetch list of dashboards from a specific environment with Git status and last task status
+ * @post Response includes effective profile filter metadata for main dashboards page context
+ * @pre page_size must be between 1 and 100 if provided
+ */
+
+// --- DashboardProjection (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Dashboard response projection and profile-filter helpers for Dashboard Hub routes.
+ */
+
+// --- _normalize_actor_alias_token (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Normalize actor alias token to comparable trim+lower text.
+ */
+
+// --- _normalize_owner_display_token (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Project owner payload value into stable display string for API response contracts.
+ */
+
+// --- _normalize_dashboard_owner_values (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Normalize dashboard owners payload to optional list of display strings.
+ */
+
+// --- _project_dashboard_response_items (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Project dashboard payloads to response-contract-safe shape.
+ */
+
+// --- _get_profile_filter_binding (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Resolve dashboard profile-filter binding through current or legacy profile service contracts.
+ */
+
+// --- _resolve_profile_actor_aliases (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Resolve stable actor aliases for profile filtering without per-dashboard detail fan-out.
+ */
+
+// --- _matches_dashboard_actor_aliases (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Apply profile actor matching against multiple aliases (username + optional display name).
+ */
+
+// --- _task_matches_dashboard (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Checks whether task params are tied to a specific dashboard and environment.
+ */
+
+// --- DashboardsRouter (backend/src/api/routes/dashboards/_router.py)
+/**!
+ * @brief Single APIRouter instance for all dashboard endpoints.
+ */
+
+// --- DashboardSchemas (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO classes for the Dashboard Hub API.
+ */
+
+// --- GitStatus (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard Git synchronization status.
+ */
+
+// --- DashboardItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO representing a single dashboard with projected metadata.
+ */
+
+// --- EffectiveProfileFilter (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Metadata about applied profile filters for UI context.
+ */
+
+// --- DashboardsResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Envelope DTO for paginated dashboards list.
+ */
+
+// --- DashboardChartItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for a chart linked to a dashboard.
+ */
+
+// --- DashboardDatasetItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for a dataset associated with a dashboard.
+ */
+
+// --- DashboardDetailResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Detailed dashboard metadata including children.
+ */
+
+// --- DashboardTaskHistoryItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Individual history record entry.
+ */
+
+// --- DashboardTaskHistoryResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Collection DTO for task history.
+ */
+
+// --- DatabaseMapping (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for cross-environment database ID mapping.
+ */
+
+// --- DatabaseMappingsResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Wrapper for database mappings.
+ */
+
+// --- MigrateRequest (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard migration requests.
+ */
+
+// --- BackupRequest (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard backup requests.
+ */
+
+// --- DatasetReviewDependencies (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Dependency injection, serialization helpers, and feature-flag guards for dataset review endpoints.
+ */
+
+// --- StartSessionRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for starting one dataset review session.
+ */
+
+// --- UpdateSessionRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for lifecycle state updates on an existing session.
+ */
+
+// --- SessionCollectionResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Paginated session collection response.
+ */
+
+// --- ExportArtifactResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Inline export response for documentation or validation outputs.
+ */
+
+// --- FieldSemanticUpdateRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for field-level semantic candidate acceptance or manual override.
+ */
+
+// --- FeedbackRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for thumbs up/down feedback.
+ */
+
+// --- ClarificationAnswerRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for submitting one clarification answer.
+ */
+
+// --- ClarificationSessionSummaryResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Summary DTO for current clarification session state.
+ */
+
+// --- ClarificationStateResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Response DTO for current clarification state and active question payload.
+ */
+
+// --- ClarificationAnswerResultResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Response DTO for one clarification answer mutation result.
+ */
+
+// --- FeedbackResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Minimal response DTO for persisted AI feedback actions.
+ */
+
+// --- ApproveMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Optional request DTO for explicit mapping approval audit notes.
+ */
+
+// --- BatchApproveSemanticItemRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for one batch semantic-approval item.
+ */
+
+// --- BatchApproveSemanticRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for explicit batch semantic approvals.
+ */
+
+// --- BatchApproveMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for explicit batch mapping approvals.
+ */
+
+// --- PreviewEnqueueResultResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Async preview trigger response exposing only enqueue state.
+ */
+
+// --- MappingCollectionResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Wrapper for execution mapping list responses.
+ */
+
+// --- UpdateExecutionMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for one manual execution-mapping override update.
+ */
+
+// --- LaunchDatasetResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Launch result exposing audited run context and SQL Lab redirect target.
+ */
+
+// --- _require_auto_review_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard US1 dataset review endpoints behind the configured feature flag.
+ */
+
+// --- _require_clarification_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard clarification-specific US2 endpoints behind the configured feature flag.
+ */
+
+// --- _require_execution_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard US3 execution endpoints behind the configured feature flag.
+ */
+
+// --- _get_repository (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build repository dependency.
+ */
+
+// --- _get_orchestrator (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build orchestrator dependency.
+ */
+
+// --- _get_clarification_engine (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build clarification engine dependency.
+ */
+
+// --- _serialize_session_summary (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map session aggregate into stable API summary DTO.
+ */
+
+// --- _serialize_session_detail (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map session aggregate into stable API detail DTO.
+ */
+
+// --- _require_session_version_header (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Read the optimistic-lock session version header.
+ */
+
+// --- _build_session_version_conflict_http_exception (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Normalize optimistic-lock conflict errors into HTTP 409 responses.
+ */
+
+// --- _enforce_session_version (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert repository optimistic-lock conflicts into deterministic HTTP 409 responses.
+ */
+
+// --- _get_owned_session_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve one session for current user or collaborator scope, returning 404 when inaccessible.
+ */
+
+// --- _require_owner_mutation_scope (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Enforce owner-only mutation scope.
+ */
+
+// --- _prepare_owned_session_mutation (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve owner-scoped mutation session and enforce optimistic-lock version.
+ */
+
+// --- _commit_owned_session_mutation (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Centralize session version bumping and commit semantics.
+ */
+
+// --- _record_session_event (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Persist one explicit audit event for an owned mutation endpoint.
+ */
+
+// --- _serialize_semantic_field (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one semantic field into stable DTO.
+ */
+
+// --- _serialize_execution_mapping (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one execution mapping into stable DTO.
+ */
+
+// --- _serialize_preview (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one preview into stable DTO.
+ */
+
+// --- _serialize_run_context (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one run context into stable DTO.
+ */
+
+// --- _serialize_clarification_question_payload (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert clarification engine payload into API DTO.
+ */
+
+// --- _serialize_clarification_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert clarification engine state into API response.
+ */
+
+// --- _serialize_empty_clarification_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Return empty clarification payload.
+ */
+
+// --- _get_latest_clarification_session_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve the latest clarification aggregate or raise.
+ */
+
+// --- _get_owned_mapping_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve one execution mapping inside one owned session.
+ */
+
+// --- _get_owned_field_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve a semantic field inside one owned session.
+ */
+
+// --- _map_candidate_provenance (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Translate accepted semantic candidate type into stable field provenance.
+ */
+
+// --- _resolve_candidate_source_version (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve the semantic source version for one accepted candidate.
+ */
+
+// --- _update_semantic_field_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Apply field-level semantic manual override or candidate acceptance.
+ * @post Manual overrides always set manual provenance plus lock.
+ */
+
+// --- _build_sql_lab_redirect_url (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build SQL Lab redirect URL.
+ */
+
+// --- _build_documentation_export (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Produce session documentation export content.
+ */
+
+// --- _build_validation_export (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Produce validation-focused export content.
+ */
+
+// --- DatasetReviewRoutes (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for clarification question/answer content.
+ */
+
+// --- list_sessions (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief List resumable dataset review sessions for the current user.
+ */
+
+// --- start_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Start a new dataset review session from a Superset link or dataset selection.
+ */
+
+// --- get_session_detail (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the full accessible dataset review session aggregate.
+ */
+
+// --- update_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Update resumable lifecycle status for an owned session.
+ */
+
+// --- delete_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Archive or hard-delete a session owned by the current user.
+ */
+
+// --- export_documentation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Export documentation output for the current session.
+ */
+
+// --- export_validation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Export validation findings for the current session.
+ */
+
+// --- get_clarification_state (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the current clarification session summary and active question payload.
+ */
+
+// --- resume_clarification (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Resume clarification mode on the highest-priority unresolved question.
+ */
+
+// --- record_clarification_answer (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist one clarification answer before advancing the active pointer.
+ */
+
+// --- update_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Apply one field-level semantic candidate decision or manual override.
+ */
+
+// --- lock_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Lock one semantic field against later automatic overwrite.
+ */
+
+// --- unlock_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Unlock one semantic field so later automated candidate application may replace it.
+ */
+
+// --- approve_batch_semantic_fields (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Approve multiple semantic candidate decisions in one batch.
+ */
+
+// --- list_execution_mappings (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the current mapping-review set for one accessible session.
+ */
+
+// --- update_execution_mapping (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist one owner-authorized execution-mapping effective value override.
+ */
+
+// --- approve_execution_mapping (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Explicitly approve a warning-sensitive mapping transformation.
+ */
+
+// --- approve_batch_execution_mappings (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Approve multiple warning-sensitive execution mappings in one batch.
+ */
+
+// --- trigger_preview_generation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Trigger Superset-side preview compilation for the current owned execution context.
+ */
+
+// --- launch_dataset (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Execute the current owned session launch handoff and return audited SQL Lab run context.
+ */
+
+// --- record_field_feedback (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for AI-assisted semantic field content.
+ */
+
+// --- record_clarification_feedback (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for clarification question/answer content.
+ */
+
+// --- DatasetsApi (backend/src/api/routes/datasets.py)
+/**!
+ * @brief API endpoints for the Dataset Hub - listing datasets with mapping progress
+ * @invariant All dataset responses include last_task metadata
+ * @post Returns dataset metadata with mapping status.
+ * @pre SupersetClient is available; env_id is valid.
+ */
+
+// --- MappedFields (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for dataset mapping progress statistics
+ */
+
+// --- LastTask (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for the most recent task associated with a dataset
+ */
+
+// --- DatasetItem (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Summary DTO for a dataset in the hub listing
+ */
+
+// --- LinkedDashboard (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for a dashboard linked to a dataset
+ */
+
+// --- DatasetColumn (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for a single dataset column's metadata
+ */
+
+// --- MetricItem (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Pydantic DTO for a dataset metric — carries Superset metric metadata.
+ */
+
+// --- DatasetDetailResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Detailed DTO for a dataset including columns, linked dashboards, and metrics.
+ */
+
+// --- StatsCounts (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Aggregate statistics for the Stats Bar — computed from full dataset list.
+ */
+
+// --- DatasetsResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Paginated response DTO for dataset listings with stats.
+ */
+
+// --- TaskResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Response DTO containing a task ID for tracking
+ */
+
+// --- ColumnDescriptionUpdate (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for inline-edit of a column description.
+ */
+
+// --- MetricDescriptionUpdate (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for inline-edit of a metric description.
+ */
+
+// --- get_dataset_ids (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Fetch list of all dataset IDs from a specific environment (without pagination)
+ * @post Returns a list of all dataset IDs
+ * @pre env_id must be a valid environment ID
+ */
+
+// --- get_datasets (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Fetch list of datasets from a specific environment with mapping progress and stats.
+ * @post Response includes pagination metadata (page, page_size, total, total_pages) and stats object.
+ * @pre page_size must be between 1 and 100 if provided
+ */
+
+// --- MapColumnsRequest (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for initiating column mapping
+ */
+
+// --- map_columns (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Trigger bulk column mapping for datasets
+ * @post Task is created and queued for execution
+ * @pre dataset_ids is a non-empty list
+ */
+
+// --- GenerateDocsRequest (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for initiating documentation generation
+ */
+
+// --- generate_docs (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Trigger bulk documentation generation for datasets
+ * @post Task is created and queued for execution
+ * @pre dataset_ids is a non-empty list
+ */
+
+// --- get_dataset_detail (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Get detailed dataset information including columns and linked dashboards
+ * @post Returns detailed dataset info with columns and linked dashboards
+ * @pre dataset_id is a valid dataset ID
+ */
+
+// --- _strip_html_tags (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Detect and strip HTML tags from a text string. Uses simple regex <[^>]*>.
+ */
+
+// --- update_column_description (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Save description for a single dataset column. Internal: GET full dataset from Superset, modify one column's description, PUT back.
+ * @post Column description in Superset is updated. Response confirms success.
+ * @pre dataset_id and column_id must exist in the target environment.
+ */
+
+// --- update_metric_description (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Save description for a single dataset metric. Mirror of update_column_description for metrics.
+ * @post Metric description in Superset is updated.
+ * @pre dataset_id and metric_id must exist in the target environment.
+ */
+
+// --- EnvironmentsApi (backend/src/api/routes/environments.py)
+/**!
+ * @brief API endpoints for listing environments and their databases.
+ * @invariant Environment IDs must exist in the configuration.
+ */
+
+// --- _normalize_superset_env_url (backend/src/api/routes/environments.py)
+/**!
+ * @brief Canonicalize Superset environment URL to base host/path without trailing /api/v1.
+ * @post Returns normalized base URL.
+ * @pre raw_url can be empty.
+ */
+
+// --- ScheduleSchema (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- EnvironmentResponse (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- DatabaseResponse (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- update_environment_schedule (backend/src/api/routes/environments.py)
+/**!
+ * @brief Update backup schedule for an environment.
+ * @post Backup schedule updated and scheduler reloaded.
+ * @pre Environment id exists, schedule is valid ScheduleSchema.
+ */
+
+// --- get_environment_databases (backend/src/api/routes/environments.py)
+/**!
+ * @brief Fetch the list of databases from a specific environment.
+ * @post Returns a list of database summaries from the environment.
+ * @pre Environment id exists.
+ */
+
+// --- GitPackage (backend/src/api/routes/git/__init__.py)
+/**!
+ * @brief Package root for decomposed git routes. Re-exports all public symbols from submodules.
+ * @invariant git_service and os are module-level attributes for test monkeypatch compatibility.
+ * @post Git API package exported
+ * @pre Git service initialized
+ */
+
+// --- GitConfigRoutes (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git server configuration CRUD and connection testing.
+ */
+
+// --- get_git_configs (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief List all configured Git servers.
+ */
+
+// --- create_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Register a new Git server configuration.
+ */
+
+// --- update_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Update an existing Git server configuration.
+ */
+
+// --- delete_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Remove a Git server configuration.
+ */
+
+// --- test_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Validate connection to a Git server using provided credentials.
+ */
+
+// --- GitDeps (backend/src/api/routes/git/_deps.py)
+/**!
+ * @brief Shared dependency wiring for monkeypatch-safe git_service access and constants.
+ * @invariant get_git_service() resolves from sys.modules at call time so test monkeypatching
+ */
+
+// --- GitEnvironmentRoutes (backend/src/api/routes/git/_environment_routes.py)
+/**!
+ * @brief FastAPI endpoint for listing deployment environments.
+ */
+
+// --- GitGiteaRoutes (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief FastAPI endpoints for Gitea-specific repository operations.
+ */
+
+// --- list_gitea_repositories (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief List repositories in Gitea for a saved Gitea config.
+ */
+
+// --- create_gitea_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Create a repository in Gitea for a saved Gitea config.
+ */
+
+// --- delete_gitea_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Delete repository in Gitea for a saved Gitea config.
+ */
+
+// --- create_remote_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Create repository on remote Git server using selected provider config.
+ */
+
+// --- GitHelpers (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Shared helper functions for Git route modules.
+ */
+
+// --- _build_no_repo_status_payload (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Build a consistent status payload for dashboards without initialized repositories.
+ * @post Returns a stable payload compatible with frontend repository status parsing.
+ */
+
+// --- _handle_unexpected_git_route_error (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Convert unexpected route-level exceptions to stable 500 API responses.
+ * @post Raises HTTPException(500) with route-specific context.
+ * @pre `error` is a non-HTTPException instance.
+ */
+
+// --- _resolve_repository_status (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve repository status for one dashboard with graceful NO_REPO semantics.
+ * @post Returns standard status payload or `NO_REPO` payload when repository path is absent.
+ * @pre `dashboard_id` is a valid integer.
+ */
+
+// --- _get_git_config_or_404 (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve GitServerConfig by id or raise 404.
+ */
+
+// --- _resolve_repo_key_from_ref (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve repository folder key with slug-first strategy and deterministic fallback.
+ */
+
+// --- _sanitize_optional_identity_value (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Normalize optional identity value into trimmed string or None.
+ */
+
+// --- _resolve_current_user_git_identity (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve configured Git username/email from current user's profile preferences.
+ */
+
+// --- _apply_git_identity_from_profile (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Apply user-scoped Git identity to repository-local config before write/pull operations.
+ */
+
+// --- GitMergeRoutes (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief FastAPI endpoints for merge operations (status, conflicts, resolve, abort, continue).
+ */
+
+// --- get_merge_status (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Return unfinished-merge status for repository (web-only recovery support).
+ */
+
+// --- get_merge_conflicts (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Return conflicted files with mine/theirs previews for web conflict resolver.
+ */
+
+// --- resolve_merge_conflicts (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Apply mine/theirs/manual conflict resolutions from WebUI and stage files.
+ */
+
+// --- abort_merge (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Abort unfinished merge from WebUI flow.
+ */
+
+// --- continue_merge (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Finalize unfinished merge from WebUI flow.
+ */
+
+// --- GitRepoLifecycleRoutes (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git lifecycle operations (sync, promote, deploy).
+ */
+
+// --- sync_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Sync dashboard state from Superset to Git using the GitPlugin.
+ */
+
+// --- promote_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Promote changes between branches via MR or direct merge.
+ */
+
+// --- deploy_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Deploy dashboard from Git to a target environment.
+ */
+
+// --- GitRepoOperationsRoutes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git repository operations (commit, push, pull, status, diff, history).
+ */
+
+// --- commit_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Stage and commit changes in the dashboard's repository.
+ */
+
+// --- push_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Push local commits to the remote repository.
+ */
+
+// --- pull_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Pull changes from the remote repository.
+ */
+
+// --- get_repository_status (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get current Git status for a dashboard repository.
+ */
+
+// --- get_repository_status_batch (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get Git statuses for multiple dashboard repositories in one request.
+ */
+
+// --- get_repository_diff (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get Git diff for a dashboard repository.
+ */
+
+// --- generate_commit_message (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Generate a suggested commit message using LLM.
+ */
+
+// --- GitRepoRoutes (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief FastAPI endpoints for core Git repository operations (init, binding, branches, checkout).
+ */
+
+// --- init_repository (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Link a dashboard to a Git repository and perform initial clone/init.
+ */
+
+// --- get_repository_binding (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Return repository binding with provider metadata for selected dashboard.
+ */
+
+// --- delete_repository (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Delete local repository workspace and DB binding for selected dashboard.
+ */
+
+// --- get_branches (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief List all branches for a dashboard's repository.
+ */
+
+// --- create_branch (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Create a new branch in the dashboard's repository.
+ */
+
+// --- checkout_branch (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Switch the dashboard's repository to a specific branch.
+ */
+
+// --- GitRouter (backend/src/api/routes/git/_router.py)
+/**!
+ * @brief Shared APIRouter for all Git route modules.
+ */
+
+// --- GitSchemas (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Defines Pydantic models for the Git integration API layer.
+ * @invariant All schemas must be compatible with the FastAPI router.
+ */
+
+// --- GitServerConfigBase (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Base schema for Git server configuration attributes.
+ */
+
+// --- GitServerConfigUpdate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for updating an existing Git server configuration.
+ */
+
+// --- GitServerConfigCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for creating a new Git server configuration.
+ */
+
+// --- GitServerConfigSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a Git server configuration with metadata.
+ */
+
+// --- GitRepositorySchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for tracking a local Git repository linked to a dashboard.
+ */
+
+// --- BranchSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a Git branch metadata.
+ */
+
+// --- CommitSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing Git commit details.
+ */
+
+// --- BranchCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for branch creation requests.
+ */
+
+// --- BranchCheckout (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for branch checkout requests.
+ */
+
+// --- CommitCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for staging and committing changes.
+ */
+
+// --- ConflictResolution (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for resolving merge conflicts.
+ */
+
+// --- MergeStatusSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema representing unfinished merge status for repository.
+ */
+
+// --- MergeConflictFileSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing one conflicted file with optional side snapshots.
+ */
+
+// --- MergeResolveRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for resolving one or multiple merge conflicts.
+ */
+
+// --- MergeContinueRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for finishing merge with optional explicit commit message.
+ */
+
+// --- DeploymentEnvironmentSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a target deployment environment.
+ */
+
+// --- DeployRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for dashboard deployment requests.
+ */
+
+// --- RepoInitRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for repository initialization requests.
+ */
+
+// --- RepositoryBindingSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing repository-to-config binding and provider metadata.
+ */
+
+// --- RepoStatusBatchRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for requesting repository statuses for multiple dashboards in a single call.
+ */
+
+// --- RepoStatusBatchResponse (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for returning repository statuses keyed by dashboard ID.
+ */
+
+// --- GiteaRepoSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing a Gitea repository.
+ */
+
+// --- GiteaRepoCreateRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for creating a Gitea repository.
+ */
+
+// --- RemoteRepoSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Provider-agnostic remote repository payload.
+ */
+
+// --- RemoteRepoCreateRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Provider-agnostic repository creation request.
+ */
+
+// --- PromoteRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for branch promotion workflow.
+ */
+
+// --- PromoteResponse (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Response schema for promotion operation result.
+ */
+
+// --- health_router (backend/src/api/routes/health.py)
+/**!
+ * @brief API endpoints for dashboard health monitoring and status aggregation.
+ */
+
+// --- get_health_summary (backend/src/api/routes/health.py)
+/**!
+ * @brief Get aggregated health status for all dashboards.
+ * @post Returns HealthSummaryResponse.
+ * @pre Caller has read permission for dashboard health view.
+ */
+
+// --- delete_health_report (backend/src/api/routes/health.py)
+/**!
+ * @brief Delete one persisted dashboard validation report from health summary.
+ * @post Validation record is removed; linked task/logs are cleaned when available.
+ * @pre Caller has write permission for tasks/report maintenance.
+ */
+
+// --- LlmRoutes (backend/src/api/routes/llm.py)
+/**!
+ * @brief API routes for LLM provider configuration and management.
+ */
+
+// --- FetchModelsRequest (backend/src/api/routes/llm.py)
+/**!
+ * @brief Pydantic request model for the fetch-models endpoint.
+ */
+
+// --- router (backend/src/api/routes/llm.py)
+/**!
+ * @brief APIRouter instance for LLM routes.
+ */
+
+// --- _is_valid_runtime_api_key (backend/src/api/routes/llm.py)
+/**!
+ * @brief Validate decrypted runtime API key presence/shape.
+ * @post Returns True only for non-placeholder key.
+ * @pre value can be None.
+ */
+
+// --- get_providers (backend/src/api/routes/llm.py)
+/**!
+ * @brief Retrieve all LLM provider configurations.
+ * @post Returns list of LLMProviderConfig.
+ * @pre User is authenticated.
+ */
+
+// --- fetch_models (backend/src/api/routes/llm.py)
+/**!
+ * @brief Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.
+ * @post Returns a list of available model IDs.
+ * @pre User is authenticated. Either provider_id or base_url+provider_type must be provided.
+ */
+
+// --- get_llm_status (backend/src/api/routes/llm.py)
+/**!
+ * @brief Returns whether LLM runtime is configured for dashboard validation.
+ * @post configured=true only when an active provider with valid decrypted key exists.
+ * @pre User is authenticated.
+ */
+
+// --- create_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Create a new LLM provider configuration.
+ * @post Returns the created LLMProviderConfig.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- update_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Update an existing LLM provider configuration.
+ * @post Returns the updated LLMProviderConfig.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- delete_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Delete an LLM provider configuration.
+ * @post Returns success status.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- test_connection (backend/src/api/routes/llm.py)
+/**!
+ * @brief Test connection to an LLM provider.
+ * @post Returns success status and message.
+ * @pre User is authenticated.
+ */
+
+// --- test_provider_config (backend/src/api/routes/llm.py)
+/**!
+ * @brief Test connection with a provided configuration (not yet saved).
+ * @post Returns success status and message.
+ * @pre User is authenticated.
+ */
+
+// --- MaintenanceRoutesPackage (backend/src/api/routes/maintenance/__init__.py)
+/**!
+ * @brief Maintenance Banner API route package.
+ */
+
+// --- MaintenanceRouter (backend/src/api/routes/maintenance/_router.py)
+/**!
+ * @brief FastAPI APIRouter for the Maintenance Banner endpoints.
+ */
+
+// --- MaintenanceRoutesModule (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Route handler stubs for all 7 Maintenance Banner API endpoints with RBAC guards per FR-015.
+ * @invariant RBAC enforced per FR-015 matrix via has_permission() dependency.
+ */
+
+// --- list_dashboard_banners (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get per-dashboard banner state for the Dashboard Hub indicator.
+ */
+
+// --- list_events (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get active and completed maintenance event lists with affected dashboard counts.
+ */
+
+// --- start_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Start a maintenance event. Validates input, creates event, dispatches TaskManager task.
+ */
+
+// --- end_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief End a specific maintenance event by ID. Removes banners from affected dashboards.
+ */
+
+// --- end_all_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief End all active maintenance events. Removes all banners from all dashboards.
+ */
+
+// --- get_maintenance_settings (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get current maintenance settings configuration.
+ */
+
+// --- update_maintenance_settings (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Update maintenance settings. All fields optional for partial update.
+ */
+
+// --- MaintenanceSchemasModule (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Pydantic models for Maintenance Banner API: request/response schemas per data-model.md.
+ * @invariant All response schemas use the standard envelope shape: { status, data, error, meta }
+ */
+
+// --- MaintenanceStartRequest (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief POST /api/maintenance/start request body with environment scoping.
+ */
+
+// --- MaintenanceSettingsUpdate (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief PUT /api/maintenance/settings request body — all fields optional for partial update.
+ */
+
+// --- MaintenanceStartResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for /api/maintenance/start — always 202 with task_id.
+ */
+
+// --- MaintenanceDashboardResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Describes a single dashboard affected by a maintenance operation.
+ */
+
+// --- MaintenanceFailedDashboard (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Describes a dashboard that failed during banner apply/removal.
+ */
+
+// --- MaintenanceTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed maintenance start task.
+ */
+
+// --- MaintenanceEndResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for /api/maintenance/{id}/end and /api/maintenance/end-all — always 202 with task_id.
+ */
+
+// --- MaintenanceEndTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed end maintenance task.
+ */
+
+// --- MaintenanceEndAllTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed end-all maintenance task.
+ */
+
+// --- MaintenanceSettingsResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for GET /api/maintenance/settings.
+ */
+
+// --- MaintenanceEventItem (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Single maintenance event summary for GET /api/maintenance/events.
+ */
+
+// --- MaintenanceEventListResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for GET /api/maintenance/events.
+ */
+
+// --- MaintenanceDashboardBannerState (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Per-dashboard banner state for GET /api/maintenance/dashboard-banners.
+ */
+
+// --- MaintenanceAlreadyActiveResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for duplicate /start call — idempotency hit.
+ */
+
+// --- MappingsApi (backend/src/api/routes/mappings.py)
+/**!
+ * @brief API endpoints for managing database mappings and getting suggestions.
+ */
+
+// --- MappingCreate (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- MappingResponse (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- SuggestRequest (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- get_mappings (backend/src/api/routes/mappings.py)
+/**!
+ * @brief List all saved database mappings.
+ * @post Returns filtered list of DatabaseMapping records.
+ * @pre db session is injected.
+ */
+
+// --- create_mapping (backend/src/api/routes/mappings.py)
+/**!
+ * @brief Create or update a database mapping.
+ * @post DatabaseMapping created or updated in database.
+ * @pre mapping is valid MappingCreate, db session is injected.
+ */
+
+// --- suggest_mappings_api (backend/src/api/routes/mappings.py)
+/**!
+ * @brief Get suggested mappings based on fuzzy matching.
+ * @post Returns mapping suggestions.
+ * @pre request is valid SuggestRequest, config_manager is injected.
+ */
+
+// --- MigrationApi (backend/src/api/routes/migration.py)
+/**!
+ * @brief HTTP contract layer for migration orchestration, settings, dry-run, and mapping sync endpoints.
+ * @invariant Migration endpoints never execute with invalid environment references and always return explicit HTTP errors on guard failures.
+ * @post Migration tasks are enqueued or dry-run results are computed and returned.
+ * @pre Backend core services initialized and Database session available.
+ */
+
+// --- execute_migration (backend/src/api/routes/migration.py)
+/**!
+ * @brief Validate migration selection and enqueue asynchronous migration task execution.
+ * @invariant Migration task dispatch never occurs before source and target environment ids pass guard validation.
+ * @post Returns {"task_id": str, "message": str} when task creation succeeds; emits HTTP_400/HTTP_500 on failure.
+ * @pre DashboardSelection payload is valid and both source/target environments exist.
+ */
+
+// --- dry_run_migration (backend/src/api/routes/migration.py)
+/**!
+ * @brief Build pre-flight migration diff and risk summary without mutating target systems.
+ * @invariant Dry-run flow remains read-only and rejects identical source/target environments before service execution.
+ * @post Returns deterministic dry-run payload; emits HTTP_400 for guard violations and HTTP_500 for orchestrator value errors.
+ * @pre DashboardSelection is valid, source and target environments exist, differ, and selected_ids is non-empty.
+ */
+
+// --- get_migration_settings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Read and return configured migration synchronization cron expression.
+ * @post Returns {"cron": str} reflecting current persisted settings value.
+ * @pre Configuration store is available and requester has READ permission.
+ */
+
+// --- update_migration_settings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Validate and persist migration synchronization cron expression update.
+ * @post Returns {"cron": str, "status": "updated"} and persists updated cron value.
+ * @pre Payload includes "cron" key and requester has WRITE permission.
+ */
+
+// --- get_resource_mappings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Fetch synchronized resource mappings with optional filters and pagination for migration mappings view.
+ * @post Returns {"items": [...], "total": int} where items reflect applied filters and pagination.
+ * @pre skip>=0, 1<=limit<=500, DB session is active, requester has READ permission.
+ */
+
+// --- trigger_sync_now (backend/src/api/routes/migration.py)
+/**!
+ * @brief Trigger immediate ID synchronization for every configured environment.
+ * @post Returns sync summary with synced/failed counts after attempting all environments.
+ * @pre At least one environment is configured and requester has EXECUTE permission.
+ */
+
+// --- PluginsRouter (backend/src/api/routes/plugins.py)
+/**!
+ * @brief Defines the FastAPI router for plugin-related endpoints, allowing clients to list available plugins.
+ */
+
+// --- list_plugins (backend/src/api/routes/plugins.py)
+/**!
+ * @brief Retrieve a list of all available plugins.
+ * @post Returns a list of PluginConfig objects.
+ * @pre plugin_loader is injected via Depends.
+ */
+
+// --- ProfileApiModule (backend/src/api/routes/profile.py)
+/**!
+ * @brief Exposes self-scoped profile preference endpoints and environment-based Superset account lookup.
+ * @invariant Endpoints are self-scoped and never mutate another user preference.
+ * @post Profile endpoints registered
+ * @pre Auth middleware configured, database session available
+ */
+
+// --- _get_profile_service (backend/src/api/routes/profile.py)
+/**!
+ * @brief Build profile service for current request scope.
+ * @post Returns a ready ProfileService instance.
+ * @pre db session and config manager are available.
+ */
+
+// --- get_preferences (backend/src/api/routes/profile.py)
+/**!
+ * @brief Get authenticated user's dashboard filter preference.
+ * @post Returns preference payload for current user only.
+ * @pre Valid JWT and authenticated user context.
+ */
+
+// --- update_preferences (backend/src/api/routes/profile.py)
+/**!
+ * @brief Update authenticated user's dashboard filter preference.
+ * @post Persists normalized preference for current user or raises validation/authorization errors.
+ * @pre Valid JWT and valid request payload.
+ */
+
+// --- lookup_superset_accounts (backend/src/api/routes/profile.py)
+/**!
+ * @brief Lookup Superset account candidates in selected environment.
+ * @post Returns success or degraded lookup payload with stable shape.
+ * @pre Valid JWT, authenticated context, and environment_id query parameter.
+ */
+
+// --- ReportsRouter (backend/src/api/routes/reports.py)
+/**!
+ * @brief FastAPI router for unified task report list and detail retrieval endpoints.
+ * @invariant Endpoints are read-only and do not trigger long-running tasks.
+ * @post Router is configured and endpoints are ready for registration.
+ * @pre Reports service and dependencies are initialized.
+ */
+
+// --- _parse_csv_enum_list (backend/src/api/routes/reports.py)
+/**!
+ * @brief Parse comma-separated query value into enum list.
+ * @post Returns enum list or raises HTTP 400 with deterministic machine-readable payload.
+ * @pre raw may be None/empty or comma-separated values.
+ */
+
+// --- list_reports (backend/src/api/routes/reports.py)
+/**!
+ * @brief Return paginated unified reports list.
+ * @post deterministic error payload for invalid filters.
+ * @pre authenticated/authorized request and validated query params.
+ */
+
+// --- get_report_detail (backend/src/api/routes/reports.py)
+/**!
+ * @brief Return one normalized report detail with diagnostics and next actions.
+ * @post returns normalized detail envelope or 404 when report is not found.
+ * @pre authenticated/authorized request and existing report_id.
+ */
+
+// --- SettingsRouter (backend/src/api/routes/settings.py)
+/**!
+ * @brief Provides API endpoints for managing application settings and Superset environments.
+ * @invariant All settings changes must be persisted via ConfigManager.
+ * @post Settings are read or written via ConfigManager.
+ * @pre ConfigManager is initialized and accessible.
+ */
+
+// --- LoggingConfigResponse (backend/src/api/routes/settings.py)
+/**!
+ * @brief Response model for logging configuration with current task log level.
+ */
+
+// --- _validate_superset_connection_fast (backend/src/api/routes/settings.py)
+/**!
+ * @brief Run lightweight Superset connectivity validation without full pagination scan.
+ * @post Raises on auth/API failures; returns None on success.
+ * @pre env contains valid URL and credentials.
+ */
+
+// --- get_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves all application settings.
+ * @post Returns masked AppConfig.
+ * @pre Config manager is available.
+ */
+
+// --- get_features (backend/src/api/routes/settings.py)
+/**!
+ * @brief Public endpoint returning feature flags for frontend sidebar filtering.
+ * @post Returns dict with dataset_review and health_monitor booleans.
+ * @pre Config manager is available.
+ */
+
+// --- get_storage_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves storage-specific settings.
+ */
+
+// --- update_storage_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates storage-specific settings.
+ * @post Storage settings are updated and saved.
+ */
+
+// --- test_environment_connection (backend/src/api/routes/settings.py)
+/**!
+ * @brief Tests the connection to a Superset environment.
+ * @post Returns success or error status.
+ * @pre ID is provided.
+ */
+
+// --- get_logging_config (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves current logging configuration.
+ * @post Returns logging configuration.
+ * @pre Config manager is available.
+ */
+
+// --- update_logging_config (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates logging configuration.
+ * @post Logging configuration is updated and saved.
+ * @pre New logging config is provided.
+ */
+
+// --- ConsolidatedSettingsResponse (backend/src/api/routes/settings.py)
+/**!
+ * @brief Response model for consolidated application settings.
+ */
+
+// --- get_consolidated_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves all settings categories in a single call.
+ * @post Returns consolidated settings, provider metadata, and persisted notification payload in one stable response.
+ * @pre Config manager is available and the caller holds admin settings read permission.
+ */
+
+// --- update_consolidated_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Bulk update application settings from the consolidated view.
+ * @post Settings are updated and saved via ConfigManager.
+ * @pre User has admin permissions, config is valid.
+ */
+
+// --- get_validation_policies (backend/src/api/routes/settings.py)
+/**!
+ * @brief Lists all validation policies.
+ */
+
+// --- create_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Creates a new validation policy.
+ */
+
+// --- update_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates an existing validation policy.
+ */
+
+// --- delete_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Deletes a validation policy.
+ */
+
+// --- get_translation_schedules (backend/src/api/routes/settings.py)
+/**!
+ * @brief Lists all translation schedules joined with translation job names.
+ */
+
+// --- storage_routes (backend/src/api/routes/storage.py)
+/**!
+ * @brief API endpoints for file storage management (backups and repositories).
+ * @invariant All paths must be validated against path traversal.
+ */
+
+// --- list_files (backend/src/api/routes/storage.py)
+/**!
+ * @brief List all files and directories in the storage system.
+ * @post Returns a list of StoredFile objects.
+ * @pre None.
+ */
+
+// --- delete_file (backend/src/api/routes/storage.py)
+/**!
+ * @brief Delete a specific file or directory.
+ * @post Item is removed from storage.
+ * @pre category must be a valid FileCategory.
+ */
+
+// --- download_file (backend/src/api/routes/storage.py)
+/**!
+ * @brief Retrieve a file for download.
+ * @post Returns a FileResponse.
+ * @pre category must be a valid FileCategory.
+ */
+
+// --- get_file_by_path (backend/src/api/routes/storage.py)
+/**!
+ * @brief Retrieve a file by validated absolute/relative path under storage root.
+ * @post Returns a FileResponse for existing files.
+ * @pre path must resolve under configured storage root.
+ */
+
+// --- TasksRouter (backend/src/api/routes/tasks.py)
+/**!
+ * @brief Defines the FastAPI router for task-related endpoints, allowing clients to create, list, and get the status of tasks.
+ */
+
+// --- resume_task (backend/src/api/routes/tasks.py)
+/**!
+ * @brief Resume a task that is awaiting input (e.g., passwords).
+ * @post Task resumes execution with provided input.
+ * @pre task must be in AWAITING_INPUT status.
+ */
+
+// --- TranslateRoutes (backend/src/api/routes/translate/__init__.py)
+/**!
+ * @brief API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.
+ * @post Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed.
+ * @pre API server is running, user is authenticated, database is accessible.
+ */
+
+// --- TranslateCorrectionRoutesModule (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Term correction submission endpoints.
+ */
+
+// --- submit_correction (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Submit a term correction from a run result review.
+ * @post Correction applied with conflict detection.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- submit_bulk_corrections (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Submit multiple term corrections atomically.
+ * @post All corrections applied or none with conflict list.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- TranslateDictionaryRoutesModule (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Terminology Dictionary CRUD, entries management, and import routes.
+ */
+
+// --- list_dictionaries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief List all terminology dictionaries.
+ * @post Returns list of dictionaries with total count.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- get_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Get a single terminology dictionary by ID.
+ * @post Returns the dictionary with entry_count.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- create_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Create a new terminology dictionary.
+ * @post Returns the created dictionary.
+ * @pre User has translate.dictionary.create permission.
+ */
+
+// --- update_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Update an existing terminology dictionary.
+ * @post Returns the updated dictionary.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- delete_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Delete a terminology dictionary, blocked if attached to active/scheduled jobs.
+ * @post Dictionary is deleted.
+ * @pre User has translate.dictionary.delete permission.
+ */
+
+// --- list_dictionary_entries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief List entries for a dictionary, optionally filtered by language pair.
+ * @post Returns paginated list of entries with language pair fields.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- add_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Add a new entry to a dictionary.
+ * @post Entry is created.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- edit_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Update an existing dictionary entry.
+ * @post Entry is updated.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- delete_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Delete a dictionary entry.
+ * @post Entry is deleted.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- import_dictionary_entries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Import entries into a terminology dictionary from CSV/TSV content.
+ * @post Entries are imported per conflict mode.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- TranslateHelpersModule (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Shared helper functions for translate route handlers.
+ */
+
+// --- _run_to_response (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Convert TranslationRun ORM to response dict.
+ */
+
+// --- _dict_to_response (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Convert a TerminologyDictionary ORM model to a response dict with computed entry_count.
+ */
+
+// --- _get_dictionary_entry_counts (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Get entry counts for a list of dictionary IDs.
+ */
+
+// --- TranslateJobRoutesModule (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Translation Job CRUD and datasource column routes.
+ */
+
+// --- list_jobs (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief List all translation jobs.
+ * @post Returns list of translation jobs.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- get_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Get a single translation job by ID.
+ * @post Returns the translation job.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- create_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Create a new translation job.
+ * @post Returns the created translation job.
+ * @pre User has translate.job.create permission.
+ */
+
+// --- update_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Update an existing translation job.
+ * @post Returns the updated translation job.
+ * @pre User has translate.job.edit permission.
+ */
+
+// --- delete_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Delete a translation job.
+ * @post Job is deleted.
+ * @pre User has translate.job.delete permission.
+ */
+
+// --- duplicate_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Duplicate a translation job.
+ * @post Returns the duplicated job with status DRAFT.
+ * @pre User has translate.job.create permission.
+ */
+
+// --- get_datasource_columns (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Get column metadata and database dialect for a Superset datasource.
+ * @post Returns column list with metadata and database_dialect.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- check_target_schema (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Проверяет схему целевой таблицы: какие колонки ожидаются, какие есть, каких не хватает.
+ */
+
+// --- TranslateMetricsRoutesModule (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Translation Metrics endpoints.
+ */
+
+// --- get_metrics (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Get translation metrics, optionally filtered by job.
+ * @post Returns metrics data.
+ * @pre User has translate.metrics.view permission.
+ */
+
+// --- get_job_metrics (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Get aggregated metrics for a specific job.
+ * @post Returns metrics dict.
+ * @pre User has translate.metrics.view permission.
+ */
+
+// --- TranslatePreviewRoutesModule (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Translation Preview session management routes.
+ */
+
+// --- preview_translation (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Preview a translation before applying it.
+ * @post Returns a preview session with records and cost estimation.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- update_preview_row (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Approve, edit, or reject a preview row (optionally per language).
+ * @post Preview row status is updated.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- accept_preview_session (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Accept a preview session, marking it as the quality gate for full execution.
+ * @post Preview session is marked as APPLIED; full execution can proceed.
+ * @pre User has translate.job.execute permission. Job has an ACTIVE preview session.
+ */
+
+// --- apply_preview (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Apply a preview session (alias for accept when accepting at session level).
+ * @post Preview is applied.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- get_preview_records (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Get records for a preview session.
+ * @post Returns list of preview records.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- TranslateRouterModule (backend/src/api/routes/translate/_router.py)
+/**!
+ * @brief APIRouter instance for translate routes.
+ */
+
+// --- translate_router (backend/src/api/routes/translate/_router.py)
+/**!
+ * @brief APIRouter instance for all translate sub-routes.
+ */
+
+// --- TranslateRunListRoutesModule (backend/src/api/routes/translate/_run_list_routes.py)
+/**!
+ * @brief Translation Run listing, detail, and CSV download routes (cross-job).
+ */
+
+// --- download_skipped_csv (backend/src/api/routes/translate/_run_list_routes.py)
+/**!
+ * @brief Download a CSV of skipped translation records from a run.
+ * @post Returns CSV file of skipped records.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- TranslateRunRoutesModule (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Translation Run execution, history, status, records and batches routes.
+ */
+
+// --- run_translation (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Execute a translation job (trigger a run).
+ * @post Returns the created translation run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- retry_run (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Retry failed batches in a translation run.
+ * @post Returns the updated translation run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- retry_insert (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Retry the SQL insert phase for a completed run.
+ * @post Returns the updated run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- cancel_run (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Cancel a running translation.
+ * @post Run is cancelled.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- get_run_history (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get run history for a translation job.
+ * @post Returns list of runs.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_run_status (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get status and statistics for a translation run.
+ * @post Returns run details with statistics.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_run_records (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get paginated records for a translation run.
+ * @post Returns paginated records.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_batches (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get batches for a translation run.
+ * @post Returns list of batches.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- override_detected_language (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Manually override the detected source language for a specific translation language entry.
+ * @post TranslationLanguage.source_language_detected is updated; language_overridden is set to True.
+ * @pre User has translate.job.execute permission. Run, record, and language entry exist.
+ */
+
+// --- inline_edit_translation (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Apply an inline correction to a translated value on a completed run result.
+ * @post TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.
+ * @pre User has translate.job.execute permission. Run, record, and language entry exist.
+ */
+
+// --- bulk_find_replace (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Perform bulk find-and-replace on translated values within a run.
+ * @post If preview=false, matching translations are updated. Optional dictionary submission.
+ * @pre User has translate.job.execute permission. Run exists.
+ */
+
+// --- TranslateScheduleRoutesModule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Translation Schedule management routes.
+ */
+
+// --- get_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Get the schedule for a translation job.
+ * @post Returns the schedule configuration.
+ * @pre User has translate.schedule.view permission.
+ */
+
+// --- set_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Set or update the schedule for a translation job.
+ * @post Schedule is created or updated.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- enable_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Enable a schedule for a translation job.
+ * @post Schedule is enabled.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- disable_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Disable a schedule for a translation job.
+ * @post Schedule is disabled.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- delete_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Delete the schedule for a translation job.
+ * @post Schedule is removed.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- get_next_executions (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Preview next N executions for a job's schedule.
+ * @post Returns next execution times.
+ * @pre User has translate.schedule.view permission.
+ */
+
+// --- ValidationRoutes (backend/src/api/routes/validation.py)
+/**!
+ * @brief API routes for validation task management and run history.
+ */
+
+// --- _get_task_service (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- _get_run_service (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- list_tasks (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- update_task (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- delete_task (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- trigger_run (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- list_runs (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- get_run_detail (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- delete_run (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- ValidationApiTests (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Unit tests for validation task CRUD and run history API endpoints.
+ * @invariant provider_id must reference a multimodal LLM provider for creation
+ */
+
+// --- test_list_tasks_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/tasks returns paginated task list with filters.
+ */
+
+// --- test_list_tasks_pagination (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Pagination query params are validated: page >= 1, page_size 1-100.
+ */
+
+// --- test_list_tasks_service_error (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Service ValueError becomes 400 on list_tasks.
+ */
+
+// --- test_create_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST /validation/tasks with valid payload returns 201.
+ */
+
+// --- test_create_task_missing_fields (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST with missing required fields returns 422.
+ */
+
+// --- test_create_task_invalid_provider (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST with non-multimodal provider returns 422.
+ */
+
+// --- test_get_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/tasks/{id} returns task with recent_runs.
+ */
+
+// --- test_get_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET for nonexistent task returns 404.
+ */
+
+// --- test_update_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief PUT /validation/tasks/{id} updates task and returns updated object.
+ */
+
+// --- test_update_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief PUT for nonexistent task returns 404.
+ */
+
+// --- test_delete_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE /validation/tasks/{id} returns 204.
+ */
+
+// --- test_delete_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE for nonexistent task returns 404.
+ */
+
+// --- test_delete_task_with_runs_flag (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE with delete_runs=true passes query param to service.
+ */
+
+// --- test_trigger_run_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST /validation/tasks/{id}/run spawns a validation task.
+ */
+
+// --- test_trigger_run_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST for nonexistent task returns 422.
+ */
+
+// --- test_trigger_run_no_dashboards (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Trigger fails with 422 when task has no dashboard IDs.
+ */
+
+// --- test_list_runs_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/runs returns paginated run list.
+ */
+
+// --- test_list_runs_filters (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief All 6 filter query params are accepted and forwarded to service.
+ */
+
+// --- test_list_runs_pagination (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Pagination boundary checks on runs list.
+ */
+
+// --- test_list_runs_invalid_status (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Status is a free string; any value passes through to service.
+ */
+
+// --- test_get_run_detail_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/runs/{id} returns full detail with issues and raw_response.
+ */
+
+// --- test_get_run_detail_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET for nonexistent run returns 404.
+ */
+
+// --- test_delete_run_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE /validation/runs/{id} returns 204.
+ */
+
+// --- test_delete_run_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE for nonexistent run returns 404.
+ */
+
+// --- test_endpoints_require_authentication (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Without current_user dependency, all 9 endpoints return 401.
+ */
+
+// --- test_permission_denied_non_admin (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief A non-admin user without validation.* permissions receives 403.
+ */
+
+// --- test_permission_denied_all_actions (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Each action (VIEW, CREATE, EDIT, DELETE, EXECUTE) denied for non-admin.
+ */
+
+// --- test_delete_task_runs_default_false (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief delete_runs query param defaults to False.
+ */
+
+// --- AppModule (backend/src/app.py)
+/**!
+ * @brief The main entry point for the FastAPI application.
+ * @invariant All WebSocket connections must be properly cleaned up on disconnect.
+ * @post FastAPI app instance is created, middleware configured, and routes registered.
+ * @pre Python environment and dependencies installed; configuration database available.
+ */
+
+// --- FastAPI_App (backend/src/app.py)
+/**!
+ * @brief Canonical FastAPI application instance for route, middleware, and websocket registration.
+ */
+
+// --- ensure_initial_admin_user (backend/src/app.py)
+/**!
+ * @brief Ensures initial admin user exists when bootstrap env flags are enabled.
+ */
+
+// --- startup_event (backend/src/app.py)
+/**!
+ * @brief Handles application startup tasks, such as starting the scheduler.
+ * @post Scheduler is started.
+ * @pre None.
+ */
+
+// --- shutdown_event (backend/src/app.py)
+/**!
+ * @brief Handles application shutdown tasks, such as stopping the scheduler.
+ * @post Scheduler is stopped.
+ * @pre None.
+ */
+
+// --- app_middleware (backend/src/app.py)
+/**!
+ * @brief Configure application-wide middleware (Session, CORS).
+ */
+
+// --- network_error_handler (backend/src/app.py)
+/**!
+ * @brief Global exception handler for NetworkError.
+ * @post Returns 503 HTTP Exception.
+ * @pre request is a FastAPI Request object.
+ */
+
+// --- log_requests (backend/src/app.py)
+/**!
+ * @brief Middleware to log incoming HTTP requests and their response status.
+ * @post Logs request and response details.
+ * @pre request is a FastAPI Request object.
+ */
+
+// --- API_Routes (backend/src/app.py)
+/**!
+ * @brief Register all FastAPI route groups exposed by the application entrypoint.
+ */
+
+// --- api.include_routers (backend/src/app.py)
+/**!
+ * @brief Registers all API routers with the FastAPI application.
+ */
+
+// --- websocket_endpoint (backend/src/app.py)
+/**!
+ * @brief Provides a WebSocket endpoint for real-time log streaming of a task with server-side filtering.
+ * @invariant Every accepted WebSocket subscription is unsubscribed exactly once even when streaming fails or the client disconnects.
+ * @post WebSocket connection is managed and logs are streamed until disconnect.
+ * @pre task_id must be a valid task ID.
+ */
+
+// --- dataset_websocket_endpoint (backend/src/app.py)
+/**!
+ * @brief WebSocket endpoint for dataset.updated events — auto-refresh on task completion.
+ * @post WebSocket streams dataset.updated events until disconnect.
+ * @pre env_id must reference a known environment.
+ */
+
+// --- StaticFiles (backend/src/app.py)
+/**!
+ * @brief Mounts the frontend build directory to serve static assets.
+ */
+
+// --- serve_spa (backend/src/app.py)
+/**!
+ * @brief Serves the SPA frontend for any path not matched by API routes.
+ * @post Returns the requested file or index.html.
+ * @pre frontend_path exists.
+ */
+
+// --- read_root (backend/src/app.py)
+/**!
+ * @brief A simple root endpoint to confirm that the API is running when frontend is missing.
+ * @post Returns a JSON message indicating API status.
+ * @pre None.
+ */
+
+// --- src.core (backend/src/core/__init__.py)
+/**!
+ * @brief Backend core services and infrastructure package root.
+ */
+
+// --- TestConfigManagerCompat (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Verifies ConfigManager compatibility wrappers preserve legacy payload sections.
+ */
+
+// --- test_get_payload_preserves_legacy_sections (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure get_payload merges typed config into raw payload without dropping legacy sections.
+ */
+
+// --- test_save_config_accepts_raw_payload_and_keeps_extras (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure save_config accepts raw dict payload, refreshes typed config, and preserves extra sections.
+ */
+
+// --- test_save_config_syncs_environment_records_for_fk_backed_flows (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure saving config mirrors typed environments into relational records required by FK-backed session persistence.
+ */
+
+// --- _FakeQuery (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal query stub returning hardcoded existing environment record list for sync tests.
+ * @invariant all() always returns [existing_record]; no parameterization or filtering.
+ */
+
+// --- _FakeSession (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal SQLAlchemy session stub that captures add/delete calls for environment sync assertions.
+ * @invariant query() always returns _FakeQuery; no real DB interaction.
+ */
+
+// --- test_save_config_syncs_deletions_to_persistence (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure stale environment records are deleted during save (in _delete_stale_environment_records)
+ */
+
+// --- _FakeQueryDel (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal query stub for deletion test.
+ */
+
+// --- _FakeSessionDel (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal session stub that captures add/delete for deletion assertions.
+ */
+
+// --- test_load_config_syncs_environment_records_from_existing_db_payload (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure loading an existing DB-backed config also mirrors environment rows required by FK-backed runtime flows.
+ */
+
+// --- NativeFilterExtractionTests (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Verify native filter extraction from permalinks and native_filters_key URLs.
+ */
+
+// --- test_extract_native_filters_from_permalink (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Extract native filters from a permalink key.
+ */
+
+// --- test_extract_native_filters_from_permalink_direct_response (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle permalink response without result wrapper.
+ */
+
+// --- test_extract_native_filters_from_key (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Extract native filters from a native_filters_key.
+ */
+
+// --- test_extract_native_filters_from_key_single_filter (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle single filter format in native filter state.
+ */
+
+// --- test_extract_native_filters_from_key_dict_value (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle filter state value as dict instead of JSON string.
+ */
+
+// --- test_parse_dashboard_url_for_filters_permalink (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse permalink URL format.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters_key URL format with numeric dashboard ID.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key_slug (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters_key URL format when dashboard reference is a slug, not a numeric ID.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Gracefully handle slug resolution failure for native_filters_key URL.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_filters_direct (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters direct query param.
+ */
+
+// --- test_parse_dashboard_url_for_filters_no_filters (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Return empty result when no filters present.
+ */
+
+// --- test_extra_form_data_merge (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ExtraFormDataMerge correctly merges dictionaries.
+ */
+
+// --- test_filter_state_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test FilterState Pydantic model.
+ */
+
+// --- test_parsed_native_filters_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ParsedNativeFilters Pydantic model.
+ */
+
+// --- test_parsed_native_filters_empty (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ParsedNativeFilters with no filters.
+ */
+
+// --- test_native_filter_data_mask_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test NativeFilterDataMask model.
+ */
+
+// --- test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Reconcile raw native filter ids from state to canonical metadata filter names.
+ */
+
+// --- test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Collapse raw-id state entries and metadata entries into one canonical filter.
+ */
+
+// --- test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Preserve unmatched raw native filter ids as fallback diagnostics when metadata mapping is unavailable.
+ */
+
+// --- test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Recovered native filter state should preserve exact Superset clause payload and time extras for preview compilation.
+ */
+
+// --- test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Assistant-facing imported-filter payload should redact likely PII while preserving structure metadata.
+ */
+
+// --- SupersetPreviewPipelineTests (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Verify explicit chart-data preview compilation and ensure non-dashboard 404 errors remain generic across sync and async clients.
+ */
+
+// --- _make_environment (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- _make_requests_http_error (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- _make_httpx_status_error (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- test_compile_dataset_preview_prefers_legacy_explore_form_data_strategy (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Superset preview compilation should prefer the legacy form_data transport inferred from browser traffic before falling back to chart-data.
+ */
+
+// --- test_compile_dataset_preview_falls_back_to_chart_data_after_legacy_failures (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Superset preview compilation should fall back to chart-data when legacy form_data strategies are rejected.
+ */
+
+// --- test_build_dataset_preview_query_context_places_recovered_filters_in_chart_style_form_data (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should mirror chart-style filter transport so recovered native filters reach Superset compilation.
+ */
+
+// --- test_build_dataset_preview_query_context_merges_dataset_template_params_and_preserves_user_values (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should merge dataset template params for parity with real dataset definitions while preserving explicit session overrides.
+ */
+
+// --- test_build_dataset_preview_query_context_preserves_time_range_from_native_filter_payload (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should preserve time-range native filter extras even when dataset defaults differ.
+ */
+
+// --- test_build_dataset_preview_legacy_form_data_preserves_native_filter_clauses (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Legacy preview form_data should preserve recovered native filter clauses in browser-style fields without duplicating datasource for QueryObjectFactory.
+ */
+
+// --- test_sync_network_404_mapping_keeps_non_dashboard_endpoints_generic (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Sync network client should reserve dashboard-not-found translation for dashboard endpoints only.
+ */
+
+// --- test_sync_network_404_mapping_translates_dashboard_endpoints (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Sync network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+ */
+
+// --- test_async_network_404_mapping_keeps_non_dashboard_endpoints_generic (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Async network client should reserve dashboard-not-found translation for dashboard endpoints only.
+ */
+
+// --- test_async_network_404_mapping_translates_dashboard_endpoints (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Async network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+ */
+
+// --- TestSupersetProfileLookup (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Verifies Superset profile lookup adapter payload normalization and fallback error precedence.
+ */
+
+// --- _RecordingNetworkClient (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Records request payloads and returns scripted responses for deterministic adapter tests.
+ * @invariant Each request consumes one scripted response in call order and persists call metadata.
+ */
+
+// --- test_get_users_page_sends_lowercase_order_direction (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Ensures adapter sends lowercase order_direction compatible with Superset rison schema.
+ * @post First request query payload contains order_direction='asc' for asc sort.
+ * @pre Adapter is initialized with recording network client.
+ */
+
+// --- test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Ensures fallback auth error does not mask primary schema/query failure.
+ * @post Raised exception remains primary SupersetAPIError (non-auth) to preserve root cause.
+ * @pre Primary endpoint fails with SupersetAPIError and fallback fails with AuthenticationError.
+ */
+
+// --- test_get_users_page_uses_fallback_endpoint_when_primary_fails (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Verifies adapter retries second users endpoint and succeeds when fallback is healthy.
+ * @post Result status is success and both endpoints were attempted in order.
+ * @pre Primary endpoint fails; fallback returns valid users payload.
+ */
+
+// --- test_throttled_scheduler (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Unit tests for ThrottledSchedulerConfigurator distribution logic.
+ */
+
+// --- test_calculate_schedule_even_distribution (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate even spacing across a two-hour scheduling window for three tasks.
+ */
+
+// --- test_calculate_schedule_midnight_crossing (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate scheduler correctly rolls timestamps into the next day across midnight.
+ */
+
+// --- test_calculate_schedule_single_task (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate single-task schedule returns only the window start timestamp.
+ */
+
+// --- test_calculate_schedule_empty_list (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate empty dashboard list produces an empty schedule.
+ */
+
+// --- test_calculate_schedule_zero_window (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate zero-length window schedules all tasks at identical start timestamp.
+ */
+
+// --- test_calculate_schedule_very_small_window (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate sub-second interpolation when task count exceeds near-zero window granularity.
+ */
+
+// --- AsyncSupersetClientModule (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+ */
+
+// --- AsyncSupersetClient (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Async sibling of SupersetClient for dashboard read paths.
+ */
+
+// --- AsyncSupersetClientInit (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Initialize async Superset client with AsyncAPIClient transport.
+ * @post Client uses async network transport and inherited projection helpers.
+ * @pre env is valid Environment instance.
+ */
+
+// --- AsyncSupersetClientClose (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Close async transport resources.
+ * @post Underlying AsyncAPIClient is closed.
+ */
+
+// --- get_dashboards_page_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one dashboards page asynchronously.
+ * @post Returns total count and page result list.
+ */
+
+// --- get_dashboard_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one dashboard payload asynchronously.
+ * @post Returns raw dashboard payload from Superset API.
+ */
+
+// --- get_chart_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one chart payload asynchronously.
+ * @post Returns raw chart payload from Superset API.
+ */
+
+// --- get_dashboard_detail_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch dashboard detail asynchronously with concurrent charts/datasets requests.
+ * @post Returns dashboard detail payload for overview page.
+ */
+
+// --- get_dashboard_permalink_state_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch stored dashboard permalink state asynchronously.
+ * @post Returns dashboard permalink state payload from Superset API.
+ */
+
+// --- get_native_filter_state_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch stored native filter state asynchronously.
+ * @post Returns native filter state payload from Superset API.
+ */
+
+// --- extract_native_filters_from_permalink_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Extract native filters dataMask from a permalink key asynchronously.
+ * @post Returns extracted dataMask with filter states.
+ */
+
+// --- extract_native_filters_from_key_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Extract native filters from a native_filters_key URL parameter asynchronously.
+ * @post Returns extracted filter state with extraFormData.
+ */
+
+// --- parse_dashboard_url_for_filters_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+ * @post Returns extracted filter state or empty dict if no filters found.
+ */
+
+// --- AuthPackage (backend/src/core/auth/__init__.py)
+/**!
+ * @brief Authentication and authorization package root.
+ */
+
+// --- test_auth (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Unit tests for authentication module
+ */
+
+// --- test_create_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies that a persisted user can be retrieved with intact credential hash.
+ */
+
+// --- test_authenticate_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Validates authentication outcomes for valid, wrong-password, and unknown-user cases.
+ */
+
+// --- test_create_session (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Ensures session creation returns bearer token payload fields.
+ */
+
+// --- test_role_permission_association (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Confirms role-permission many-to-many assignments persist and reload correctly.
+ */
+
+// --- test_user_role_association (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Confirms user-role assignment persists and is queryable from repository reads.
+ */
+
+// --- test_ad_group_mapping (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies AD group mapping rows persist and reference the expected role.
+ */
+
+// --- test_authenticate_user_updates_last_login (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies successful authentication updates last_login audit field.
+ */
+
+// --- test_authenticate_inactive_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies inactive accounts are rejected during password authentication.
+ */
+
+// --- test_verify_password_empty_hash (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies password verification safely rejects empty or null password hashes.
+ */
+
+// --- test_provision_adfs_user_new (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies JIT provisioning creates a new ADFS user and maps group-derived roles.
+ */
+
+// --- test_provision_adfs_user_existing (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.
+ */
+
+// --- APIKeyUtilities (backend/src/core/auth/api_key.py)
+/**!
+ * @brief API key generation and hashing utilities for service-to-service authentication.
+ * @invariant hash_api_key() produces SHA-256 hex digest for lookup and storage.
+ */
+
+// --- generate_api_key (backend/src/core/auth/api_key.py)
+/**!
+ * @brief Generate a new API key in ssk_ format with SHA-256 hash.
+ * @post Returns (raw_key, prefix, key_hash) — raw_key shown ONCE to caller, never stored.
+ */
+
+// --- hash_api_key (backend/src/core/auth/api_key.py)
+/**!
+ * @brief Hash an API key string to SHA-256 hex digest for lookup.
+ * @post Returns 64-character hex digest.
+ * @pre raw_key is a non-empty string.
+ */
+
+// --- AuthConfigModule (backend/src/core/auth/config.py)
+/**!
+ * @brief Centralized configuration for authentication and authorization.
+ * @invariant All sensitive configuration must be loaded from environment; no hardcoded secrets.
+ */
+
+// --- AuthConfig (backend/src/core/auth/config.py)
+/**!
+ * @brief Holds authentication-related settings.
+ * @post Returns a configuration object with validated settings.
+ * @pre Environment variables may be provided via .env file.
+ */
+
+// --- auth_config (backend/src/core/auth/config.py)
+/**!
+ * @brief Singleton instance of AuthConfig.
+ */
+
+// --- AuthJwtModule (backend/src/core/auth/jwt.py)
+/**!
+ * @brief JWT token generation and validation logic.
+ * @invariant Tokens must include expiration time and user identifier.
+ * @post Token encode/decode functions exported
+ * @pre JWT secret configured in environment
+ */
+
+// --- create_access_token (backend/src/core/auth/jwt.py)
+/**!
+ * @brief Generates a new JWT access token.
+ * @post Returns a signed JWT string.
+ * @pre data dict contains 'sub' (user_id) and optional 'scopes' (roles).
+ */
+
+// --- decode_token (backend/src/core/auth/jwt.py)
+/**!
+ * @brief Decodes and validates a JWT token.
+ * @post Returns the decoded payload if valid.
+ * @pre token is a signed JWT string.
+ */
+
+// --- AuthLoggerModule (backend/src/core/auth/logger.py)
+/**!
+ * @brief Structured auth logging module for audit trail generation.
+ * @invariant Must not log sensitive data like passwords or full tokens.
+ * @post Audit logging functions exported
+ * @pre Auth module initialized
+ */
+
+// --- log_security_event (backend/src/core/auth/logger.py)
+/**!
+ * @brief Logs a security-related event for audit trails.
+ * @post Security event is written to the application log.
+ * @pre event_type and username are strings.
+ */
+
+// --- AuthOauthModule (backend/src/core/auth/oauth.py)
+/**!
+ * @brief ADFS OIDC configuration and client using Authlib.
+ * @invariant Must use secure OIDC flows.
+ */
+
+// --- oauth (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Global Authlib OAuth registry.
+ */
+
+// --- register_adfs (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Registers the ADFS OIDC client.
+ * @post ADFS client is registered in oauth registry.
+ * @pre ADFS configuration is provided in auth_config.
+ */
+
+// --- is_adfs_configured (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Checks if ADFS is properly configured.
+ * @post Returns True if ADFS client is registered, False otherwise.
+ * @pre None.
+ */
+
+// --- AuthRepositoryModule (backend/src/core/auth/repository.py)
+/**!
+ * @brief Data access layer for authentication and user preference entities.
+ * @invariant All database read/write operations must execute via the injected SQLAlchemy session boundary.
+ * @post Provides valid access to identity data.
+ * @pre Database connection is active.
+ */
+
+// --- AuthRepository (backend/src/core/auth/repository.py)
+/**!
+ * @brief Provides low-level CRUD operations for identity and authorization records.
+ * @post Entity instances returned safely.
+ * @pre Database session is bound.
+ */
+
+// --- get_user_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve user by UUID.
+ * @post Returns User object if found, else None.
+ * @pre user_id is a valid UUID string.
+ */
+
+// --- get_user_by_username (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve user by username.
+ * @post Returns User object if found, else None.
+ * @pre username is a non-empty string.
+ */
+
+// --- get_role_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve role by UUID with permissions preloaded.
+ */
+
+// --- get_role_by_name (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve role by unique name.
+ */
+
+// --- get_permission_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve permission by UUID.
+ */
+
+// --- get_permission_by_resource_action (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve permission by resource and action tuple.
+ */
+
+// --- list_permissions (backend/src/core/auth/repository.py)
+/**!
+ * @brief List all system permissions.
+ */
+
+// --- get_user_dashboard_preference (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve dashboard filters/preferences for a user.
+ */
+
+// --- get_roles_by_ad_groups (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve roles that match a list of AD group names.
+ * @post Returns a list of Role objects mapped to the provided AD groups.
+ * @pre groups is a list of strings representing AD group identifiers.
+ */
+
+// --- AuthSecurityModule (backend/src/core/auth/security.py)
+/**!
+ * @brief Utility for password hashing and verification using Passlib.
+ * @invariant Uses bcrypt for hashing with standard work factor.
+ */
+
+// --- verify_password (backend/src/core/auth/security.py)
+/**!
+ * @brief Verifies a plain password against a hashed password.
+ * @post Returns True if password matches, False otherwise.
+ * @pre plain_password is a string, hashed_password is a bcrypt hash.
+ */
+
+// --- get_password_hash (backend/src/core/auth/security.py)
+/**!
+ * @brief Generates a bcrypt hash for a plain password.
+ * @post Returns a secure bcrypt hash string.
+ * @pre password is a string.
+ */
+
+// --- ConfigManager (backend/src/core/config_manager.py)
+/**!
+ * @brief Manages application configuration persistence in DB with one-time migration from legacy JSON.
+ * @invariant Configuration must always be representable by AppConfig and persisted under global record id.
+ * @post Configuration is loaded into memory and logger is configured.
+ * @pre Database schema for AppConfigRecord must be initialized.
+ */
+
+// --- _apply_features_from_env (backend/src/core/config_manager.py)
+/**!
+ * @brief Read FEATURES__* env vars and apply them to a GlobalSettings features config.
+ */
+
+// --- _default_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Build default application configuration fallback.
+ */
+
+// --- _sync_raw_payload_from_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Merge typed AppConfig state into raw payload while preserving unsupported legacy sections.
+ */
+
+// --- _load_from_legacy_file (backend/src/core/config_manager.py)
+/**!
+ * @brief Load legacy JSON configuration for migration fallback path.
+ */
+
+// --- _get_record (backend/src/core/config_manager.py)
+/**!
+ * @brief Resolve global configuration record from DB.
+ */
+
+// --- _load_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Load configuration from DB or perform one-time migration from legacy JSON.
+ */
+
+// --- _sync_environment_records (backend/src/core/config_manager.py)
+/**!
+ * @brief Mirror configured environments into the relational environments table used by FK-backed domain models.
+ */
+
+// --- _delete_stale_environment_records (backend/src/core/config_manager.py)
+/**!
+ * @brief Remove persisted environment records that are no longer in the configured environments.
+ * @post Stale Environment rows are deleted via the session (caller must commit).
+ * @pre _sync_environment_records must already have run so the query returns a current view.
+ */
+
+// --- _save_config_to_db (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist provided AppConfig into the global DB configuration record.
+ */
+
+// --- save (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist current in-memory configuration state.
+ */
+
+// --- get_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Return current in-memory configuration snapshot.
+ */
+
+// --- get_payload (backend/src/core/config_manager.py)
+/**!
+ * @brief Return full persisted payload including sections outside typed AppConfig schema.
+ */
+
+// --- save_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist configuration provided either as typed AppConfig or raw payload dict.
+ */
+
+// --- update_global_settings (backend/src/core/config_manager.py)
+/**!
+ * @brief Replace global settings and persist the resulting configuration.
+ */
+
+// --- validate_path (backend/src/core/config_manager.py)
+/**!
+ * @brief Validate that path exists and is writable, creating it when absent.
+ */
+
+// --- get_environments (backend/src/core/config_manager.py)
+/**!
+ * @brief Return all configured environments.
+ */
+
+// --- has_environments (backend/src/core/config_manager.py)
+/**!
+ * @brief Check whether at least one environment exists in configuration.
+ */
+
+// --- get_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Resolve a configured environment by identifier.
+ */
+
+// --- add_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Upsert environment by id into configuration and persist.
+ */
+
+// --- update_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Update existing environment by id and preserve masked password placeholder behavior.
+ */
+
+// --- delete_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Delete environment by id and persist when deletion occurs.
+ */
+
+// --- ConfigModels (backend/src/core/config_models.py)
+/**!
+ * @brief Defines the data models for application configuration using Pydantic.
+ */
+
+// --- CoreContracts (backend/src/core/config_models.py)
+/**!
+ * @brief Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.
+ */
+
+// --- ConnectionContracts (backend/src/core/config_models.py)
+/**!
+ * @brief Contract for database/environment connection configuration models.
+ */
+
+// --- Schedule (backend/src/core/config_models.py)
+/**!
+ * @brief Represents a backup schedule configuration.
+ */
+
+// --- Environment (backend/src/core/config_models.py)
+/**!
+ * @brief Represents a Superset environment configuration.
+ */
+
+// --- LoggingConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Defines the configuration for the application's logging system.
+ */
+
+// --- CleanReleaseConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Configuration for clean release compliance subsystem.
+ */
+
+// --- FeaturesConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Top-level feature flags that toggle entire project features on/off.
+ */
+
+// --- GlobalSettings (backend/src/core/config_models.py)
+/**!
+ * @brief Represents global application settings.
+ */
+
+// --- AppConfig (backend/src/core/config_models.py)
+/**!
+ * @brief The root configuration model containing all application settings.
+ */
+
+// --- CotLoggerModule (backend/src/core/cot_logger.py)
+/**!
+ * @brief Structured JSON logger implementing the molecular CoT (Chain-of-Thought) logging protocol.
+ */
+
+// --- cot_trace_context (backend/src/core/cot_logger.py)
+/**!
+ * @brief ContextVars for trace ID and span ID propagation across async boundaries.
+ */
+
+// --- cot_logger_instance (backend/src/core/cot_logger.py)
+/**!
+ * @brief Dedicated Python logger for all CoT (molecular) log output.
+ */
+
+// --- seed_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Generate a new UUID4 trace_id, set it in ContextVar, and return it.
+ */
+
+// --- set_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Set an explicit trace_id into the ContextVar (e.g. from an incoming header).
+ */
+
+// --- get_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Get the current trace_id from ContextVar.
+ */
+
+// --- push_span (backend/src/core/cot_logger.py)
+/**!
+ * @brief Set a new span_id in ContextVar and return the previous span_id for later restoration.
+ */
+
+// --- pop_span (backend/src/core/cot_logger.py)
+/**!
+ * @brief Restore a previous span_id into the ContextVar.
+ */
+
+// --- cot_log_function (backend/src/core/cot_logger.py)
+/**!
+ * @brief Core structured logging function that emits a single-line JSON record.
+ */
+
+// --- MarkerLogger (backend/src/core/cot_logger.py)
+/**!
+ * @brief Thin proxy class providing .reason(), .reflect(), .explore() convenience methods.
+ */
+
+// --- MarkerLogger.__init__ (backend/src/core/cot_logger.py)
+/**!
+ * @brief Store the module/component name used as the 'src' field in all log calls.
+ */
+
+// --- MarkerLogger.reason (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log a REASON marker — strict deduction, core logic.
+ */
+
+// --- MarkerLogger.reflect (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log a REFLECT marker — self-check, structural validation.
+ */
+
+// --- MarkerLogger.explore (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log an EXPLORE marker — searching, alternatives, violated assumptions.
+ */
+
+// --- DatabaseModule (backend/src/core/database.py)
+/**!
+ * @brief Configures database connection and session management (PostgreSQL-first).
+ * @invariant A single engine instance is used for the entire application.
+ */
+
+// --- BASE_DIR (backend/src/core/database.py)
+/**!
+ * @brief Base directory for the backend.
+ */
+
+// --- DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the main application database. Read from env; dev fallback only.
+ */
+
+// --- TASKS_DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the tasks execution database.
+ */
+
+// --- AUTH_DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the authentication database.
+ */
+
+// --- engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for mappings database.
+ */
+
+// --- tasks_engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for tasks database.
+ */
+
+// --- auth_engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for authentication database.
+ */
+
+// --- SessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the main mappings database.
+ * @pre engine is initialized.
+ */
+
+// --- TasksSessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the tasks execution database.
+ * @pre tasks_engine is initialized.
+ */
+
+// --- AuthSessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the authentication database.
+ * @pre auth_engine is initialized.
+ */
+
+// --- _ensure_user_dashboard_preferences_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for user_dashboard_preferences table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database where profile table is stored.
+ */
+
+// --- _ensure_user_dashboard_preferences_health_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for user_dashboard_preferences table (health fields).
+ */
+
+// --- _ensure_llm_validation_results_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for llm_validation_results table.
+ */
+
+// --- _ensure_git_server_configs_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for git_server_configs table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database.
+ */
+
+// --- _ensure_auth_users_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for auth users table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to authentication database.
+ */
+
+// --- _ensure_filter_source_enum_values (backend/src/core/database.py)
+/**!
+ * @brief Adds missing FilterSource enum values to the PostgreSQL native filtersource type.
+ * @post New enum values are available without data loss.
+ * @pre bind_engine points to application database with imported_filters table.
+ */
+
+// --- _ensure_dataset_review_session_columns (backend/src/core/database.py)
+/**!
+ * @brief Apply additive schema upgrades for dataset review persistence required by optimistic-lock and recovery metadata semantics.
+ * @post Missing additive columns across legacy dataset review tables are created without removing existing data.
+ * @pre bind_engine points to the application database where dataset review tables are stored.
+ */
+
+// --- _ensure_translation_schedules_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for translation_schedules table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database.
+ */
+
+// --- _ensure_dictionary_entries_columns (backend/src/core/database.py)
+/**!
+ * @brief Additive migration for dictionary_entries origin tracking columns.
+ */
+
+// --- init_db (backend/src/core/database.py)
+/**!
+ * @brief Initializes the database by creating all tables.
+ * @post Database tables created in all databases.
+ * @pre engine, tasks_engine and auth_engine are initialized.
+ */
+
+// --- get_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting a database session.
+ * @post Session is closed after use.
+ * @pre SessionLocal is initialized.
+ */
+
+// --- get_tasks_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting a tasks database session.
+ * @post Session is closed after use.
+ * @pre TasksSessionLocal is initialized.
+ */
+
+// --- get_auth_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting an authentication database session.
+ * @post Session is closed after use.
+ * @pre AuthSessionLocal is initialized.
+ */
+
+// --- EncryptionKeyModule (backend/src/core/encryption_key.py)
+/**!
+ * @brief Resolve and persist the Fernet encryption key required by runtime services.
+ * @invariant Runtime key resolution never falls back to an ephemeral secret.
+ * @post A valid Fernet key is available to runtime services via ENCRYPTION_KEY.
+ * @pre Runtime environment can read process variables and target .env path is writable when key generation is required.
+ */
+
+// --- ensure_encryption_key (backend/src/core/encryption_key.py)
+/**!
+ * @brief Ensure backend runtime has a persistent valid Fernet key.
+ * @post Returns a valid Fernet key and guarantees it is present in process environment.
+ * @pre env_file_path points to a writable backend .env file or ENCRYPTION_KEY exists in process environment.
+ */
+
+// --- LoggerModule (backend/src/core/logger.py)
+/**!
+ * @brief Application logging system with CotJsonFormatter producing molecular CoT JSON output.
+ * @invariant CotJsonFormatter.format() always returns valid single-line JSON string.
+ * @post All log output is single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+ * @pre Python 3.7+ with cot_logger ContextVars available.
+ */
+
+// --- CotJsonFormatter (backend/src/core/logger.py)
+/**!
+ * @brief JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+ */
+
+// --- CotJsonFormatter.format (backend/src/core/logger.py)
+/**!
+ * @brief Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.
+ * @invariant Output is always valid single-line JSON.
+ */
+
+// --- BeliefFormatter (backend/src/core/logger.py)
+/**!
+ * @brief Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.
+ */
+
+// --- LogEntry (backend/src/core/logger.py)
+/**!
+ * @brief A Pydantic model representing a single, structured log entry.
+ */
+
+// --- belief_scope (backend/src/core/logger.py)
+/**!
+ * @brief Context manager for Molecular CoT structured logging. Uses cot_logger.log() for JSON output.
+ * @post Thread-local belief state is updated; REASON/REFLECT/EXPLORE markers emitted via structured JSON logger.
+ * @pre anchor_id must be provided.
+ */
+
+// --- configure_logger (backend/src/core/logger.py)
+/**!
+ * @brief Configures the main logger and the CoT logger with CotJsonFormatter, file handlers, and global flags.
+ * @post Logger levels, handlers, formatters, belief state flag, and task log level are updated.
+ * @pre config is a valid LoggingConfig instance.
+ */
+
+// --- get_task_log_level (backend/src/core/logger.py)
+/**!
+ * @brief Returns the current task log level filter.
+ */
+
+// --- should_log_task_level (backend/src/core/logger.py)
+/**!
+ * @brief Checks if a log level should be recorded based on task_log_level setting.
+ */
+
+// --- Logger (backend/src/core/logger.py)
+/**!
+ * @brief The global application logger instance configured with CotJsonFormatter, console handler, and WebSocketLogHandler.
+ */
+
+// --- believed (backend/src/core/logger.py)
+/**!
+ * @brief A decorator that wraps a function in a belief scope.
+ */
+
+// --- explore (backend/src/core/logger.py)
+/**!
+ * @brief Logs an EXPLORE marker (WARNING level) with structured extra data for CotJsonFormatter.
+ */
+
+// --- reason (backend/src/core/logger.py)
+/**!
+ * @brief Logs a REASON marker (DEBUG level) with structured extra data for CotJsonFormatter.
+ */
+
+// --- reflect (backend/src/core/logger.py)
+/**!
+ * @brief Logs a REFLECT marker (DEBUG level) with structured extra data for CotJsonFormatter.
+ */
+
+// --- test_logger (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Unit tests for logger module
+ */
+
+// --- test_belief_scope_logs_reason_reflect_at_debug (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.
+ * @post Logs are verified to contain REASON and REFLECT markers at DEBUG level.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_error_handling (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs EXPLORE on exception.
+ * @post Logs are verified to contain EXPLORE marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_success_reflect (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs REFLECT on success.
+ * @post Logs are verified to contain REFLECT marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_not_visible_at_info (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope REFLECT logs are NOT visible at INFO level.
+ * @post REASON is visible at INFO (uses info()); REFLECT is not (uses debug()).
+ * @pre belief_scope is available. caplog fixture is used.
+ */
+
+// --- test_task_log_level_default (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that default task log level is INFO.
+ * @post Default level is INFO.
+ * @pre None.
+ */
+
+// --- test_should_log_task_level (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that should_log_task_level correctly filters log levels.
+ * @post Filtering works correctly for all level combinations.
+ * @pre None.
+ */
+
+// --- test_configure_logger_task_log_level (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that configure_logger updates task_log_level.
+ * @post task_log_level is updated correctly.
+ * @pre LoggingConfig is available.
+ */
+
+// --- test_enable_belief_state_flag (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that enable_belief_state flag controls belief_scope logging.
+ * @post belief_scope explicit REASON logs are controlled by the flag; REFLECT always logged.
+ * @pre LoggingConfig is available. caplog fixture is used.
+ */
+
+// --- test_belief_scope_missing_anchor (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test @PRE condition: anchor_id must be provided
+ */
+
+// --- test_configure_logger_post_conditions (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test @POST condition: Logger level, handlers, belief state flag, and task log level are updated.
+ */
+
+// --- IdMappingServiceModule (backend/src/core/mapping_service.py)
+/**!
+ * @brief Service for tracking and synchronizing Superset Resource IDs (UUID <-> Integer ID)
+ * @invariant sync_environment must handle remote API failures gracefully.
+ * @post Mapping synchronization and lookup APIs are available for environment-scoped UUID-to-integer resolution.
+ * @pre Database session is valid and Superset client factory returns authenticated clients for requested environments.
+ */
+
+// --- IdMappingService (backend/src/core/mapping_service.py)
+/**!
+ * @brief Service handling the cataloging and retrieval of remote Superset Integer IDs.
+ * @invariant self.db remains the authoritative session for all mapping operations.
+ * @post Service instance provides scheduler control and environment-scoped mapping synchronization APIs.
+ * @pre db_session is an active SQLAlchemy Session bound to mapping tables.
+ */
+
+// --- start_scheduler (backend/src/core/mapping_service.py)
+/**!
+ * @brief Starts the background scheduler with a given cron string.
+ * @param superset_client_factory - Function to get a client for an environment.
+ */
+
+// --- sync_environment (backend/src/core/mapping_service.py)
+/**!
+ * @brief Fully synchronizes mapping for a specific environment.
+ * @param superset_client - Instance capable of hitting the Superset API.
+ * @post ResourceMapping records for the environment are created or updated.
+ * @pre environment_id exists in the database.
+ */
+
+// --- get_remote_id (backend/src/core/mapping_service.py)
+/**!
+ * @brief Retrieves the remote integer ID for a given universal UUID.
+ * @param uuid (str)
+ * @return Optional[int]
+ */
+
+// --- get_remote_ids_batch (backend/src/core/mapping_service.py)
+/**!
+ * @brief Retrieves remote integer IDs for a list of universal UUIDs efficiently.
+ * @param uuids (List[str])
+ * @return Dict[str, int] - Mapping of UUID -> Integer ID
+ */
+
+// --- middleware_package (backend/src/core/middleware/__init__.py)
+/**!
+ * @brief FastAPI/Starlette middleware package for request-level context and tracing.
+ */
+
+// --- TraceContextMiddlewareModule (backend/src/core/middleware/trace.py)
+/**!
+ * @brief FastAPI/Starlette middleware that seeds a trace_id for every incoming HTTP request.
+ */
+
+// --- TraceContextMiddleware (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Starlette BaseHTTPMiddleware that seeds a trace_id per request.
+ */
+
+// --- TraceContextMiddleware.__init__ (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Standard BaseHTTPMiddleware initialiser.
+ */
+
+// --- TraceContextMiddleware.dispatch (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Dispatch handler that seeds trace_id before passing to the next middleware.
+ */
+
+// --- MigrationPackage (backend/src/core/migration/__init__.py)
+/**!
+ */
+
+// --- MigrationArchiveParserModule (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Parse Superset export ZIP archives into normalized object catalogs for diffing.
+ * @invariant Parsing is read-only and never mutates archive files.
+ * @post Parsed migration archive returned
+ * @pre Archive file path is valid and readable
+ */
+
+// --- MigrationArchiveParser (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Extract normalized dashboards/charts/datasets metadata from ZIP archives.
+ */
+
+// --- extract_objects_from_zip (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Extract object catalogs from Superset archive.
+ * @post Returns object lists grouped by resource type.
+ * @pre zip_path points to a valid readable ZIP.
+ * @return Dict[str, List[Dict[str, Any]]]
+ */
+
+// --- _collect_yaml_objects (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Read and normalize YAML manifests for one object type.
+ * @post Returns only valid normalized objects.
+ * @pre object_type is one of dashboards/charts/datasets.
+ */
+
+// --- _normalize_object_payload (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Convert raw YAML payload to stable diff signature shape.
+ * @post Returns normalized descriptor with `uuid`, `title`, and `signature`.
+ * @pre payload is parsed YAML mapping.
+ */
+
+// --- MigrationDryRunOrchestratorModule (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Compute pre-flight migration diff and risk scoring without apply.
+ * @invariant Dry run is informative only and must not mutate target environment.
+ * @post Dry-run diff returned without mutation
+ * @pre Source and target environments configured
+ */
+
+// --- MigrationDryRunService (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build deterministic diff/risk payload for migration pre-flight.
+ */
+
+// --- run (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Execute full dry-run computation for selected dashboards.
+ * @post Returns JSON-serializable pre-flight payload with summary, diff and risk.
+ * @pre source/target clients are authenticated and selection validated by caller.
+ */
+
+// --- _load_db_mapping (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Resolve UUID mapping for optional DB config replacement.
+ */
+
+// --- _accumulate_objects (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Merge extracted resources by UUID to avoid duplicates.
+ */
+
+// --- _index_by_uuid (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build UUID-index map for normalized resources.
+ */
+
+// --- _build_object_diff (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Compute create/update/delete buckets by UUID+signature.
+ */
+
+// --- _build_target_signatures (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Pull target metadata and normalize it into comparable signatures.
+ */
+
+// --- _build_risks (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build risk items for missing datasource, broken refs, overwrite, owner mismatch.
+ */
+
+// --- RiskAssessorModule (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Compute deterministic migration risk items and aggregate score for dry-run reporting.
+ * @invariant Risk scoring must remain bounded to [0,100] and preserve severity-to-weight mapping.
+ * @post Risk scoring output preserves item list and provides bounded score with derived level.
+ * @pre Risk assessor functions receive normalized migration object collections from dry-run orchestration.
+ */
+
+// --- index_by_uuid (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Build UUID-index from normalized objects.
+ * @post Returns mapping keyed by string uuid; only truthy uuid values are included.
+ * @pre Input list items are dict-like payloads potentially containing "uuid".
+ */
+
+// --- extract_owner_identifiers (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Normalize owner payloads for stable comparison.
+ * @post Returns sorted unique owner identifiers as strings.
+ * @pre Owners may be list payload, scalar values, or None.
+ */
+
+// --- build_risks (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Build risk list from computed diffs and target catalog state.
+ * @post Returns list of deterministic risk items derived from overwrite, missing datasource, reference, and owner mismatch checks.
+ * @pre target_client is authenticated/usable for database list retrieval.
+ */
+
+// --- score_risks (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Aggregate risk list into score and level.
+ * @post Returns dict with score in [0,100], derived level, and original items.
+ * @pre risk_items contains optional severity fields expected in {high,medium,low} or defaults to low weight.
+ */
+
+// --- MigrationEngineModule (backend/src/core/migration_engine.py)
+/**!
+ * @brief Transforms Superset export ZIP archives while preserving archive integrity and patching mapped identifiers.
+ * @invariant ZIP structure and non-targeted metadata must remain valid after transformation.
+ * @post Migration engine contracts preserve ZIP integrity while exposing transformation entrypoints for import pipelines.
+ * @pre Input archives are readable Superset exports and optional mapping collaborators expose remote id lookup APIs.
+ */
+
+// --- MigrationEngine (backend/src/core/migration_engine.py)
+/**!
+ * @brief Engine for transforming Superset export ZIPs.
+ */
+
+// --- transform_zip (backend/src/core/migration_engine.py)
+/**!
+ * @brief Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.
+ * @param fix_cross_filters (bool) - Whether to patch dashboard json_metadata.
+ * @post Returns True only when extraction, transformation, and packaging complete without exception.
+ * @pre zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.
+ * @return bool - True if successful.
+ */
+
+// --- _transform_yaml (backend/src/core/migration_engine.py)
+/**!
+ * @brief Replaces database_uuid in a single YAML file.
+ * @param db_mapping (Dict[str, str]) - UUID mapping dictionary.
+ * @post database_uuid is replaced in-place only when source UUID is present in db_mapping.
+ * @pre file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.
+ */
+
+// --- _extract_chart_uuids_from_archive (backend/src/core/migration_engine.py)
+/**!
+ * @brief Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.
+ * @param temp_dir (Path) - Root dir of unpacked archive.
+ * @post Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.
+ * @pre temp_dir exists and points to extracted archive root with optional chart YAML resources.
+ * @return Dict[int, str] - Mapping of source Integer ID to UUID.
+ */
+
+// --- _patch_dashboard_metadata (backend/src/core/migration_engine.py)
+/**!
+ * @brief Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.
+ * @param source_map (Dict[int, str])
+ * @post json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.
+ * @pre file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.
+ */
+
+// --- PluginBase (backend/src/core/plugin_base.py)
+/**!
+ * @brief PluginLoader scans for subclasses of PluginBase.
+ * @invariant All plugins MUST inherit from this class.
+ */
+
+// --- id (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the unique identifier for the plugin.
+ * @post Returns string ID.
+ * @pre Plugin instance exists.
+ * @return str - Plugin ID.
+ */
+
+// --- name (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the human-readable name of the plugin.
+ * @post Returns string name.
+ * @pre Plugin instance exists.
+ * @return str - Plugin name.
+ */
+
+// --- description (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns a brief description of the plugin.
+ * @post Returns string description.
+ * @pre Plugin instance exists.
+ * @return str - Plugin description.
+ */
+
+// --- version (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the version of the plugin.
+ * @post Returns string version.
+ * @pre Plugin instance exists.
+ * @return str - Plugin version.
+ */
+
+// --- required_permission (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the required permission string to execute this plugin.
+ * @post Returns string permission.
+ * @pre Plugin instance exists.
+ * @return str - Required permission (e.g., "plugin:backup:execute").
+ */
+
+// --- ui_route (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the frontend route for the plugin's UI, if applicable.
+ * @post Returns string route or None.
+ * @pre Plugin instance exists.
+ * @return Optional[str] - Frontend route.
+ */
+
+// --- get_schema (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the JSON schema for the plugin's input parameters.
+ * @post Returns dict schema.
+ * @pre Plugin instance exists.
+ * @return Dict[str, Any] - JSON schema.
+ */
+
+// --- execute (backend/src/core/plugin_base.py)
+/**!
+ * @brief Executes the plugin's core logic.
+ * @param params (Dict[str, Any]) - Validated input parameters.
+ * @post Plugin execution is completed.
+ * @pre params must be a dictionary.
+ */
+
+// --- PluginConfig (backend/src/core/plugin_base.py)
+/**!
+ * @brief Validated PluginConfig exposed to API layer.
+ */
+
+// --- PluginLoader (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Discovers and manages available PluginBase implementations.
+ */
+
+// --- _load_plugins (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Scans the plugin directory and loads all valid plugins.
+ * @post _load_module is called for each .py file.
+ * @pre plugin_dir exists or can be created.
+ */
+
+// --- _load_module (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Loads a single Python module and discovers PluginBase implementations.
+ * @param file_path (str) - The path to the module file.
+ * @post Plugin classes are instantiated and registered.
+ * @pre module_name and file_path are valid.
+ */
+
+// --- _register_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Registers a PluginBase instance and its configuration.
+ * @param plugin_instance (PluginBase) - The plugin instance to register.
+ * @post Plugin is added to _plugins and _plugin_configs.
+ * @pre plugin_instance is a valid implementation of PluginBase.
+ */
+
+// --- get_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Retrieves a loaded plugin instance by its ID.
+ * @param plugin_id (str) - The unique identifier of the plugin.
+ * @post Returns plugin instance or None.
+ * @pre plugin_id is a string.
+ * @return Optional[PluginBase] - The plugin instance if found, otherwise None.
+ */
+
+// --- get_all_plugin_configs (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Returns a list of all registered plugin configurations.
+ * @post Returns list of all PluginConfig objects.
+ * @pre None.
+ * @return List[PluginConfig] - A list of plugin configurations.
+ */
+
+// --- has_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Checks if a plugin with the given ID is registered.
+ * @param plugin_id (str) - The unique identifier of the plugin.
+ * @post Returns True if plugin exists.
+ * @pre plugin_id is a string.
+ * @return bool - True if the plugin is registered, False otherwise.
+ */
+
+// --- SchedulerModule (backend/src/core/scheduler.py)
+/**!
+ * @brief Manages scheduled tasks using APScheduler.
+ */
+
+// --- SchedulerService (backend/src/core/scheduler.py)
+/**!
+ * @brief Provides a service to manage scheduled backup tasks.
+ */
+
+// --- start (backend/src/core/scheduler.py)
+/**!
+ * @brief Starts the background scheduler and loads initial schedules.
+ * @post Scheduler is running and schedules are loaded.
+ * @pre Scheduler should be initialized.
+ */
+
+// --- stop (backend/src/core/scheduler.py)
+/**!
+ * @brief Stops the background scheduler.
+ * @post Scheduler is shut down.
+ * @pre Scheduler should be running.
+ */
+
+// --- load_schedules (backend/src/core/scheduler.py)
+/**!
+ * @brief Load backup and active translation schedules from config and DB, re-registering all jobs.
+ * @post All enabled backup jobs and active translation schedules are re-registered in APScheduler.
+ * @pre config_manager must have valid configuration; database is accessible.
+ */
+
+// --- add_backup_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Adds a scheduled backup job for an environment.
+ * @param cron_expression (str) - The cron expression for the schedule.
+ * @post A new job is added to the scheduler or replaced if it already exists.
+ * @pre env_id and cron_expression must be valid strings.
+ */
+
+// --- add_translation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Register a translation schedule with APScheduler.
+ * @post A new APScheduler job is registered or replaced if it already exists.
+ * @pre schedule_id, job_id, and cron_expression are valid strings.
+ */
+
+// --- remove_translation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Remove a translation schedule from APScheduler.
+ * @post The APScheduler job is removed if it exists; silently ignored otherwise.
+ * @pre schedule_id is a valid string.
+ */
+
+// --- _trigger_backup (backend/src/core/scheduler.py)
+/**!
+ * @brief Triggered by the scheduler to start a backup task.
+ * @param env_id (str) - The ID of the environment.
+ * @post A new backup task is created in the task manager if not already running.
+ * @pre env_id must be a valid environment ID.
+ */
+
+// --- add_validation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Register a validation policy schedule with APScheduler.
+ * @post A new APScheduler job is registered or replaced if it already exists.
+ * @pre policy_id and cron_expression are valid strings.
+ */
+
+// --- remove_validation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Remove a validation policy schedule from APScheduler.
+ * @post The APScheduler job is removed if it exists; silently ignored otherwise.
+ * @pre policy_id is a valid string.
+ */
+
+// --- reload_validation_policy (backend/src/core/scheduler.py)
+/**!
+ * @brief Reload a single validation policy schedule — calls remove then add.
+ * @post Old job is removed; new job is registered if policy is active and has schedule_days.
+ * @pre policy_id is a valid ValidationPolicy id with schedule data in DB.
+ */
+
+// --- _trigger_validation (backend/src/core/scheduler.py)
+/**!
+ * @brief APScheduler job handler — triggers validation runs for a policy.
+ * @post A validation task is spawned via TaskManager for each dashboard in the policy.
+ * @pre policy_id is a valid ValidationPolicy id with dashboard_ids.
+ */
+
+// --- ThrottledSchedulerConfigurator (backend/src/core/scheduler.py)
+/**!
+ * @brief Distributes validation tasks evenly within an execution window.
+ * @invariant Returned schedule size always matches number of dashboard IDs.
+ * @post Produces deterministic per-dashboard run timestamps within the configured window.
+ * @pre Validation policies provide a finite dashboard list and a valid execution window.
+ */
+
+// --- calculate_schedule (backend/src/core/scheduler.py)
+/**!
+ * @brief Calculates execution times for N tasks within a window.
+ * @invariant Tasks are distributed with near-even spacing.
+ * @post Returns List[EXT:Python:datetime] of scheduled times.
+ * @pre window_start, window_end (time), dashboard_ids (List), current_date (date).
+ */
+
+// --- SupersetClientModule (backend/src/core/superset_client/__init__.py)
+/**!
+ * @brief Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
+ * @invariant All network operations must use the internal APIClient instance.
+ */
+
+// --- SupersetClient (backend/src/core/superset_client/__init__.py)
+/**!
+ * @brief Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
+ */
+
+// --- SupersetClientBase (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Base class for SupersetClient providing initialization, authentication, pagination, and import/export helpers.
+ */
+
+// --- SupersetClientInit (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
+ */
+
+// --- SupersetClientAuthenticate (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Authenticates the client using the configured credentials.
+ */
+
+// --- SupersetClientHeaders (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
+ */
+
+// --- SupersetClientValidateQueryParams (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Ensures query parameters have default page and page_size.
+ */
+
+// --- SupersetClientFetchTotalObjectCount (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Fetches the total number of items for a given endpoint.
+ */
+
+// --- SupersetClientFetchAllPages (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Iterates through all pages to collect all data items.
+ */
+
+// --- SupersetClientDoImport (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Performs the actual multipart upload for import.
+ */
+
+// --- SupersetClientValidateExportResponse (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Validates that the export response is a non-empty ZIP archive.
+ */
+
+// --- SupersetClientResolveExportFilename (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Determines the filename for an exported dashboard.
+ */
+
+// --- SupersetClientValidateImportFile (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Validates that the file to be imported is a valid ZIP with metadata.yaml.
+ */
+
+// --- SupersetClientResolveTargetIdForDelete (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Resolves a dashboard ID from either an ID or a slug.
+ */
+
+// --- SupersetClientGetAllResources (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Fetches all resources of a given type with id, uuid, and name columns.
+ */
+
+// --- SupersetChartsMixin (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Chart domain mixin for SupersetClient — list, get, extract IDs from layout.
+ */
+
+// --- SupersetClientGetChart (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Fetches a single chart by ID.
+ */
+
+// --- SupersetClientGetCharts (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Fetches all charts with pagination support.
+ */
+
+// --- SupersetClientExtractChartIdsFromLayout (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Traverses dashboard layout metadata and extracts chart IDs from common keys.
+ */
+
+// --- SupersetDashboardsCrudMixin (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Dashboard CRUD mixin for SupersetClient — detail, export, import, delete.
+ */
+
+// --- SupersetClientGetDashboardDetail (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Fetches detailed dashboard information including related charts and datasets.
+ */
+
+// --- extract_dataset_id_from_form_data (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ */
+
+// --- SupersetClientExportDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Экспортирует дашборд в виде ZIP-архива.
+ */
+
+// --- SupersetClientImportDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Импортирует дашборд из ZIP-файла.
+ */
+
+// --- SupersetClientDeleteDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Удаляет дашборд по его ID или slug.
+ */
+
+// --- SupersetDashboardsFiltersMixin (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Dashboard native filter extraction mixin for SupersetClient.
+ */
+
+// --- SupersetClientGetDashboard (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches a single dashboard by ID or slug.
+ */
+
+// --- SupersetClientGetDashboardPermalinkState (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches stored dashboard permalink state by permalink key.
+ */
+
+// --- SupersetClientGetNativeFilterState (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches stored native filter state by filter state key.
+ */
+
+// --- SupersetClientExtractNativeFiltersFromPermalink (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Extract native filters dataMask from a permalink key.
+ */
+
+// --- SupersetClientExtractNativeFiltersFromKey (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Extract native filters from a native_filters_key URL parameter.
+ */
+
+// --- SupersetClientParseDashboardUrlForFilters (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state if present.
+ */
+
+// --- SupersetDashboardsListMixin (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Dashboard listing mixin for SupersetClient — paginated list, summary projection.
+ */
+
+// --- SupersetClientGetDashboards (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Получает полный список дашбордов, автоматически обрабатывая пагинацию.
+ */
+
+// --- SupersetClientGetDashboardsPage (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches a single dashboards page from Superset without iterating all pages.
+ */
+
+// --- SupersetClientGetDashboardsSummary (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches dashboard metadata optimized for the grid.
+ */
+
+// --- SupersetClientGetDashboardsSummaryPage (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches one page of dashboard metadata optimized for the grid.
+ */
+
+// --- SupersetDashboardsWriteMixin (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Dashboard write mixin for SupersetClient — markdown chart CRUD and layout manipulation for maintenance banners.
+ * @invariant All network operations use self.network.request()
+ */
+
+// --- create_markdown_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Create a markdown chart and return the new chart ID.
+ * @post Returns chart_id (int). Chart is NOT yet placed in dashboard layout.
+ * @pre dashboard_id exists in Superset. markdown_text not empty.
+ */
+
+// --- update_markdown_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Update the markdown text of an existing markdown chart.
+ * @post Chart markdown content updated.
+ * @pre chart_id exists and is a markdown chart.
+ */
+
+// --- update_dashboard_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Insert a native MARKDOWN element at (0,0) with full width (12 cols),
+ */
+
+// --- remove_chart_from_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Remove banner markdown element from dashboard layout without deleting the chart.
+ * @post MARKDOWN element removed from position_json; items shifted up.
+ * @pre dashboard_id exists. chart_id exists in layout as MARKDOWN-banner-{chart_id}.
+ */
+
+// --- delete_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Delete a chart from Superset by ID.
+ * @post Chart permanently deleted from Superset.
+ * @pre chart_id exists.
+ */
+
+// --- update_banner_on_dashboard (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Update the content of a native MARKDOWN banner element on a dashboard.
+ * @post MARKDOWN element content updated on dashboard.
+ * @pre dashboard_id exists. chart_id used for key lookup.
+ */
+
+// --- get_dashboard_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Fetch the position_json layout of a dashboard.
+ * @post Returns the dashboard layout dict.
+ * @pre dashboard_id exists.
+ */
+
+// --- _resolve_markdown_datasource (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Find a valid datasource_id for markdown chart creation.
+ * @post Returns an integer datasource_id.
+ * @pre dashboard_id exists.
+ */
+
+// --- SupersetDatabasesMixin (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Database domain mixin for SupersetClient — list, get, summary, by_uuid.
+ */
+
+// --- SupersetClientGetDatabases (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Получает полный список баз данных.
+ */
+
+// --- SupersetClientGetDatabase (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Получает информацию о конкретной базе данных по её ID.
+ */
+
+// --- SupersetClientGetDatabasesSummary (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Fetch a summary of databases including uuid, name, and engine.
+ */
+
+// --- SupersetClientGetDatabaseByUuid (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Find a database by its UUID.
+ */
+
+// --- SupersetDatasetsMixin (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Dataset domain mixin for SupersetClient — list, get, detail, update.
+ */
+
+// --- SupersetClientGetDatasets (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Получает полный список датасетов, автоматически обрабатывая пагинацию.
+ */
+
+// --- SupersetClientGetDatasetsSummary (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetches dataset metadata optimized for the Dataset Hub grid.
+ */
+
+// --- SupersetClientGetDatasetLinkedDashboardCount (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetch the number of dashboards linked to a dataset via related_objects endpoint.
+ */
+
+// --- SupersetClientGetDatasetDetail (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetches detailed dataset information including columns and linked dashboards.
+ */
+
+// --- SupersetClientGetDataset (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Получает информацию о конкретном датасете по его ID.
+ */
+
+// --- SupersetClientUpdateDataset (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Обновляет данные датасета по его ID.
+ */
+
+// --- SupersetDatasetsPreviewMixin (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Dataset preview compilation mixin for SupersetClient — build query context, compile SQL.
+ */
+
+// --- SupersetClientCompileDatasetPreview (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Compile dataset preview SQL through the strongest supported Superset preview endpoint family and return normalized SQL output.
+ */
+
+// --- SupersetClientBuildDatasetPreviewLegacyFormData (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Build browser-style legacy form_data payload for Superset preview endpoints inferred from observed deployment traffic.
+ */
+
+// --- SupersetClientBuildDatasetPreviewQueryContext (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Build a reduced-scope chart-data query context for deterministic dataset preview compilation.
+ */
+
+// --- SupersetDatasetsPreviewFiltersMixin (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Filter normalization and SQL extraction helpers for dataset preview compilation.
+ */
+
+// --- SupersetClientNormalizeEffectiveFiltersForQueryContext (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Convert execution mappings into Superset chart-data filter objects.
+ */
+
+// --- SupersetClientExtractCompiledSqlFromPreviewResponse (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Normalize compiled SQL from either chart-data or legacy form_data preview responses.
+ */
+
+// --- LayoutUtils (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Utility functions for manipulating Superset dashboard position_json layout.
+ */
+
+// --- parse_position_json (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Parse position_json from a dashboard API response (may be string or dict).
+ * @post Returns a dict.
+ * @pre raw_position is a string, dict, or None.
+ */
+
+// --- _estimate_markdown_height (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Estimate grid height for a MARKDOWN element based on HTML content.
+ */
+
+// --- _generate_banner_id (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Generate a deterministic row and markdown key for a banner chart.
+ */
+
+// --- insert_banner_markdown_at_top (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Insert a ROW + native MARKDOWN pair at the top of the dashboard grid.
+ */
+
+// --- update_banner_markdown_content (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Update the code content and adaptive height of an existing banner markdown element.
+ * @post position_json is mutated; markdown content and height updated.
+ * @pre position_json has markdown_key. content is the new HTML/markdown string.
+ */
+
+// --- remove_banner_from_position (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Remove the banner ROW + MARKDOWN pair from the position dict and GRID children.
+ */
+
+// --- SupersetUserProjection (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief User/owner payload normalization helpers for Superset client responses.
+ */
+
+// --- SupersetUserProjectionMixin (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Mixin providing user/owner payload normalization for Superset API responses.
+ */
+
+// --- SupersetClientExtractOwnerLabels (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Normalize dashboard owners payload to stable display labels.
+ */
+
+// --- SupersetClientExtractUserDisplay (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Normalize user payload to a stable display name.
+ */
+
+// --- SupersetClientSanitizeUserText (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Convert scalar value to non-empty user-facing text.
+ */
+
+// --- SupersetProfileLookup (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Provides environment-scoped Superset account lookup adapter with stable normalized output.
+ * @invariant Adapter never leaks raw upstream payload shape to API consumers.
+ */
+
+// --- SupersetAccountLookupAdapter (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Lookup Superset users and normalize candidates for profile binding.
+ */
+
+// --- __init__ (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Initializes lookup adapter with authenticated API client and environment context.
+ * @post Adapter is ready to perform users lookup requests.
+ * @pre network_client supports request(method, endpoint, params=...).
+ */
+
+// --- get_users_page (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Fetch one users page from Superset with passthrough search/sort parameters.
+ * @post Returns deterministic payload with normalized items and total count.
+ * @pre page_index >= 0 and page_size >= 1.
+ * @return Dict[str, Any]
+ */
+
+// --- _normalize_lookup_payload (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Convert Superset users response variants into stable candidates payload.
+ * @post Output contains canonical keys: status, environment_id, page_index, page_size, total, items.
+ * @pre response can be dict/list in any supported upstream shape.
+ * @return Dict[str, Any]
+ */
+
+// --- normalize_user_payload (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Project raw Superset user object to canonical candidate shape.
+ * @post Returns normalized candidate keys (environment_id, username, display_name, email, is_active).
+ * @pre raw_user may have heterogenous key names between Superset versions.
+ * @return Dict[str, Any]
+ */
+
+// --- TaskManagerPackage (backend/src/core/task_manager/__init__.py)
+/**!
+ */
+
+// --- TestContext (backend/src/core/task_manager/__tests__/test_context.py)
+/**!
+ * @brief Verify TaskContext preserves optional background task scheduler across sub-context creation.
+ */
+
+// --- test_task_context_preserves_background_tasks_across_sub_context (backend/src/core/task_manager/__tests__/test_context.py)
+/**!
+ * @brief Plugins must be able to access background_tasks from both root and sub-context loggers.
+ * @post background_tasks remains available on root and derived sub-contexts.
+ * @pre TaskContext is initialized with a BackgroundTasks-like object.
+ */
+
+// --- __tests__/test_task_logger (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Contract testing for TaskLogger
+ */
+
+// --- test_task_logger_initialization (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger initializes with correct task_id and state.
+ */
+
+// --- test_log_methods_delegation (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger delegates log method calls to the underlying persistence service.
+ */
+
+// --- test_with_source (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger.with_source returns a new logger with the correct source attribution.
+ */
+
+// --- test_missing_task_id (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger raises or handles missing task_id gracefully.
+ */
+
+// --- test_invalid_add_log_fn (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger raises ValueError for invalid add_log_fn parameter.
+ */
+
+// --- test_progress_log (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger correctly logs progress updates with percentage and message.
+ */
+
+// --- TaskCleanupModule (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Implements task cleanup and retention policies, including associated logs.
+ */
+
+// --- TaskCleanupService (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Provides methods to clean up old task records and their associated logs.
+ */
+
+// --- run_cleanup (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Deletes tasks older than the configured retention period and their logs.
+ * @post Old tasks and their logs are deleted from persistence.
+ * @pre Config manager has valid settings.
+ */
+
+// --- delete_task_with_logs (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Delete a single task and all its associated logs.
+ * @param task_id (str) - The task ID to delete.
+ * @post Task and all its logs are deleted.
+ * @pre task_id is a valid task ID.
+ */
+
+// --- TaskContextModule (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Provides execution context passed to plugins during task execution.
+ * @invariant Each TaskContext is bound to a single task execution.
+ * @post Plugins receive context instances with stable logger and parameter accessors.
+ * @pre Task execution pipeline provides valid task identifiers, logging callbacks, and parameter dictionaries.
+ */
+
+// --- TaskContext (backend/src/core/task_manager/context.py)
+/**!
+ * @brief A container passed to plugin.execute() providing the logger and other task-specific utilities.
+ * @invariant logger is always a valid TaskLogger instance.
+ * @post Instance exposes immutable task identity with logger, params, and optional background task access.
+ * @pre Constructor receives non-empty task_id, callable add_log_fn, and params mapping.
+ */
+
+// --- task_id (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the task ID.
+ * @post Returns the task ID string.
+ * @pre TaskContext must be initialized.
+ * @return str - The task ID.
+ */
+
+// --- logger (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the TaskLogger instance for this context.
+ * @post Returns the TaskLogger instance.
+ * @pre TaskContext must be initialized.
+ * @return TaskLogger - The logger instance.
+ */
+
+// --- params (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the task parameters.
+ * @post Returns the parameters dictionary.
+ * @pre TaskContext must be initialized.
+ * @return Dict[str, Any] - The task parameters.
+ */
+
+// --- background_tasks (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Expose optional background task scheduler for plugins that dispatch deferred side effects.
+ * @post Returns BackgroundTasks-like object or None.
+ * @pre TaskContext must be initialized.
+ */
+
+// --- get_param (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get a specific parameter value with optional default.
+ * @param default (Any) - Default value if key not found.
+ * @post Returns parameter value or default.
+ * @pre TaskContext must be initialized.
+ * @return Any - Parameter value or default.
+ */
+
+// --- create_sub_context (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Create a sub-context with a different default source.
+ * @param source (str) - New default source for logging.
+ * @post Returns new TaskContext with different logger source.
+ * @pre source is a non-empty string.
+ * @return TaskContext - New context with different source.
+ */
+
+// --- EventBusModule (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Task-scoped log buffering, persistence flushes, and subscriber fan-out for real-time
+ */
+
+// --- EventBus (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Coordinates task-scoped log buffering, persistence flushes, and subscriber fan-out
+ */
+
+// --- flush_task_logs (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Flush logs for a specific task immediately.
+ * @post Task's buffered logs are written to database.
+ * @pre task_id exists.
+ */
+
+// --- add_log (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Adds a log entry to a task buffer and notifies subscribers.
+ * @post Log added to buffer and pushed to queues (if level meets task_log_level filter).
+ * @pre Task exists.
+ */
+
+// --- TaskGraphModule (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief In-memory task registry with persistence-backed hydration, pagination, and
+ */
+
+// --- TaskGraph (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief In-memory task dependency graph spanning task registry nodes, pause futures,
+ */
+
+// --- add_task (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Register a task in the in-memory registry.
+ */
+
+// --- remove_tasks (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Remove tasks from registry and persistence, cancel futures for waiting tasks.
+ */
+
+// --- create_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Create and store a future for a paused task.
+ */
+
+// --- resolve_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Resolve a paused task's future and remove it from the map.
+ */
+
+// --- remove_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Remove a future without resolving it.
+ */
+
+// --- JobLifecycleModule (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Task creation, execution, pause/resume, and completion transitions for plugin-backed
+ */
+
+// --- JobLifecycle (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Encodes task creation, execution, pause/resume, and completion transitions for
+ */
+
+// --- _broadcast_dataset_updated (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Broadcast dataset.updated event to all subscribers for a given environment.
+ */
+
+// --- TaskManagerModule (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Thin facade composing TaskGraph (registry), EventBus (log/pub-sub), and JobLifecycle
+ */
+
+// --- TaskManager (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Facade composing TaskGraph, EventBus, and JobLifecycle into a single interface.
+ * @post In-memory task graph, lifecycle scheduler, and log event bus stay consistent with
+ * @pre Plugin loader resolves plugin ids and persistence services are available.
+ */
+
+// --- _make_add_log_callback (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Create a closure for adding logs that looks up the task and delegates to EventBus.
+ */
+
+// --- _flusher_loop (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus._flusher_loop.
+ */
+
+// --- _flush_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus._flush_logs.
+ */
+
+// --- _flush_task_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus.flush_task_logs.
+ */
+
+// --- get_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves a task by its ID.
+ */
+
+// --- get_all_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves all registered tasks.
+ */
+
+// --- get_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves tasks with pagination and optional status filter.
+ */
+
+// --- load_persisted_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Load persisted tasks using persistence service.
+ */
+
+// --- clear_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Clears tasks based on status filter (also deletes associated logs).
+ */
+
+// --- get_task_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves logs for a specific task (from memory or persistence).
+ */
+
+// --- get_task_log_stats (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Get statistics about logs for a task.
+ */
+
+// --- get_task_log_sources (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Get unique sources for a task's logs.
+ */
+
+// --- subscribe_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Subscribes to real-time logs for a task.
+ */
+
+// --- unsubscribe_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Unsubscribes from real-time logs for a task.
+ */
+
+// --- create_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Creates and queues a new task for execution.
+ */
+
+// --- _run_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Internal method to execute a task with TaskContext support (delegates to lifecycle).
+ */
+
+// --- resolve_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Resumes a task that is awaiting mapping.
+ */
+
+// --- wait_for_resolution (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Pauses execution and waits for a resolution signal.
+ */
+
+// --- wait_for_input (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Pauses execution and waits for user input.
+ */
+
+// --- await_input (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Transition a task to AWAITING_INPUT state with input request.
+ */
+
+// --- resume_task_with_password (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Resume a task that is awaiting input with provided passwords.
+ */
+
+// --- subscribe_dataset_events (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Subscribe to dataset.updated events for an environment.
+ */
+
+// --- unsubscribe_dataset_events (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Unsubscribe from dataset.updated events.
+ */
+
+// --- TaskManagerModels (backend/src/core/task_manager/models.py)
+/**!
+ * @brief Defines the data models and enumerations used by the Task Manager.
+ * @invariant Must use Pydantic for data validation.
+ * @post Task models exported with immutable IDs
+ * @pre Task manager initialized
+ */
+
+// --- TaskStatus (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- LogLevel (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- TaskLog (backend/src/core/task_manager/models.py)
+/**!
+ * @brief A Pydantic model representing a persisted log entry from the database.
+ */
+
+// --- LogFilter (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- LogStats (backend/src/core/task_manager/models.py)
+/**!
+ * @brief Statistics about log entries for a task.
+ */
+
+// --- Task (backend/src/core/task_manager/models.py)
+/**!
+ * @brief A Pydantic model representing a single execution instance of a plugin, including its status, parameters, and logs.
+ */
+
+// --- TaskPersistenceModule (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Handles the persistence of tasks using SQLAlchemy and the tasks.db database.
+ * @invariant Database schema must match the TaskRecord model structure.
+ * @post Provides reliable storage and retrieval for task metadata and logs.
+ * @pre Tasks database must be initialized with TaskRecord and TaskLogRecord schemas.
+ */
+
+// --- TaskPersistenceService (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Provides methods to save, load, and delete task records in tasks.db using SQLAlchemy models.
+ * @invariant Persistence must handle potentially missing task fields natively.
+ * @post Persist operations leave matching TaskRecord rows committed or rolled back without leaking sessions, load operations return reconstructed Task objects from stored TaskRecord rows, and delete operations remove only the addressed task rows.
+ * @pre TasksSessionLocal must provide an active SQLAlchemy session, Task inputs must expose id/plugin_id/status/params/result/logs fields, and TaskRecord plus Environment schemas must be available.
+ */
+
+// --- _json_load_if_needed (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Safely load JSON strings from DB if necessary
+ * @post Returns parsed JSON object, list, string, or primitive
+ * @pre value is an arbitrary database value
+ */
+
+// --- _parse_datetime (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Safely parse a datetime string from the database
+ * @post Returns datetime object or None
+ * @pre value is an ISO string or datetime object
+ */
+
+// --- _resolve_environment_id (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Resolve environment id into existing environments.id value to satisfy FK constraints.
+ * @post Returns existing environments.id or None when unresolved.
+ * @pre Session is active
+ */
+
+// --- persist_task (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Persists or updates a single task in the database.
+ * @param task (Task) - The task object to persist.
+ * @post Task record created or updated in database.
+ * @pre isinstance(task, Task)
+ */
+
+// --- persist_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Persists multiple tasks.
+ * @param tasks (List[Task]) - The list of tasks to persist.
+ * @post All tasks in list are persisted.
+ * @pre isinstance(tasks, list)
+ */
+
+// --- load_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Loads tasks from the database.
+ * @param status (Optional[TaskStatus]) - Filter by status.
+ * @post Returns list of Task objects.
+ * @pre limit is an integer.
+ * @return List[Task] - The loaded tasks.
+ */
+
+// --- delete_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Deletes specific tasks from the database.
+ * @param task_ids (List[str]) - List of task IDs to delete.
+ * @post Specified task records deleted from database.
+ * @pre task_ids is a list of strings.
+ */
+
+// --- TaskLogPersistenceService (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Provides methods to store, query, summarize, and delete task log rows in the task_logs table.
+ * @invariant Log entries are batch-inserted for performance.
+ * @post add_logs commits all provided log entries or rolls back on failure, query methods return TaskLog or LogStats views reconstructed from TaskLogRecord rows, and delete methods remove only log rows matching the supplied task identifiers.
+ * @pre TasksSessionLocal must provide an active SQLAlchemy session, task_id inputs must identify task log rows, LogEntry batches must expose timestamp/level/source/message/metadata fields, and LogFilter inputs must provide pagination and filter attributes used by queries.
+ */
+
+// --- add_logs (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Batch insert log entries for a task.
+ * @param logs (List[LogEntry]) - Log entries to insert.
+ * @post All logs inserted into task_logs table.
+ * @pre logs is a list of LogEntry objects.
+ */
+
+// --- get_logs (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Query logs for a task with filtering and pagination.
+ * @param log_filter (LogFilter) - Filter parameters.
+ * @post Returns list of TaskLog objects matching filters.
+ * @pre task_id is a valid task ID.
+ * @return List[TaskLog] - Filtered log entries.
+ */
+
+// --- get_log_stats (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Get statistics about logs for a task.
+ * @param task_id (str) - The task ID.
+ * @post Returns LogStats with counts by level and source.
+ * @pre task_id is a valid task ID.
+ * @return LogStats - Statistics about task logs.
+ */
+
+// --- get_sources (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Get unique sources for a task's logs.
+ * @param task_id (str) - The task ID.
+ * @post Returns list of unique source strings.
+ * @pre task_id is a valid task ID.
+ * @return List[str] - Unique source names.
+ */
+
+// --- delete_logs_for_task (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Delete all logs for a specific task.
+ * @param task_id (str) - The task ID.
+ * @post All logs for the task are deleted.
+ * @pre task_id is a valid task ID.
+ */
+
+// --- delete_logs_for_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Delete all logs for multiple tasks.
+ * @param task_ids (List[str]) - List of task IDs.
+ * @post All logs for the tasks are deleted.
+ * @pre task_ids is a list of task IDs.
+ */
+
+// --- TaskLoggerModule (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Provides a dedicated logger for tasks with automatic source attribution.
+ * @invariant Each TaskLogger instance is bound to a specific task_id and default source.
+ */
+
+// --- TaskLogger (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief A wrapper around TaskManager._add_log that carries task_id and source context.
+ * @invariant All log calls include the task_id and source.
+ */
+
+// --- with_source (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Create a sub-logger with a different default source.
+ * @param source (str) - New default source.
+ * @post Returns new TaskLogger with the same task_id but different source.
+ * @pre source is a non-empty string.
+ * @return TaskLogger - New logger instance.
+ */
+
+// --- _log (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Internal method to log a message at a given level.
+ * @param metadata (Optional[Dict]) - Additional structured data.
+ * @post Log entry added via add_log_fn.
+ * @pre level is a valid log level string.
+ */
+
+// --- debug (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a DEBUG level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added via internally with DEBUG level.
+ * @pre message is a string.
+ */
+
+// --- info (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log an INFO level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with INFO level.
+ * @pre message is a string.
+ */
+
+// --- warning (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a WARNING level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with WARNING level.
+ * @pre message is a string.
+ */
+
+// --- error (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log an ERROR level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with ERROR level.
+ * @pre message is a string.
+ */
+
+// --- progress (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a progress update with percentage.
+ * @param source (Optional[str]) - Override source.
+ * @post Log entry with progress metadata added.
+ * @pre percent is between 0 and 100.
+ */
+
+// --- AppTimezone (backend/src/core/timezone.py)
+/**!
+ * @brief Application-level timezone utilities. Reads APP_TIMEZONE from env (default Europe/Moscow)
+ */
+
+// --- _get_default_tz_name (backend/src/core/timezone.py)
+/**!
+ * @brief Read APP_TIMEZONE from env, fall back to Europe/Moscow.
+ * @post Returns a valid IANA timezone string.
+ * @pre Environment is loaded (dotenv or os.environ).
+ */
+
+// --- get_app_timezone (backend/src/core/timezone.py)
+/**!
+ * @brief Return cached ZoneInfo for the configured application timezone.
+ * @post Returns a ZoneInfo instance matching APP_TIMEZONE env var.
+ */
+
+// --- invalidate_timezone_cache (backend/src/core/timezone.py)
+/**!
+ * @brief Reset the cached ZoneInfo so the next get_app_timezone() call re-reads from env/DB.
+ * @post _APP_TZ_CACHE is set to None; subsequent get_app_timezone() will re-resolve.
+ */
+
+// --- validate_timezone (backend/src/core/timezone.py)
+/**!
+ * @brief Validate that a timezone string is a known IANA timezone.
+ * @post Returns True if ZoneInfo accepts the name, False otherwise.
+ * @pre tz_name is a string.
+ */
+
+// --- localize (backend/src/core/timezone.py)
+/**!
+ * @brief Convert a timezone-aware or naive UTC datetime to the configured app timezone.
+ * @post Returns a datetime with the app timezone attached (astimezone).
+ * @pre If dt is timezone-naive, it is assumed to be UTC.
+ */
+
+// --- now (backend/src/core/timezone.py)
+/**!
+ * @brief Get current time in the configured application timezone.
+ * @post Returns timezone-aware datetime in the app timezone.
+ */
+
+// --- format_timezone_offset (backend/src/core/timezone.py)
+/**!
+ * @brief Return the UTC offset string for the configured timezone (e.g. "+03:00").
+ * @post Returns string like "+03:00" or "+00:00".
+ */
+
+// --- CoreUtils (backend/src/core/utils/__init__.py)
+/**!
+ * @brief Shared utility package root.
+ */
+
+// --- AsyncAPIClient.__init__ (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Initialize async API client for one environment.
+ * @post Client is ready for async request/authentication flow.
+ * @pre config contains base_url and auth payload.
+ */
+
+// --- AsyncAPIClient._normalize_base_url (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Normalize base URL for Superset API root construction.
+ * @post Returns canonical base URL without trailing slash and duplicate /api/v1 suffix.
+ */
+
+// --- AsyncAPIClient._build_api_url (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Build full API URL from relative Superset endpoint.
+ * @post Returns absolute URL for upstream request.
+ */
+
+// --- AsyncAPIClient._get_auth_lock (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Return per-cache-key async lock to serialize fresh login attempts.
+ * @post Returns stable asyncio.Lock instance.
+ */
+
+// --- AsyncAPIClient.authenticate (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Authenticate against Superset and cache access/csrf tokens.
+ * @post Client tokens are populated and reusable across requests.
+ */
+
+// --- AsyncAPIClient.get_headers (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Return authenticated Superset headers for async requests.
+ * @post Headers include Authorization and CSRF tokens.
+ */
+
+// --- AsyncAPIClient._is_dashboard_endpoint (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+ * @post Returns true only for dashboard-specific endpoints.
+ */
+
+// --- AsyncAPIClient._handle_network_error (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Translate generic httpx errors into NetworkError.
+ * @post Raises NetworkError with URL context.
+ */
+
+// --- AsyncAPIClient.aclose (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Close underlying httpx client.
+ * @post Client resources are released.
+ */
+
+// --- DatasetMapperModule (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Этот модуль отвечает за обновление метаданных (verbose_name) в датасетах Superset,
+ */
+
+// --- DatasetMapper (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Класс для маппинга и обновления verbose_name в датасетах Superset.
+ */
+
+// --- get_sqllab_mappings (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Извлекает маппинги column_name -> verbose_name через SQL Lab Superset.
+ * @post Возвращается словарь column_name -> verbose_name из результатов SQL-запроса.
+ * @pre dataset_id должен существовать в Superset.
+ */
+
+// --- load_excel_mappings (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Загружает маппинги column_name -> verbose_name из XLSX файла.
+ * @param file_path (str) - Путь к XLSX файлу.
+ * @post Возвращается словарь с маппингами из файла.
+ * @pre file_path должен указывать на существующий XLSX файл.
+ * @return Dict[str, str] - Словарь с маппингами.
+ */
+
+// --- run_mapping (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Основная функция для выполнения маппинга и обновления verbose_name датасета в Superset.
+ * @param excel_path (Optional[str]) - Путь к XLSX файлу.
+ * @post Если найдены изменения, датасет в Superset обновлен через API.
+ * @pre dataset_id должен быть существующим ID в Superset.
+ */
+
+// --- FileIO (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Предоставляет набор утилит для управления файловыми операциями, включая работу с временными файлами, архивами ZIP, файлами YAML и очистку директорий.
+ */
+
+// --- InvalidZipFormatError (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Exception raised when a file is not a valid ZIP archive.
+ */
+
+// --- create_temp_file (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Контекстный менеджер для создания временного файла или директории с гарантированным удалением.
+ * @post Временный ресурс создан и путь к нему возвращен; ресурс удален после выхода из контекста.
+ * @pre suffix должен быть строкой, определяющей тип ресурса.
+ */
+
+// --- remove_empty_directories (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Рекурсивно удаляет все пустые поддиректории, начиная с указанного пути.
+ * @post Все пустые поддиректории удалены, возвращено их количество.
+ * @pre root_dir должен быть путем к существующей директории.
+ */
+
+// --- read_dashboard_from_disk (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Читает бинарное содержимое файла с диска.
+ * @post Возвращает байты содержимого и имя файла.
+ * @pre file_path должен указывать на существующий файл.
+ */
+
+// --- calculate_crc32 (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Вычисляет контрольную сумму CRC32 для файла.
+ * @post Возвращает 8-значную hex-строку CRC32.
+ * @pre file_path должен быть объектом Path к существующему файлу.
+ */
+
+// --- RetentionPolicy (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Определяет политику хранения для архивов (ежедневные, еженедельные, ежемесячные).
+ */
+
+// --- archive_exports (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Управляет архивом экспортированных файлов, применяя политику хранения и дедупликацию.
+ * @post Старые или дублирующиеся архивы удалены согласно политике.
+ * @pre output_dir должен быть путем к существующей директории.
+ */
+
+// --- apply_retention_policy (backend/src/core/utils/fileio.py)
+/**!
+ * @brief (Helper) Применяет политику хранения к списку файлов, возвращая те, что нужно сохранить.
+ * @post Returns a set of files to keep.
+ * @pre files_with_dates is a list of (Path, date) tuples.
+ */
+
+// --- save_and_unpack_dashboard (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Сохраняет бинарное содержимое ZIP-архива на диск и опционально распаковывает его.
+ * @post ZIP-файл сохранен, и если unpack=True, он распакован в output_dir.
+ * @pre zip_content должен быть байтами валидного ZIP-архива.
+ */
+
+// --- update_yamls (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Обновляет конфигурации в YAML-файлах, заменяя значения или применяя regex.
+ * @post Все YAML файлы в директории обновлены согласно переданным параметрам.
+ * @pre path должен быть существующей директорией.
+ */
+
+// --- _update_yaml_file (backend/src/core/utils/fileio.py)
+/**!
+ * @brief (Helper) Обновляет один YAML файл.
+ * @post Файл обновлен согласно переданным конфигурациям или регулярному выражению.
+ * @pre file_path должен быть объектом Path к существующему YAML файлу.
+ */
+
+// --- replacer (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Функция замены, сохраняющая кавычки если они были.
+ * @post Возвращает строку с новым значением, сохраняя префикс и кавычки.
+ * @pre match должен быть объектом совпадения регулярного выражения.
+ */
+
+// --- create_dashboard_export (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Создает ZIP-архив из указанных исходных путей.
+ * @post ZIP-архив создан по пути zip_path.
+ * @pre source_paths должен содержать существующие пути.
+ */
+
+// --- sanitize_filename (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Очищает строку от символов, недопустимых в именах файлов.
+ * @post Возвращает строку без спецсимволов.
+ * @pre filename должен быть строкой.
+ */
+
+// --- get_filename_from_headers (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Извлекает имя файла из HTTP заголовка 'Content-Disposition'.
+ * @post Возвращает имя файла или None, если заголовок отсутствует.
+ * @pre headers должен быть словарем заголовков.
+ */
+
+// --- consolidate_archive_folders (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Консолидирует директории архивов на основе общего слага в имени.
+ * @post Директории с одинаковым префиксом объединены в одну.
+ * @pre root_directory должен быть объектом Path к существующей директории.
+ */
+
+// --- FuzzyMatching (backend/src/core/utils/matching.py)
+/**!
+ * @brief Provides utility functions for fuzzy matching database names.
+ * @invariant Confidence scores are returned as floats between 0.0 and 1.0.
+ */
+
+// --- suggest_mappings (backend/src/core/utils/matching.py)
+/**!
+ * @brief Suggests mappings between source and target databases using fuzzy matching.
+ * @post Returns a list of suggested mappings with confidence scores.
+ * @pre source_databases and target_databases are lists of dictionaries with 'uuid' and 'database_name'.
+ */
+
+// --- NetworkModule (backend/src/core/utils/network.py)
+/**!
+ * @brief Инкапсулирует низкоуровневую HTTP-логику для взаимодействия с Superset API, включая аутентификацию, управление сессией, retry-логику и обработку ошибок.
+ */
+
+// --- SupersetAPIError (backend/src/core/utils/network.py)
+/**!
+ * @brief Base exception for all Superset API related errors.
+ */
+
+// --- AuthenticationError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when authentication fails.
+ */
+
+// --- PermissionDeniedError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when access is denied.
+ */
+
+// --- DashboardNotFoundError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when a dashboard cannot be found.
+ */
+
+// --- NetworkError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when a network level error occurs.
+ */
+
+// --- NetworkError.__init__ (backend/src/core/utils/network.py)
+/**!
+ * @brief Initializes the network error.
+ * @post NetworkError is initialized.
+ * @pre message is a string.
+ */
+
+// --- SupersetAuthCache (backend/src/core/utils/network.py)
+/**!
+ * @brief Process-local cache for Superset access/csrf tokens keyed by environment credentials.
+ * @post Cached entries expire automatically by TTL and can be reused across requests.
+ * @pre base_url and username are stable strings.
+ */
+
+// --- SupersetAuthCache.get (backend/src/core/utils/network.py)
+/**!
+ */
+
+// --- SupersetAuthCache.set (backend/src/core/utils/network.py)
+/**!
+ */
+
+// --- APIClient (backend/src/core/utils/network.py)
+/**!
+ * @brief Synchronous Superset API client with process-local auth token caching.
+ */
+
+// --- APIClient.__init__ (backend/src/core/utils/network.py)
+/**!
+ * @brief Инициализирует API клиент с конфигурацией, сессией и логгером.
+ * @param timeout (int) - Таймаут запросов.
+ * @post APIClient instance is initialized with a session.
+ * @pre config must contain 'base_url' and 'auth'.
+ */
+
+// --- _init_session (backend/src/core/utils/network.py)
+/**!
+ * @brief Создает и настраивает `requests.Session` с retry-логикой.
+ * @post Returns a configured requests.Session instance.
+ * @pre self.request_settings must be initialized.
+ * @return requests.Session - Настроенная сессия.
+ */
+
+// --- _normalize_base_url (backend/src/core/utils/network.py)
+/**!
+ * @brief Normalize Superset environment URL to base host/path without trailing slash and /api/v1 suffix.
+ */
+
+// --- _build_api_url (backend/src/core/utils/network.py)
+/**!
+ * @brief Build absolute Superset API URL for endpoint using canonical /api/v1 base.
+ * @post Returns full URL without accidental duplicate slashes.
+ * @pre endpoint is relative path or absolute URL.
+ * @return str
+ */
+
+// --- APIClient.authenticate (backend/src/core/utils/network.py)
+/**!
+ * @brief Выполняет аутентификацию в Superset API и получает access и CSRF токены.
+ * @post `self._tokens` заполнен, `self._authenticated` установлен в `True`.
+ * @pre self.auth and self.base_url must be valid.
+ * @return Dict[str, str] - Словарь с токенами.
+ */
+
+// --- headers (backend/src/core/utils/network.py)
+/**!
+ * @brief Возвращает HTTP-заголовки для аутентифицированных запросов.
+ * @post Returns headers including auth tokens.
+ * @pre APIClient is initialized and authenticated or can be authenticated.
+ */
+
+// --- request (backend/src/core/utils/network.py)
+/**!
+ * @brief Выполняет универсальный HTTP-запрос к API.
+ * @param raw_response (bool) - Возвращать ли сырой ответ.
+ * @post Returns response content or raw Response object.
+ * @pre method and endpoint must be strings.
+ * @return `requests.Response` если `raw_response=True`, иначе `dict`.
+ */
+
+// --- _handle_http_error (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Преобразует HTTP ошибки в кастомные исключения.
+ * @param endpoint (str) - Эндпоинт.
+ * @post Raises a specific SupersetAPIError or subclass.
+ * @pre e must be a valid HTTPError with a response.
+ */
+
+// --- _is_dashboard_endpoint (backend/src/core/utils/network.py)
+/**!
+ * @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+ * @post Returns true only for dashboard-specific endpoints.
+ * @pre endpoint may be relative or absolute.
+ */
+
+// --- _handle_network_error (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Преобразует сетевые ошибки в `NetworkError`.
+ * @param url (str) - URL.
+ * @post Raises a NetworkError.
+ * @pre e must be a RequestException.
+ */
+
+// --- upload_file (backend/src/core/utils/network.py)
+/**!
+ * @brief Загружает файл на сервер через multipart/form-data.
+ * @param timeout (Optional[int]) - Таймаут.
+ * @post File is uploaded and response returned.
+ * @pre file_info must contain 'file_obj' and 'file_name'.
+ * @return Ответ API в виде словаря.
+ */
+
+// --- _perform_upload (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Выполняет POST запрос с файлом.
+ * @param timeout (Optional[int]) - Таймаут.
+ * @post POST request is performed and JSON response returned.
+ * @pre url, files, and headers must be provided.
+ * @return Dict - Ответ.
+ */
+
+// --- fetch_paginated_count (backend/src/core/utils/network.py)
+/**!
+ * @brief Получает общее количество элементов для пагинации.
+ * @param count_field (str) - Поле с количеством.
+ * @post Returns total count of items.
+ * @pre query_params must be a dictionary.
+ * @return int - Количество.
+ */
+
+// --- fetch_paginated_data (backend/src/core/utils/network.py)
+/**!
+ * @brief Автоматически собирает данные со всех страниц пагинированного эндпоинта.
+ * @param pagination_options (Dict[str, Any]) - Опции пагинации.
+ * @post Returns all items across all pages.
+ * @pre pagination_options must contain 'base_query', 'results_field'. 'total_count' is optional.
+ * @return List[Any] - Список данных.
+ */
+
+// --- SupersetCompilationAdapter (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Interact with Superset preview compilation and SQL Lab execution endpoints using the current approved execution context.
+ * @invariant The adapter never fabricates compiled SQL locally; preview truth is delegated to Superset only.
+ * @post preview and launch calls return Superset-originated artifacts or explicit errors.
+ * @pre effective template params and dataset execution reference are available.
+ */
+
+// --- SupersetCompilationAdapter.imports (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ */
+
+// --- PreviewCompilationPayload (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Typed preview payload for Superset-side compilation.
+ */
+
+// --- SqlLabLaunchPayload (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Typed SQL Lab payload for audited launch handoff.
+ */
+
+// --- SupersetCompilationAdapter.__init__ (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Bind adapter to one Superset environment and client instance.
+ */
+
+// --- SupersetCompilationAdapter._supports_client_method (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Detect explicitly implemented client capabilities without treating loose mocks as real methods.
+ */
+
+// --- SupersetCompilationAdapter.compile_preview (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Request Superset-side compiled SQL preview for the current effective inputs.
+ * @post returns a ready or failed preview artifact backed only by Superset-originated SQL or diagnostics.
+ * @pre dataset_id and effective inputs are available for the current session.
+ */
+
+// --- SupersetCompilationAdapter.mark_preview_stale (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Invalidate previous preview after mapping or value changes.
+ * @post preview status becomes stale without fabricating a replacement artifact.
+ * @pre preview is a persisted preview artifact or current in-memory snapshot.
+ */
+
+// --- SupersetCompilationAdapter.create_sql_lab_session (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Create the canonical audited execution session after all launch gates pass.
+ * @post returns one canonical SQL Lab session reference from Superset.
+ * @pre compiled_sql is Superset-originated and launch gates are already satisfied.
+ */
+
+// --- SupersetCompilationAdapter._request_superset_preview (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Request preview compilation through explicit client support backed by real Superset endpoints only.
+ * @post returns one normalized upstream compilation response including the chosen strategy metadata.
+ * @pre payload contains a valid dataset identifier and deterministic execution inputs for one preview attempt.
+ */
+
+// --- SupersetCompilationAdapter._request_sql_lab_session (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Probe supported SQL Lab execution surfaces and return the first successful response.
+ * @post returns the first successful SQL Lab execution response from Superset.
+ * @pre payload carries non-empty Superset-originated SQL and a preview identifier for the current launch.
+ */
+
+// --- SupersetCompilationAdapter._normalize_preview_response (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Normalize candidate Superset preview responses into one compiled-sql structure.
+ */
+
+// --- SupersetCompilationAdapter._dump_json (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Serialize Superset request payload deterministically for network transport.
+ */
+
+// --- SupersetContextExtractorPackage (backend/src/core/utils/superset_context_extractor/__init__.py)
+/**!
+ * @brief Recover dataset and dashboard context from Superset links while preserving explicit partial-recovery markers.
+ * @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+ * @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+ * @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+ */
+
+// --- SupersetContextExtractor (backend/src/core/utils/superset_context_extractor/__init__.py)
+/**!
+ * @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+ * @post extractor instance is ready to parse links against one Superset environment.
+ * @pre constructor receives a configured environment with a usable Superset base URL.
+ */
+
+// --- SupersetContextExtractorBase (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Base class and helpers for recovering dataset/dashboard context from Superset links with explicit partial-recovery markers.
+ * @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+ * @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+ * @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+ */
+
+// --- _base_imports (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ */
+
+// --- SupersetParsedContext (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Normalized output of Superset link parsing for session intake and recovery.
+ */
+
+// --- SupersetContextExtractorBase.__init__ (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Bind extractor to one Superset environment and client instance.
+ */
+
+// --- SupersetContextExtractorBase.build_recovery_summary (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Summarize recovered, partial, and unresolved context for session state and UX.
+ */
+
+// --- SupersetContextExtractorBase._extract_numeric_identifier (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a numeric identifier from a REST-like Superset URL path.
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_reference (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard id-or-slug reference from a Superset URL path.
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_permalink_key (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard permalink key from a Superset URL path.
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_id_from_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard identifier from returned permalink state when present.
+ */
+
+// --- SupersetContextExtractorBase._extract_chart_id_from_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a chart identifier from returned permalink state when dashboard id is absent.
+ */
+
+// --- SupersetContextExtractorBase._search_nested_numeric_key (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Recursively search nested dict/list payloads for the first numeric value under a candidate key set.
+ */
+
+// --- SupersetContextExtractorBase._decode_query_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Decode query-string structures used by Superset URL state transport.
+ */
+
+// --- SupersetContextFiltersExtractMixin (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ * @brief Extract normalized imported filters from decoded Superset query state (native_filters, dataMask, native_filter_state, form_data).
+ */
+
+// --- _filters_imports (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ */
+
+// --- SupersetContextFiltersExtractMixin._extract_imported_filters (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ * @brief Normalize imported filters from decoded query state without fabricating missing values.
+ */
+
+// --- SupersetContextParsingMixin (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+ */
+
+// --- _parsing_imports (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ */
+
+// --- SupersetContextParsingMixin.parse_superset_link (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Extract candidate identifiers and query state from supported Superset URLs.
+ * @post returns resolved dataset/dashboard context, preserving explicit partial-recovery state if some identifiers cannot be confirmed.
+ * @pre link is a non-empty Superset URL compatible with the configured environment.
+ */
+
+// --- SupersetContextParsingMixin._recover_dataset_binding_from_dashboard (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Recover a dataset binding from resolved dashboard context while preserving explicit unresolved markers.
+ */
+
+// --- SupersetContextExtractorPII (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief PII redaction helpers for assistant-facing dataset-review context — mask emails, UUIDs, long digit strings, and mixed identifiers.
+ */
+
+// --- _pii_imports (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ */
+
+// --- mask_pii_value (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Redact likely sensitive identifiers while preserving structural hints for assistant-facing dataset-review context.
+ */
+
+// --- sanitize_imported_filter_for_assistant (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Build assistant-safe imported-filter payload with raw-value redaction metadata when sensitive tokens are detected.
+ */
+
+// --- _mask_sensitive_text (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Redact likely PII substrings from one string while preserving non-sensitive delimiters and token shape.
+ */
+
+// --- SupersetContextRecoveryMixin (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Recover imported filters from Superset parsed context and dashboard metadata.
+ */
+
+// --- _recovery_imports (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ */
+
+// --- SupersetContextRecoveryMixin.recover_imported_filters (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Build imported filter entries from URL state and Superset-side saved context.
+ * @post returns explicit recovered and partial filter entries with preserved provenance and confirmation requirements.
+ * @pre parsed_context comes from a successful Superset link parse for one environment.
+ */
+
+// --- SupersetContextRecoveryMixin._normalize_imported_filter_payload (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Normalize one imported-filter payload with explicit provenance and confirmation state.
+ */
+
+// --- SupersetContextTemplatesMixin (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Deterministically detect runtime variables and Jinja references from dataset query-bearing fields without execution.
+ */
+
+// --- _templates_imports (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ */
+
+// --- SupersetContextTemplatesMixin.discover_template_variables (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Detect runtime variables and Jinja references from dataset query-bearing fields.
+ * @post returns deduplicated explicit variable records without executing Jinja or fabricating runtime values.
+ * @pre dataset_payload is a Superset dataset-detail style payload with query-bearing fields when available.
+ */
+
+// --- SupersetContextTemplatesMixin._collect_query_bearing_expressions (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Collect SQL and expression-bearing dataset fields for deterministic template-variable discovery.
+ */
+
+// --- SupersetContextTemplatesMixin._append_template_variable (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Append one deduplicated template-variable descriptor.
+ */
+
+// --- SupersetContextTemplatesMixin._extract_primary_jinja_identifier (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Extract a deterministic primary identifier from a Jinja expression without executing it.
+ */
+
+// --- SupersetContextTemplatesMixin._normalize_default_literal (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Normalize literal default fragments from template helper calls into JSON-safe values.
+ */
+
+// --- WsLogHandlerModule (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief WebSocket log handler module providing LogEntry DTO and WebSocketLogHandler for buffered log streaming.
+ */
+
+// --- WebSocketLogHandler (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Custom logging handler that captures log records into a fixed-capacity buffer for WebSocket streaming.
+ */
+
+// --- WebSocketLogHandler.__init__ (backend/src/core/ws_log_handler.py)
+/**!
+ */
+
+// --- WebSocketLogHandler.emit (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Captures a log record, formats it, and stores it in the buffer as a LogEntry.
+ */
+
+// --- WebSocketLogHandler.get_recent_logs (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Returns a list of recent log entries from the buffer.
+ */
+
+// --- AppDependencies (backend/src/dependencies.py)
+/**!
+ * @brief Provides shared instances to app and routers.
+ */
+
+// --- get_config_manager (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for ConfigManager.
+ * @post Returns shared ConfigManager instance.
+ * @pre Global config_manager must be initialized.
+ */
+
+// --- get_plugin_loader (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for PluginLoader.
+ * @post Returns shared PluginLoader instance.
+ * @pre Global plugin_loader must be initialized.
+ */
+
+// --- get_task_manager (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for TaskManager.
+ * @post Returns shared TaskManager instance.
+ * @pre Global task_manager must be initialized.
+ */
+
+// --- get_scheduler_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for SchedulerService.
+ * @post Returns shared SchedulerService instance.
+ * @pre Global scheduler_service must be initialized.
+ */
+
+// --- get_resource_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for ResourceService.
+ * @post Returns shared ResourceService instance.
+ * @pre Global resource_service must be initialized.
+ */
+
+// --- get_mapping_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for MappingService.
+ * @post Returns new MappingService instance.
+ * @pre Global config_manager must be initialized.
+ */
+
+// --- get_clean_release_repository (backend/src/dependencies.py)
+/**!
+ * @brief Legacy compatibility shim for CleanReleaseRepository.
+ * @post Returns a shared CleanReleaseRepository instance.
+ */
+
+// --- get_clean_release_facade (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for CleanReleaseFacade.
+ * @post Returns a facade instance with a fresh DB session.
+ */
+
+// --- APIKeyPrincipal (backend/src/dependencies.py)
+/**!
+ * @brief Dataclass representing an authenticated API key principal for service-to-service auth.
+ */
+
+// --- require_api_key_or_jwt (backend/src/dependencies.py)
+/**!
+ * @brief Factory: creates a dependency that accepts either a valid API key (with permission check)
+ */
+
+// --- check_api_key_environment_scope (backend/src/dependencies.py)
+/**!
+ * @brief Check the request's API key environment scope against a target env_id. Raises 400 if mismatch.
+ */
+
+// --- get_api_key_principal (backend/src/dependencies.py)
+/**!
+ * @brief FastAPI dependency that reads X-API-Key header and returns APIKeyPrincipal or None.
+ * @post If valid key: returns APIKeyPrincipal; if no header: returns None; if invalid: raises 401.
+ * @pre X-API-Key header may be present in the request.
+ */
+
+// --- oauth2_scheme (backend/src/dependencies.py)
+/**!
+ * @brief OAuth2 password bearer scheme for token extraction (raises 401 on missing token).
+ */
+
+// --- oauth2_scheme_optional (backend/src/dependencies.py)
+/**!
+ * @brief Optional OAuth2 scheme — returns None instead of raising 401 when no token.
+ */
+
+// --- get_current_user (backend/src/dependencies.py)
+/**!
+ * @brief Dependency for retrieving currently authenticated user from a JWT.
+ * @post Returns User object if token is valid.
+ * @pre JWT token provided in Authorization header.
+ */
+
+// --- has_permission (backend/src/dependencies.py)
+/**!
+ * @brief Dependency for checking if the current user has a specific permission.
+ * @post Returns True if user has permission.
+ * @pre User is authenticated.
+ */
+
+// --- ModelsPackage (backend/src/models/__init__.py)
+/**!
+ * @brief Domain model package root.
+ */
+
+// --- TestCleanReleaseModels (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Contract testing for Clean Release models
+ */
+
+// --- test_release_candidate_valid (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a valid release candidate can be instantiated.
+ */
+
+// --- test_release_candidate_empty_id (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a release candidate with an empty ID is rejected.
+ */
+
+// --- test_enterprise_policy_valid (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a valid enterprise policy is accepted.
+ */
+
+// --- test_enterprise_policy_missing_prohibited (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that an enterprise policy without prohibited categories is rejected.
+ */
+
+// --- test_enterprise_policy_external_allowed (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that an enterprise policy allowing external sources is rejected.
+ */
+
+// --- test_manifest_count_mismatch (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a manifest with count mismatches is rejected.
+ */
+
+// --- test_compliant_run_validation (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify compliant run validation logic and mandatory stage checks.
+ */
+
+// --- test_report_validation (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify compliance report validation based on status and violation counts.
+ */
+
+// --- test_models (backend/src/models/__tests__/test_models.py)
+/**!
+ * @brief Unit tests for data models
+ */
+
+// --- test_environment_model (backend/src/models/__tests__/test_models.py)
+/**!
+ * @brief Tests that Environment model correctly stores values.
+ * @post Values are verified.
+ * @pre Environment class is available.
+ */
+
+// --- test_report_models (backend/src/models/__tests__/test_report_models.py)
+/**!
+ * @brief Unit tests for report Pydantic models and their validators
+ */
+
+// --- APIKeyModel (backend/src/models/api_key.py)
+/**!
+ * @brief SQLAlchemy model for API Key authentication — stores SHA-256 hash only, raw key shown once at creation.
+ * @invariant Raw key is NEVER stored — shown once at creation and discarded.
+ */
+
+// --- APIKey (backend/src/models/api_key.py)
+/**!
+ * @brief Stores API key metadata and SHA-256 hash for service-to-service authentication.
+ */
+
+// --- AssistantModels (backend/src/models/assistant.py)
+/**!
+ * @brief SQLAlchemy models for assistant audit trail and confirmation tokens.
+ * @invariant Assistant records preserve immutable ids and creation timestamps.
+ */
+
+// --- AssistantAuditRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Store audit decisions and outcomes produced by assistant command handling.
+ * @post Audit payload remains available for compliance and debugging.
+ * @pre user_id must identify the actor for every record.
+ */
+
+// --- AssistantMessageRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Persist chat history entries for assistant conversations.
+ * @post Message row can be queried in chronological order.
+ * @pre user_id, conversation_id, role and text must be present.
+ */
+
+// --- AssistantConfirmationRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Persist risky operation confirmation tokens with lifecycle state.
+ * @post State transitions can be tracked and audited.
+ * @pre intent/dispatch and expiry timestamp must be provided.
+ */
+
+// --- AuthModels (backend/src/models/auth.py)
+/**!
+ * @brief SQLAlchemy models for multi-user authentication and authorization.
+ * @invariant Usernames and emails must be unique.
+ * @post Auth ORM models registered with unique constraints
+ * @pre Database engine initialized
+ */
+
+// --- generate_uuid (backend/src/models/auth.py)
+/**!
+ * @brief Generates a unique UUID string.
+ * @post Returns a string representation of a new UUID.
+ */
+
+// --- user_roles (backend/src/models/auth.py)
+/**!
+ * @brief Association table for many-to-many relationship between Users and Roles.
+ */
+
+// --- role_permissions (backend/src/models/auth.py)
+/**!
+ * @brief Association table for many-to-many relationship between Roles and Permissions.
+ */
+
+// --- Role (backend/src/models/auth.py)
+/**!
+ * @brief Represents a collection of permissions.
+ */
+
+// --- Permission (backend/src/models/auth.py)
+/**!
+ * @brief Represents a specific capability within the system.
+ */
+
+// --- ADGroupMapping (backend/src/models/auth.py)
+/**!
+ * @brief Maps an Active Directory group to a local System Role.
+ */
+
+// --- CleanReleaseModels (backend/src/models/clean_release.py)
+/**!
+ * @brief Define canonical clean release domain entities and lifecycle guards.
+ * @invariant Immutable snapshots are never mutated; forbidden lifecycle transitions are rejected.
+ * @post Provides SQLAlchemy and dataclass definitions for governance domain.
+ * @pre Base mapping model and release enums are available.
+ */
+
+// --- ExecutionMode (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible execution mode enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckFinalStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible final status enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageName (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage name enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage status enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageResult (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage result container for legacy TUI/orchestrator tests.
+ */
+
+// --- ProfileType (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible profile enum for legacy TUI bootstrap logic.
+ */
+
+// --- RegistryStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible registry status enum for legacy TUI bootstrap logic.
+ */
+
+// --- ReleaseCandidateStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible release candidate status enum for legacy TUI.
+ */
+
+// --- ResourceSourceEntry (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible source entry model for legacy TUI bootstrap logic.
+ */
+
+// --- ResourceSourceRegistry (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible source registry model for legacy TUI bootstrap logic.
+ */
+
+// --- CleanProfilePolicy (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible policy model for legacy TUI bootstrap logic.
+ */
+
+// --- ComplianceCheckRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible run model for legacy TUI typing/import compatibility.
+ */
+
+// --- ReleaseCandidate (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents the release unit being prepared and governed.
+ * @post status advances only through legal transitions.
+ * @pre id, version, source_snapshot_ref are non-empty.
+ */
+
+// --- CandidateArtifact (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents one artifact associated with a release candidate.
+ */
+
+// --- ManifestItem (backend/src/models/clean_release.py)
+/**!
+ */
+
+// --- ManifestSummary (backend/src/models/clean_release.py)
+/**!
+ */
+
+// --- DistributionManifest (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable snapshot of the candidate payload.
+ * @invariant Immutable after creation.
+ */
+
+// --- SourceRegistrySnapshot (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable registry snapshot for allowed sources.
+ */
+
+// --- CleanPolicySnapshot (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable policy snapshot used to evaluate a run.
+ */
+
+// --- ComplianceRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Operational record for one compliance execution.
+ */
+
+// --- ComplianceStageRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Stage-level execution record inside a run.
+ */
+
+// --- ViolationSeverity (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible violation severity enum for legacy clean-release tests.
+ */
+
+// --- ViolationCategory (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible violation category enum for legacy clean-release tests.
+ */
+
+// --- ComplianceViolation (backend/src/models/clean_release.py)
+/**!
+ * @brief Violation produced by a stage.
+ */
+
+// --- ComplianceReport (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable result derived from a completed run.
+ * @invariant Immutable after creation.
+ */
+
+// --- ApprovalDecision (backend/src/models/clean_release.py)
+/**!
+ * @brief Approval or rejection bound to a candidate and report.
+ */
+
+// --- PublicationRecord (backend/src/models/clean_release.py)
+/**!
+ * @brief Publication or revocation record.
+ */
+
+// --- CleanReleaseAuditLog (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents a persistent audit log entry for clean release actions.
+ */
+
+// --- AppConfigRecord (backend/src/models/config.py)
+/**!
+ * @brief Stores persisted application configuration as a single authoritative record model.
+ * @post ORM table 'app_configurations' exposes id, payload, and updated_at fields with declared nullability/default semantics.
+ * @pre SQLAlchemy declarative Base is initialized and table metadata registration is active.
+ */
+
+// --- NotificationConfig (backend/src/models/config.py)
+/**!
+ * @brief Stores persisted provider-level notification configuration and encrypted credentials metadata.
+ * @post ORM table 'notification_configs' exposes id, type, name, credentials, is_active, created_at, updated_at fields with declared constraints/defaults.
+ * @pre SQLAlchemy declarative Base is initialized and uuid generation is available at instance creation time.
+ */
+
+// --- DashboardModels (backend/src/models/dashboard.py)
+/**!
+ * @brief Defines data models for dashboard metadata and selection.
+ */
+
+// --- DashboardMetadata (backend/src/models/dashboard.py)
+/**!
+ * @brief Represents a dashboard available for migration.
+ */
+
+// --- DashboardSelection (backend/src/models/dashboard.py)
+/**!
+ * @brief Represents the user's selection of dashboards to migrate.
+ */
+
+// --- DatasetReviewModels (backend/src/models/dataset_review.py)
+/**!
+ * @brief Thin facade re-exporting all dataset review domain models from the decomposed sub-package.
+ * @invariant All public model classes and enums remain importable from `src.models.dataset_review` without changes.
+ */
+
+// --- DatasetReviewClarificationModels (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief Clarification session, question, option, and answer models for guided review flow.
+ * @invariant Only one active clarification question may exist at a time per session.
+ * @post Clarification ORM models registered
+ * @pre Database engine initialized
+ */
+
+// --- ClarificationSession (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One clarification session aggregate owning questions and tracking resolution progress.
+ */
+
+// --- ClarificationQuestion (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One clarification question with priority ordering, options, and state machine.
+ */
+
+// --- ClarificationOption (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One selectable option for a clarification question with recommendation flag.
+ */
+
+// --- ClarificationAnswer (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One persisted clarification answer with impact summary and feedback tracking.
+ */
+
+// --- DatasetReviewEnums (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief All enumeration types for the dataset review domain, grouped for stable cross-module reuse.
+ * @invariant Enum values are string-based for JSON serialization compatibility.
+ */
+
+// --- SessionStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status of a dataset review session.
+ */
+
+// --- SessionPhase (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Ordered phase progression for dataset review orchestration.
+ */
+
+// --- ReadinessState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Granular readiness indicator driving the recommended-action UX flow.
+ */
+
+// --- RecommendedAction (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Next-action guidance derived from the current readiness state.
+ */
+
+// --- SessionCollaboratorRole (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief RBAC role for session collaborators.
+ */
+
+// --- BusinessSummarySource (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Provenance of the dataset business summary text.
+ */
+
+// --- ConfidenceState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Confidence level for dataset profile completeness.
+ */
+
+// --- FindingArea (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Domain area classification for validation findings.
+ */
+
+// --- FindingSeverity (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Severity classification for validation findings.
+ */
+
+// --- ResolutionState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Resolution status for validation findings and clarification items.
+ */
+
+// --- SemanticSourceType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Classification of semantic enrichment source origins.
+ */
+
+// --- TrustLevel (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Trust classification for semantic source reliability.
+ */
+
+// --- SemanticSourceStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for semantic source application.
+ */
+
+// --- FieldKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Kind classification for semantic field entries.
+ */
+
+// --- FieldProvenance (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Provenance tracking for semantic field value origin.
+ */
+
+// --- CandidateMatchType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Match type classification for semantic candidates.
+ */
+
+// --- CandidateStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for semantic candidate proposals.
+ */
+
+// --- FilterSource (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Origin classification for imported filters.
+ */
+
+// --- FilterConfidenceState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Confidence classification for imported filter values.
+ */
+
+// --- FilterRecoveryStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Recovery quality status for imported filters.
+ */
+
+// --- VariableKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Kind classification for template variables.
+ */
+
+// --- MappingStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for template variable mapping.
+ */
+
+// --- MappingMethod (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Method classification for execution mapping creation.
+ */
+
+// --- MappingWarningLevel (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Warning severity for execution mapping quality indicators.
+ */
+
+// --- ApprovalState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Approval lifecycle for execution mapping gate checks.
+ */
+
+// --- ClarificationStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for clarification sessions.
+ */
+
+// --- QuestionState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief State machine for individual clarification questions.
+ */
+
+// --- AnswerKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Classification of clarification answer types.
+ */
+
+// --- PreviewStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for compiled SQL previews.
+ */
+
+// --- LaunchStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Outcome status for dataset launch handoff.
+ */
+
+// --- ArtifactType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Type classification for export artifacts.
+ */
+
+// --- ArtifactFormat (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Format classification for export artifact output.
+ */
+
+// --- DatasetReviewExecutionModels (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief Compiled preview, run context, session event, and export artifact models for execution and audit.
+ */
+
+// --- CompiledPreview (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One compiled SQL preview snapshot with fingerprint for staleness detection.
+ */
+
+// --- DatasetRunContext (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief Immutable launch audit snapshot capturing effective filters, template params, and approval state at launch time.
+ */
+
+// --- SessionEvent (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One persisted audit event for dataset review session mutations.
+ */
+
+// --- ExportArtifact (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One persisted export artifact reference for documentation and validation outputs.
+ */
+
+// --- DatasetReviewFilterModels (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Imported filter and template variable models for Superset context recovery and execution mapping.
+ */
+
+// --- ImportedFilter (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Recovered Superset filter with confidence and recovery status tracking.
+ */
+
+// --- TemplateVariable (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Discovered template variable from dataset SQL with mapping status tracking.
+ */
+
+// --- DatasetReviewFindingModels (backend/src/models/dataset_review_pkg/_finding_models.py)
+/**!
+ * @brief Validation finding model for tracking blocking, warning, and informational issues during review.
+ */
+
+// --- ValidationFinding (backend/src/models/dataset_review_pkg/_finding_models.py)
+/**!
+ * @brief Structured finding record for dataset review validation issues with resolution tracking.
+ */
+
+// --- DatasetReviewMappingModels (backend/src/models/dataset_review_pkg/_mapping_models.py)
+/**!
+ * @brief Execution mapping model linking imported filters to template variables with approval gates.
+ */
+
+// --- ExecutionMapping (backend/src/models/dataset_review_pkg/_mapping_models.py)
+/**!
+ * @brief One filter-to-variable mapping with approval gate, effective value, and transformation metadata.
+ * @invariant Explicit approval is required before launch when requires_explicit_approval is true.
+ */
+
+// --- DatasetReviewProfileModels (backend/src/models/dataset_review_pkg/_profile_models.py)
+/**!
+ * @brief Dataset profile model capturing business summary, confidence, and completeness metadata.
+ */
+
+// --- DatasetProfile (backend/src/models/dataset_review_pkg/_profile_models.py)
+/**!
+ * @brief One-to-one profile snapshot for a dataset review session, tracking business summary provenance and completeness.
+ */
+
+// --- DatasetReviewSemanticModels (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Semantic source, field entry, and candidate models for dictionary-driven semantic enrichment.
+ * @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+ * @post Semantic ORM models registered with override protection
+ * @pre Database engine initialized
+ */
+
+// --- SemanticSource (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Registered semantic enrichment source with trust level and application status.
+ */
+
+// --- SemanticFieldEntry (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Per-field semantic metadata entry with provenance tracking, lock state, and candidate set.
+ * @invariant Locked fields preserve their active value regardless of later candidate proposals.
+ */
+
+// --- SemanticCandidate (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief One proposed semantic value for a field entry, ranked by match type and confidence.
+ */
+
+// --- DatasetReviewSessionModels (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief Session aggregate root and collaborator models for dataset review orchestration.
+ * @invariant Session and profile entities are strictly scoped to an authenticated user.
+ * @post Session ORM models registered with optimistic locking
+ * @pre Database engine initialized
+ */
+
+// --- SessionCollaborator (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief RBAC collaborator record linking a user to a dataset review session with a specific role.
+ */
+
+// --- DatasetReviewSession (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief Aggregate root for the dataset review lifecycle, owning all child entities and driving readiness transitions.
+ * @invariant Optimistic-lock version column prevents lost-update races on concurrent mutations.
+ */
+
+// --- FilterStateModels (backend/src/models/filter_state.py)
+/**!
+ * @brief Pydantic models for Superset native filter state extraction and restoration.
+ */
+
+// --- FilterState (backend/src/models/filter_state.py)
+/**!
+ * @brief Represents the state of a single native filter.
+ */
+
+// --- NativeFilterDataMask (backend/src/models/filter_state.py)
+/**!
+ * @brief Represents the dataMask containing all native filter states.
+ */
+
+// --- ParsedNativeFilters (backend/src/models/filter_state.py)
+/**!
+ * @brief Result of parsing native filters from permalink or native_filters_key.
+ */
+
+// --- DashboardURLFilterExtraction (backend/src/models/filter_state.py)
+/**!
+ * @brief Result of parsing a complete dashboard URL for filter information.
+ */
+
+// --- ExtraFormDataMerge (backend/src/models/filter_state.py)
+/**!
+ * @brief Configuration for merging extraFormData from different sources.
+ */
+
+// --- GitModels (backend/src/models/git.py)
+/**!
+ */
+
+// --- GitServerConfig (backend/src/models/git.py)
+/**!
+ * @brief Configuration for a Git server connection.
+ */
+
+// --- GitRepository (backend/src/models/git.py)
+/**!
+ * @brief Tracking for a local Git repository linked to a dashboard.
+ */
+
+// --- DeploymentEnvironment (backend/src/models/git.py)
+/**!
+ * @brief Target Superset environments for dashboard deployment.
+ */
+
+// --- LlmModels (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy models for LLM provider configuration and validation results.
+ */
+
+// --- ValidationPolicy (backend/src/models/llm.py)
+/**!
+ * @brief Defines a scheduled rule for validating a group of dashboards within an execution window.
+ */
+
+// --- LLMProvider (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy model for LLM provider configuration.
+ */
+
+// --- ValidationRecord (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy model for dashboard validation history.
+ */
+
+// --- MaintenanceModels (backend/src/models/maintenance.py)
+/**!
+ * @brief SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.
+ * @invariant MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint
+ */
+
+// --- MaintenanceEventStatus (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- MaintenanceDashboardBannerStatus (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- MaintenanceDashboardStateStatus (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- DashboardScope (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- MaintenanceEvent (backend/src/models/maintenance.py)
+/**!
+ * @brief A record of a maintenance event with table list, time window, status, and linked dashboard states.
+ */
+
+// --- MaintenanceDashboardBanner (backend/src/models/maintenance.py)
+/**!
+ * @brief The canonical "one chart per dashboard" entity. Unique partial index enforces single active banner per dashboard.
+ * @invariant Unique partial index (environment_id, dashboard_id) WHERE status='active'
+ */
+
+// --- MaintenanceDashboardState (backend/src/models/maintenance.py)
+/**!
+ * @brief Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.
+ */
+
+// --- MaintenanceSettings (backend/src/models/maintenance.py)
+/**!
+ * @brief Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').
+ * @invariant id must always be 'default' — enforced by CheckConstraint
+ */
+
+// --- MappingModels (backend/src/models/mapping.py)
+/**!
+ * @brief Defines the database schema for environment metadata and database mappings using SQLAlchemy.
+ * @invariant All primary keys are UUID strings.
+ */
+
+// --- Base (backend/src/models/mapping.py)
+/**!
+ * @brief SQLAlchemy declarative base for all domain models.
+ */
+
+// --- ResourceType (backend/src/models/mapping.py)
+/**!
+ * @brief Enumeration of possible Superset resource types for ID mapping.
+ */
+
+// --- MigrationStatus (backend/src/models/mapping.py)
+/**!
+ * @brief Enumeration of possible migration job statuses.
+ */
+
+// --- MigrationJob (backend/src/models/mapping.py)
+/**!
+ * @brief Represents a single migration execution job.
+ */
+
+// --- ResourceMapping (backend/src/models/mapping.py)
+/**!
+ * @brief Maps a universal UUID for a resource to its actual ID on a specific environment.
+ */
+
+// --- ProfileModels (backend/src/models/profile.py)
+/**!
+ * @brief Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
+ * @invariant Sensitive Git token is stored encrypted and never returned in plaintext.
+ * @post Profile ORM models registered
+ * @pre Database engine initialized
+ */
+
+// --- UserDashboardPreference (backend/src/models/profile.py)
+/**!
+ * @brief Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
+ */
+
+// --- ReportModels (backend/src/models/report.py)
+/**!
+ * @brief Canonical report schemas for unified task reporting across heterogeneous task types.
+ * @invariant Canonical report fields are always present for every report item.
+ * @post Provides validated schemas for cross-plugin reporting and UI consumption.
+ * @pre Pydantic library and task manager models are available.
+ */
+
+// --- TaskType (backend/src/models/report.py)
+/**!
+ * @brief Supported normalized task report types.
+ * @invariant Must contain valid generic task type mappings.
+ */
+
+// --- ReportStatus (backend/src/models/report.py)
+/**!
+ * @brief Supported normalized report status values.
+ * @invariant TaskStatus enum mapping logic holds.
+ */
+
+// --- ErrorContext (backend/src/models/report.py)
+/**!
+ * @brief Error and recovery context for failed/partial reports.
+ * @invariant The properties accurately describe error state.
+ */
+
+// --- TaskReport (backend/src/models/report.py)
+/**!
+ * @brief Canonical normalized report envelope for one task execution.
+ * @invariant Must represent canonical task record attributes.
+ */
+
+// --- ReportQuery (backend/src/models/report.py)
+/**!
+ * @brief Query object for server-side report filtering, sorting, and pagination.
+ * @invariant Time and pagination queries are mutually consistent.
+ */
+
+// --- ReportCollection (backend/src/models/report.py)
+/**!
+ * @brief Paginated collection of normalized task reports.
+ * @invariant Represents paginated data correctly.
+ */
+
+// --- ReportDetailView (backend/src/models/report.py)
+/**!
+ * @brief Detailed report representation including diagnostics and recovery actions.
+ * @invariant Incorporates a report and logs correctly.
+ */
+
+// --- StorageModels (backend/src/models/storage.py)
+/**!
+ */
+
+// --- FileCategory (backend/src/models/storage.py)
+/**!
+ * @brief Enumeration of supported file categories in the storage system.
+ */
+
+// --- StorageConfig (backend/src/models/storage.py)
+/**!
+ * @brief Configuration model for the storage system, defining paths and naming patterns.
+ */
+
+// --- StoredFile (backend/src/models/storage.py)
+/**!
+ * @brief Data model representing metadata for a file stored in the system.
+ */
+
+// --- TaskModels (backend/src/models/task.py)
+/**!
+ * @brief Defines the database schema for task execution records.
+ * @invariant All primary keys are UUID strings.
+ */
+
+// --- TaskRecord (backend/src/models/task.py)
+/**!
+ * @brief Represents a persistent record of a task execution.
+ */
+
+// --- TaskLogRecord (backend/src/models/task.py)
+/**!
+ * @brief Represents a single persistent log entry for a task.
+ * @invariant Each log entry belongs to exactly one task.
+ */
+
+// --- TranslateModels (backend/src/models/translate.py)
+/**!
+ * @brief SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects.
+ */
+
+// --- TranslationJob (backend/src/models/translate.py)
+/**!
+ * @brief A translation job representing a multi-dialect conversion task with column mappings, LLM config, and dictionary attachments.
+ */
+
+// --- TranslationRun (backend/src/models/translate.py)
+/**!
+ * @brief Represents a single execution of a translation job, capturing status, timing, and Superset execution metadata.
+ */
+
+// --- TranslationBatch (backend/src/models/translate.py)
+/**!
+ * @brief Groups translation records within a run into manageable batches with timing and record counts.
+ */
+
+// --- TranslationRecord (backend/src/models/translate.py)
+/**!
+ * @brief Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.
+ */
+
+// --- TranslationEvent (backend/src/models/translate.py)
+/**!
+ * @brief Audit/event log for translation operations, with optional run_id for context.
+ */
+
+// --- TranslationPreviewSession (backend/src/models/translate.py)
+/**!
+ * @brief A preview session allowing users to review proposed translations before applying them.
+ */
+
+// --- TranslationPreviewRecord (backend/src/models/translate.py)
+/**!
+ * @brief Individual preview entry within a preview session, showing original and translated content side by side.
+ */
+
+// --- TerminologyDictionary (backend/src/models/translate.py)
+/**!
+ * @brief A named collection of terminology mappings used during translation to ensure consistent term translation.
+ */
+
+// --- DictionaryEntry (backend/src/models/translate.py)
+/**!
+ * @brief A single term mapping entry with case-insensitive unique constraint on source_term_normalized and origin tracking.
+ */
+
+// --- TranslationSchedule (backend/src/models/translate.py)
+/**!
+ * @brief Defines a cron-based schedule for recurring translation jobs.
+ */
+
+// --- TranslationJobDictionary (backend/src/models/translate.py)
+/**!
+ * @brief Many-to-many association between translation jobs and terminology dictionaries.
+ */
+
+// --- MetricSnapshot (backend/src/models/translate.py)
+/**!
+ * @brief Captures translation performance metrics at a point in time with config/content/dictionary hash keys for aggregation.
+ */
+
+// --- TranslationLanguage (backend/src/models/translate.py)
+/**!
+ * @brief Per-language translation result for a single record, supporting multi-language output.
+ */
+
+// --- TranslationPreviewLanguage (backend/src/models/translate.py)
+/**!
+ * @brief Per-language preview entry within a preview session.
+ */
+
+// --- TranslationRunLanguageStats (backend/src/models/translate.py)
+/**!
+ * @brief Per-language statistics for a translation run (row counts, tokens, cost).
+ */
+
+// --- src.plugins (backend/src/plugins/__init__.py)
+/**!
+ * @brief Plugin package root for dynamic discovery and runtime imports.
+ */
+
+// --- BackupPlugin (backend/src/plugins/backup.py)
+/**!
+ * @brief A plugin that provides functionality to back up Superset dashboards.
+ */
+
+// --- DebugPluginModule (backend/src/plugins/debug.py)
+/**!
+ * @brief Plugin for diagnostics. Inherits PluginBase.
+ */
+
+// --- DebugPlugin (backend/src/plugins/debug.py)
+/**!
+ * @brief Plugin for system diagnostics and debugging.
+ */
+
+// --- GitPluginExt (backend/src/plugins/git/__init__.py)
+/**!
+ * @brief Git plugin extension package root.
+ */
+
+// --- GitLLMExtensionModule (backend/src/plugins/git/llm_extension.py)
+/**!
+ * @brief LLM-based extensions for the Git plugin, specifically for commit message generation.
+ */
+
+// --- GitLLMExtension (backend/src/plugins/git/llm_extension.py)
+/**!
+ * @brief Provides LLM capabilities to the Git plugin.
+ */
+
+// --- GitPluginModule (backend/src/plugins/git_plugin.py)
+/**!
+ * @brief Предоставляет плагин для версионирования и развертывания дашбордов Superset.
+ * @invariant _handle_sync сохраняет backup управляемых директорий перед удалением;
+ */
+
+// --- GitPlugin (backend/src/plugins/git_plugin.py)
+/**!
+ * @brief Реализация плагина Git Integration для управления версиями дашбордов.
+ */
+
+// --- LLMAnalysisPackage (backend/src/plugins/llm_analysis/__init__.py)
+/**!
+ */
+
+// --- LLMAnalysisModels (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Define Pydantic models for LLM Analysis plugin.
+ */
+
+// --- LLMProviderType (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Enum for supported LLM providers.
+ */
+
+// --- LLMProviderConfig (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Configuration for an LLM provider.
+ */
+
+// --- ValidationStatus (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Enum for dashboard validation status.
+ */
+
+// --- DetectedIssue (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Model for a single issue detected during validation.
+ */
+
+// --- ValidationResult (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Model for dashboard validation result.
+ */
+
+// --- LLMAnalysisPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Implements DashboardValidationPlugin and DocumentationPlugin.
+ * @invariant All LLM interactions must be executed as asynchronous tasks.
+ */
+
+// --- _is_masked_or_invalid_api_key (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Guards against placeholder or malformed API keys in runtime.
+ * @post Returns True when value cannot be used for authenticated provider calls.
+ * @pre value may be None.
+ */
+
+// --- _json_safe_value (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Recursively normalize payload values for JSON serialization.
+ * @post datetime values are converted to ISO strings.
+ * @pre value may be nested dict/list with datetime values.
+ */
+
+// --- DashboardValidationPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Plugin for automated dashboard health analysis using LLMs.
+ */
+
+// --- DocumentationPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Plugin for automated dataset documentation using LLMs.
+ */
+
+// --- LLMAnalysisScheduler (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Provides helper functions to schedule LLM-based validation tasks.
+ */
+
+// --- schedule_dashboard_validation (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Schedules a recurring dashboard validation task.
+ */
+
+// --- _parse_cron (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Basic cron parser placeholder.
+ */
+
+// --- LLMAnalysisService (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Services for LLM interaction and dashboard screenshots.
+ * @invariant Screenshots must be 1920px width and capture full page height.
+ */
+
+// --- ScreenshotService (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Handles capturing screenshots of Superset dashboards.
+ */
+
+// --- LLMClient (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Wrapper for LLM provider APIs.
+ */
+
+// --- MaintenanceBannerPlugin (backend/src/plugins/maintenance_banner.py)
+/**!
+ * @brief TaskManager plugin for executing maintenance banner operations (start, end, end-all).
+ */
+
+// --- MapperPluginModule (backend/src/plugins/mapper.py)
+/**!
+ * @brief Plugin for dataset column mapping. Inherits PluginBase.
+ */
+
+// --- MapperPlugin (backend/src/plugins/mapper.py)
+/**!
+ * @brief Plugin for mapping dataset columns verbose names.
+ */
+
+// --- MigrationPlugin (backend/src/plugins/migration.py)
+/**!
+ * @brief Orchestrates export, DB-mapping transformation, and import of Superset dashboards across environments.
+ * @invariant Dashboards must never be imported with unmapped/source DB connections to prevent data leaks or cross-environment pollution.
+ * @post Plugin metadata remains stable and migration execution preserves mapped-environment import guarantees.
+ * @pre Plugin loader can resolve infrastructure dependencies and execution requests provide validated migration context.
+ */
+
+// --- SearchPluginModule (backend/src/plugins/search.py)
+/**!
+ * @brief Plugin for text search across datasets. Inherits PluginBase.
+ */
+
+// --- SearchPlugin (backend/src/plugins/search.py)
+/**!
+ * @brief Plugin for searching text patterns in Superset datasets.
+ */
+
+// --- StoragePluginPackage (backend/src/plugins/storage/__init__.py)
+/**!
+ */
+
+// --- StoragePlugin (backend/src/plugins/storage/plugin.py)
+/**!
+ * @brief Provides core filesystem operations for managing backups and repositories.
+ * @invariant All file operations must be restricted to the configured storage root.
+ */
+
+// --- TranslatePluginPackage (backend/src/plugins/translate/__init__.py)
+/**!
+ */
+
+// --- TestClickHouseTimestampNormalization (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify Unix timestamp detection and conversion for ClickHouse Date columns.
+ */
+
+// --- TestClickHouseInsertSqlGeneration (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify SQLGenerator produces valid ClickHouse INSERT SQL with normalized dates.
+ */
+
+// --- TestClickHouseJoinVerification (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify the JOIN query SQL is syntactically correct for ClickHouse.
+ */
+
+// --- TestOrchestratorInsertFlow (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify the orchestrator's _generate_and_insert_sql produces correct SQL for ClickHouse.
+ */
+
+// --- TestClickHouseEndToEnd (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief End-to-end test: generate SQL, verify structure, simulate execution.
+ */
+
+// --- TestDictionaryLegacyHub (backend/src/plugins/translate/__tests__/test_dictionary.py)
+/**!
+ * @brief Legacy test module — all tests migrated to domain-specific test files:
+ */
+
+// --- TestDictionaryCorrection (backend/src/plugins/translate/__tests__/test_dictionary_correction.py)
+/**!
+ * @brief Validate InlineCorrectionService and dictionary correction flows.
+ */
+
+// --- TestDictionaryCRUD (backend/src/plugins/translate/__tests__/test_dictionary_crud.py)
+/**!
+ * @brief Validate DictionaryCRUD and DictionaryEntryCRUD operations.
+ */
+
+// --- TestDictionaryFilter (backend/src/plugins/translate/__tests__/test_dictionary_filter.py)
+/**!
+ * @brief Validate DictionaryBatchFilter operations.
+ */
+
+// --- TestDictionaryImport (backend/src/plugins/translate/__tests__/test_dictionary_import.py)
+/**!
+ * @brief Validate DictionaryImportExport operations.
+ */
+
+// --- TestDictionaryPromptBuilder (backend/src/plugins/translate/__tests__/test_dictionary_prompt_builder.py)
+/**!
+ * @brief Validate ContextAwarePromptBuilder operations: Jaccard similarity, context truncation, entry rendering.
+ */
+
+// --- TestDictionaryUtils (backend/src/plugins/translate/__tests__/test_dictionary_utils.py)
+/**!
+ * @brief Validate utility functions: _normalize_term and _detect_delimiter.
+ */
+
+// --- LanguageDetectServiceTests (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @brief Unit tests for LanguageDetectService — local language detection via lingua.
+ */
+
+// --- test_detect_language_basic (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @brief Verify core language detection for common languages.
+ */
+
+// --- test_detect_language_edge_cases (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_batch_detect (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_build_detector (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_get_detector_cache (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_code_to_lang_mapping (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- fixtures (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- TestTextCleaner (backend/src/plugins/translate/__tests__/test_text_cleaner.py)
+/**!
+ * @brief Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.
+ */
+
+// --- TestTokenBudget (backend/src/plugins/translate/__tests__/test_token_budget.py)
+/**!
+ * @brief Verify estimate_token_budget contracts — safe batch sizing, auto-reduction, warning generation.
+ */
+
+// --- BatchInsertService (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @brief Insert successful translation records into target table via Superset SQL Lab.
+ */
+
+// --- insert_batch_to_target (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @brief Insert successful records from a single batch into the target table.
+ */
+
+// --- _fetch_batch_records (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _build_target_columns (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _build_context_keys (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _build_insert_rows (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _resolve_insert_backend (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _generate_insert_sql (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _execute_insert_sql (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- BatchProcessingService (backend/src/plugins/translate/_batch_proc.py)
+/**!
+ * @brief Batch processing for translation: classify rows (same-language/cache/preview/LLM),
+ */
+
+// --- process_batch (backend/src/plugins/translate/_batch_proc.py)
+/**!
+ * @brief Process a single batch: create record, classify rows, call LLM, persist.
+ * @post TranslationBatch and TranslationRecord rows are created.
+ * @pre job and batch_rows are valid.
+ */
+
+// --- AdaptiveBatchSizer (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Adaptive batch sizing for LLM translation — splits source rows into variable-sized
+ */
+
+// --- resolve_provider_model (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Resolve the LLM provider model name for token budget estimation.
+ * @post Returns model name string or None if resolution fails.
+ */
+
+// --- auto_size_batches (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Split source rows into variable-sized batches based on content length.
+ * @post Returns list of batches, each batch is a list of row dicts.
+ * @pre source_rows is non-empty. job has valid config.
+ */
+
+// --- LanguageDetectService (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Local language detection powered by lingua-language-detector (no LLM).
+ */
+
+// --- _detector_cache_key (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Build a deterministic cache key from target languages list.
+ */
+
+// --- build_detector (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Build a LanguageDetector restricted to target + common source languages.
+ */
+
+// --- get_detector (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Get or create a cached detector for the given target languages.
+ */
+
+// --- detect_language (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Detect the language of a single text string. Returns BCP-47 code or "und".
+ */
+
+// --- _character_block_fallback (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief When lingua returns "und", check if character-block dominance (e.g. Cyrillic)
+ */
+
+// --- batch_detect (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Detect language for multiple texts in batch. Builds detector if not provided.
+ */
+
+// --- LLMTranslationService (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief LLM interaction for batch translation: call provider with retry, handle truncation
+ */
+
+// --- call_llm_for_batch (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief Call LLM for a batch of rows requiring translation. Parse and persist results.
+ * @post Returns dict with successful/failed/skipped counts.
+ * @pre job has valid provider_id. batch_rows is non-empty.
+ */
+
+// --- call_llm (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief Route to provider-specific LLM call implementation.
+ */
+
+// --- LLMHttpClient (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @brief HTTP client for OpenAI-compatible LLM API calls with rate-limit handling and
+ */
+
+// --- call_openai_compatible (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @brief Call OpenAI-compatible API with rate-limit handling and structured output fallback.
+ * @post Returns (response text, finish_reason).
+ * @pre Valid API endpoint, key, model, and prompt.
+ */
+
+// --- _do_http_request (backend/src/plugins/translate/_llm_http.py)
+/**!
+ */
+
+// --- _handle_response_format_fallback (backend/src/plugins/translate/_llm_http.py)
+/**!
+ */
+
+// --- LLMResponseParser (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ * @brief Parse LLM JSON response into per-row translations with support for markdown code
+ */
+
+// --- _recover_from_markdown (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ */
+
+// --- _recover_truncated_rows (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ */
+
+// --- RunExecutionService (backend/src/plugins/translate/_run_service.py)
+/**!
+ * @brief Full run lifecycle: prepare run, fetch source rows, filter new keys, orchestrate batches,
+ */
+
+// --- RunSourceFetcher (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @brief Fetch source rows for translation runs from Superset datasource or preview session.
+ */
+
+// --- fetch_source_rows (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @brief Fetch source rows from Superset datasource or preview session fallback.
+ */
+
+// --- _extract_chart_data_rows (backend/src/plugins/translate/_run_source.py)
+/**!
+ */
+
+// --- TextCleaner (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Text cleaning utilities for the translation pipeline — whitespace normalization
+ */
+
+// --- normalize_whitespace (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Collapse multiple spaces, tabs, and newlines into single spaces; trim leading/trailing
+ */
+
+// --- truncate_text (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Truncate text to max_length characters, appending "..." if truncation occurs.
+ * @post When len(text) <= max_length, returns text unchanged.
+ * @pre text is a string. max_length >= 0.
+ */
+
+// --- clean_text (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Combine whitespace normalization and truncation into one step.
+ */
+
+// --- estimate_token_budget (backend/src/plugins/translate/_token_budget.py)
+/**!
+ * @brief Calculate safe batch_size and max_tokens for LLM translation calls based on actual content length and model context window limits.
+ */
+
+// --- DEFAULT_CONTEXT_WINDOW (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DEFAULT_MAX_OUTPUT_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- REASONING_OVERHEAD (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- PROVIDER_DEFAULTS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- OUTPUT_PER_ROW_PER_LANG (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- JSON_OVERHEAD_PER_ROW (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- PROMPT_BASE_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DICT_TOKENS_PER_ENTRY (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DICT_TOKENS_MAX (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- CHARS_PER_TOKEN_MIXED (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- MIN_MAX_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- MAX_OUTPUT_HEADROOM (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- TranslationUtils (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Shared utility functions for the translation plugin — dictionary enforcement,
+ */
+
+// --- _normalize_term (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Normalize a term for case-insensitive unique constraint lookup.
+ */
+
+// --- _detect_delimiter (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Detect the delimiter used in a CSV/TSV header line.
+ */
+
+// --- _enforce_dictionary (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Post-process LLM output: enforce dictionary term replacements.
+ * @post per_lang_values may be mutated to include forced dictionary replacements.
+ * @pre dict_matches is a list of dict entries with source_term/target_term.
+ */
+
+// --- _compute_source_hash (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Compute deterministic cache key for a source row.
+ */
+
+// --- _check_translation_cache (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Look up a previously successful translation by source_hash.
+ */
+
+// --- _compute_key_hash (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Compute a stable hash from source_data dict for matching preview edits.
+ */
+
+// --- estimate_row_tokens (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Estimate token count for a single source row including context fields.
+ * @post Returns estimated token count >= 1.
+ * @pre source_text is a string.
+ */
+
+// --- DictionaryManagerModule (backend/src/plugins/translate/dictionary.py)
+/**!
+ * @brief Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering.
+ * @post Dictionary and entry mutations are persisted with conflict detection.
+ * @pre Database session is open and valid.
+ */
+
+// --- DictionaryManager (backend/src/plugins/translate/dictionary.py)
+/**!
+ * @brief Facade for terminology dictionaries: delegates to DictionaryCRUD, DictionaryEntryCRUD, DictionaryImportExport, DictionaryBatchFilter, DictionaryCorrectionService.
+ * @post Dictionary and entry mutations are persisted with conflict detection.
+ * @pre Database session is open and valid.
+ */
+
+// --- DictionaryCorrectionService (backend/src/plugins/translate/dictionary_correction.py)
+/**!
+ * @brief Submit term corrections and bulk corrections to dictionaries with conflict detection.
+ */
+
+// --- DictionaryCRUD (backend/src/plugins/translate/dictionary_crud.py)
+/**!
+ * @brief CRUD operations for TerminologyDictionary records.
+ */
+
+// --- DictionaryEntryCRUD (backend/src/plugins/translate/dictionary_entries.py)
+/**!
+ * @brief CRUD operations for DictionaryEntry records.
+ */
+
+// --- DictionaryBatchFilter (backend/src/plugins/translate/dictionary_filter.py)
+/**!
+ * @brief Scan batch texts for case-insensitive, word-boundary-aware matches against dictionaries.
+ */
+
+// --- DictionaryImportExport (backend/src/plugins/translate/dictionary_import_export.py)
+/**!
+ * @brief Import/export entries as CSV/TSV with conflict detection, and migration of old entries.
+ */
+
+// --- _validate_bcp47 (backend/src/plugins/translate/dictionary_validation.py)
+/**!
+ * @brief Validate that a language tag is a non-empty BCP-47 string.
+ */
+
+// --- TranslationEventLog (backend/src/plugins/translate/events.py)
+/**!
+ * @brief Structured event logging for translation operations with terminal event invariant enforcement.
+ * @invariant Exactly one run_started + exactly one terminal event per non-null run_id.
+ * @post Events are persisted immutably; terminal events enforce exactly-one invariant per run.
+ * @pre Database session is open and valid.
+ */
+
+// --- TranslationExecutor (backend/src/plugins/translate/executor.py)
+/**!
+ * @brief Process translation in batches: fetch source rows, call LLM, persist TranslationBatch
+ */
+
+// --- TranslationMetrics (backend/src/plugins/translate/metrics.py)
+/**!
+ * @brief Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting.
+ * @post Metrics are aggregated and returned; no side effects.
+ * @pre Database session is open.
+ */
+
+// --- TranslationOrchestrator (backend/src/plugins/translate/orchestrator.py)
+/**!
+ * @brief Run lifecycle coordination: validate preconditions, dispatch executor, generate SQL, submit to Superset, record events.
+ * @invariant State transitions: PENDING -> RUNNING -> COMPLETED|FAILED|CANCELLED. Exactly one terminal event per run.
+ * @post Translation run is executed, SQL generated and submitted, events recorded.
+ * @pre Valid job and accepted preview (for manual runs). Superset and LLM are reachable.
+ */
+
+// --- TranslationResultAggregator (backend/src/plugins/translate/orchestrator_aggregator.py)
+/**!
+ * @brief Query translation run status, records, and history.
+ * @post Returns structured run data with pagination.
+ * @pre Database session is available.
+ */
+
+// --- orchestrator_cancel (backend/src/plugins/translate/orchestrator_cancel.py)
+/**!
+ * @brief Cancel and retry-insert operations for translation runs.
+ */
+
+// --- orchestrator_config (backend/src/plugins/translate/orchestrator_config.py)
+/**!
+ * @brief Config hash and dictionary snapshot hash utilities for translation planning.
+ */
+
+// --- TranslationExecutionEngine (backend/src/plugins/translate/orchestrator_exec.py)
+/**!
+ * @brief Execute translation runs: dispatch executor, manage completion and failure paths.
+ * @post Run is executed with SQL generated; events recorded.
+ * @pre Database session and config manager are available. Run is in valid state.
+ */
+
+// --- update_language_stats (backend/src/plugins/translate/orchestrator_lang_stats.py)
+/**!
+ * @brief Aggregate TranslationLanguage entries by language_code and update TranslationRunLanguageStats.
+ */
+
+// --- TranslationPlanner (backend/src/plugins/translate/orchestrator_planner.py)
+/**!
+ * @brief Handle translation run planning: validation, config hashing, dictionary snapshot.
+ * @post TranslationRun is planned with hashes and config snapshot; events recorded.
+ * @pre Database session and config manager are available.
+ */
+
+// --- orchestrator_query (backend/src/plugins/translate/orchestrator_query.py)
+/**!
+ * @brief Query translation run records and history with pagination.
+ */
+
+// --- TranslationRunRetryManager (backend/src/plugins/translate/orchestrator_retry.py)
+/**!
+ * @brief Manage retry of translation run batches.
+ * @post Retried batches are re-executed.
+ * @pre Database session and config manager are available.
+ */
+
+// --- orchestrator_run_completion (backend/src/plugins/translate/orchestrator_run_completion.py)
+/**!
+ * @brief Post-execution run completion handlers: cancelled, success-with-insert, and failure paths.
+ */
+
+// --- TranslationStageRunner (backend/src/plugins/translate/orchestrator_runner.py)
+/**!
+ * @brief Coordinate translation run execution, retry, and cancellation via delegated components.
+ * @post Run is executed; events recorded.
+ * @pre Database session and config manager are available. Run is in valid state.
+ */
+
+// --- SQLInsertService (backend/src/plugins/translate/orchestrator_sql.py)
+/**!
+ * @brief Generate INSERT SQL from translation records and submit to Superset SQL Lab.
+ * @post SQL is generated and submitted to Superset; returns execution result.
+ * @pre Job has target table configured. Run has successful records.
+ */
+
+// --- orchestrator_sql_rows (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Column and row building utilities for SQL insertion in translate plugin.
+ */
+
+// --- build_columns (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build list of target columns for SQL INSERT from job configuration.
+ */
+
+// --- build_context_keys (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build list of context keys for SQL row data.
+ */
+
+// --- build_rows (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build row data for SQL INSERT with per-language expansion.
+ */
+
+// --- validate_job_preconditions (backend/src/plugins/translate/orchestrator_validation.py)
+/**!
+ * @brief Validate preconditions before starting a translation run.
+ * @post Raises ValueError if any precondition fails.
+ * @pre Job exists and db session is valid.
+ */
+
+// --- TranslatePlugin (backend/src/plugins/translate/plugin.py)
+/**!
+ * @brief TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.
+ */
+
+// --- DEFAULT_EXECUTION_PROMPT_TEMPLATE (backend/src/plugins/translate/preview_constants.py)
+/**!
+ * @brief Default LLM prompt template for full execution (batch translation).
+ */
+
+// --- DEFAULT_PREVIEW_PROMPT_TEMPLATE (backend/src/plugins/translate/preview_constants.py)
+/**!
+ * @brief Default LLM prompt template for preview (sample translation).
+ */
+
+// --- PreviewExecutor (backend/src/plugins/translate/preview_executor.py)
+/**!
+ * @brief Fetch sample data from Superset and call LLM provider for preview.
+ * @post Sample rows fetched, LLM called.
+ * @pre Database session, config manager, and Superset client are available.
+ */
+
+// --- PreviewPromptBuilder (backend/src/plugins/translate/preview_prompt_builder.py)
+/**!
+ * @brief Build LLM prompts for preview sessions including dictionary glossary and row context.
+ */
+
+// --- preview_prompt_helpers (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Token estimation metadata and budget helpers for preview prompt building.
+ */
+
+// --- estimate_token_budget_for_rows (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Check token budget and optionally truncate source rows for preview.
+ * @post Returns adjusted source_rows, actual_row_count, and token_budget dict.
+ */
+
+// --- compute_build_token_metadata (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Compute token estimation metadata for prompt builder return dict.
+ * @post Returns prompt, row_meta, target_languages, cost estimates, and cost_warning.
+ */
+
+// --- preview_response_parser (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Parse LLM JSON responses and Superset data; compute config/dict hashes for preview.
+ */
+
+// --- parse_llm_response (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Parse LLM JSON response into structured translations dict with per-language support.
+ * @post Returns dict mapping row_id -> {detected_source_language, lang_code: translation, ...}.
+ * @pre response_text is a valid JSON string (possibly wrapped in markdown code block).
+ */
+
+// --- extract_data_rows (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Extract data rows from Superset chart data API response.
+ */
+
+// --- compute_config_hash (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Compute a deterministic hash of job configuration for snapshot comparison.
+ */
+
+// --- compute_dict_snapshot_hash (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Compute a hash of dictionary state for snapshot comparison.
+ */
+
+// --- PreviewSessionManager (backend/src/plugins/translate/preview_review.py)
+/**!
+ * @brief Manage preview session row-level actions: approve/edit/reject rows.
+ */
+
+// --- preview_session_ops (backend/src/plugins/translate/preview_session_ops.py)
+/**!
+ * @brief Preview session lifecycle operations: accept and query preview sessions.
+ */
+
+// --- get_preview_session (backend/src/plugins/translate/preview_session_ops.py)
+/**!
+ * @brief Get the latest preview session for a job with its records.
+ */
+
+// --- preview_session_serializer (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Serialization and action helpers for preview sessions: record serialization and per-row approve/reject/edit actions.
+ */
+
+// --- serialize_preview_record (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Serialize a TranslationPreviewRecord to a response dict.
+ */
+
+// --- apply_language_action (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Apply approve/reject/edit action to a TranslationPreviewLanguage entry.
+ */
+
+// --- apply_record_action (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Apply approve/reject/edit action to a TranslationPreviewRecord and its language entries.
+ */
+
+// --- TokenEstimator (backend/src/plugins/translate/preview_token_estimator.py)
+/**!
+ * @brief Estimate token counts and costs for LLM translation operations.
+ */
+
+// --- ContextAwarePromptBuilder (backend/src/plugins/translate/prompt_builder.py)
+/**!
+ * @brief Pure-function prompt builder that enhances dictionary entries with context annotations.
+ */
+
+// --- TranslationScheduler (backend/src/plugins/translate/scheduler.py)
+/**!
+ * @brief Manage TranslationSchedule rows and register them with core SchedulerService.
+ * @post TranslationSchedule CRUD persisted; APScheduler jobs registered/updated/removed.
+ * @pre Database session and SchedulerService are available.
+ */
+
+// --- execute_scheduled_translation (backend/src/plugins/translate/scheduler.py)
+/**!
+ * @brief APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.
+ * @post Translation run created and executed if no concurrent run exists.
+ * @pre schedule_id is valid.
+ */
+
+// --- TranslateJobService (backend/src/plugins/translate/service.py)
+/**!
+ * @brief Service layer for translation job CRUD with datasource column validation and database dialect detection.
+ * @post Translation jobs are created/updated/deleted with column validation and dialect caching.
+ * @pre Database session and config manager are available.
+ */
+
+// --- BulkFindReplaceService (backend/src/plugins/translate/service_bulk_replace.py)
+/**!
+ * @brief Service for bulk find-and-replace operations on translated values.
+ */
+
+// --- DatasourceMetadataService (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Fetch datasource column metadata and database dialect from Superset.
+ * @post Datasource metadata is fetched with column details and normalized dialect.
+ * @pre Database session and config manager are available.
+ */
+
+// --- get_dialect_from_database (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Extract normalized dialect string from a Superset database record.
+ */
+
+// --- fetch_datasource_metadata (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Fetch datasource columns and database dialect from Superset.
+ */
+
+// --- detect_virtual_columns (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Identify virtual (calculated) columns from column metadata.
+ */
+
+// --- InlineCorrectionService (backend/src/plugins/translate/service_inline_correction.py)
+/**!
+ * @brief Service for inline editing translated values and submitting corrections to dictionaries.
+ * @post Inline edits applied with optional dictionary submission.
+ * @pre Database session is available.
+ */
+
+// --- TargetSchemaValidation (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Проверка схемы целевой таблицы: запрос колонок через Superset SQL Lab,
+ */
+
+// --- _build_expected_columns (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Собирает список ожидаемых колонок по конфигурации column mapping.
+ */
+
+// --- _extract_columns_from_rows (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Извлекает список колонок таблицы из data-строк результата SQL Lab.
+ */
+
+// --- _parse_sqllab_result (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Извлекает data-строки из ответа Superset SQL Lab.
+ */
+
+// --- validate_target_table_schema (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Основная функция: проверяет схему целевой таблицы через Superset SQL Lab.
+ * @post Возвращает TargetSchemaValidationResponse с diff-анализом.
+ * @pre Superset окружение и target_database_id валидны.
+ */
+
+// --- ServiceUtils (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Utility functions for the translate service layer.
+ */
+
+// --- _extract_dialect (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Extract database dialect from Superset backend URI.
+ */
+
+// --- job_to_response (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Convert a TranslationJob ORM model to a TranslateJobResponse schema with dictionary_ids.
+ */
+
+// --- SQLGenerator (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Dialect-aware safe SQL generation for INSERT/UPSERT operations.
+ * @post Returns safe SQL strings for the target dialect.
+ * @pre Job has target_schema and target_table configured. Dialect is one of supported SUPPORTED_DIALECTS.
+ */
+
+// --- _normalize_timestamp_value (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Detect Unix timestamp strings (seconds or millis) and convert to 'YYYY-MM-DD' for Date columns.
+ */
+
+// --- _quote_identifier (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.
+ * @post Returns safely quoted identifier.
+ * @pre identifier is a non-empty string.
+ */
+
+// --- _encode_sql_value (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Encode a Python value into a SQL-safe literal for INSERT VALUES, with ClickHouse timestamp normalization.
+ */
+
+// --- _build_values_clause (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Build a VALUES clause for multiple rows with per-column value encoding and dialect-aware quoting.
+ */
+
+// --- generate_insert_sql (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Generate a dialect-aware plain INSERT SQL statement for the given table, columns, and rows.
+ */
+
+// --- generate_upsert_sql (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.
+ * @post Returns UPSERT SQL string or raises ValueError.
+ * @pre dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.
+ */
+
+// --- SupersetSqlLabExecutor (backend/src/plugins/translate/superset_executor.py)
+/**!
+ * @brief Submit SQL to Superset SQL Lab API and poll execution status.
+ * @post SQL is submitted to Superset SQL Lab; execution reference is returned.
+ * @pre Valid Superset environment configuration and authenticated client.
+ */
+
+// --- SchemasPackage (backend/src/schemas/__init__.py)
+/**!
+ * @brief API schema package root.
+ */
+
+// --- TestSettingsAndHealthSchemas (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Regression tests for settings and health schema contracts updated in 026 fix batch.
+ */
+
+// --- test_validation_policy_create_accepts_structured_custom_channels (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Ensure policy schema accepts structured custom channel objects with type/target fields.
+ */
+
+// --- test_validation_policy_create_rejects_legacy_string_custom_channels (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Ensure legacy list[str] custom channel payload is rejected by typed channel contract.
+ */
+
+// --- test_dashboard_health_item_status_accepts_only_whitelisted_values (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Verify strict grouped regex only accepts PASS/WARN/FAIL/UNKNOWN exact statuses.
+ */
+
+// --- AuthSchemas (backend/src/schemas/auth.py)
+/**!
+ * @brief Pydantic schemas for authentication requests and responses.
+ * @invariant Sensitive fields like password must not be included in response schemas.
+ */
+
+// --- Token (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a JWT access token response.
+ */
+
+// --- TokenData (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents the data encoded in a JWT token.
+ */
+
+// --- PermissionSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a permission in API responses.
+ */
+
+// --- RoleSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a role in API responses.
+ */
+
+// --- RoleCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating a new role.
+ */
+
+// --- RoleUpdate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for updating an existing role.
+ */
+
+// --- ADGroupMappingSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents an AD Group to Role mapping in API responses.
+ */
+
+// --- ADGroupMappingCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating an AD Group mapping.
+ */
+
+// --- UserBase (backend/src/schemas/auth.py)
+/**!
+ * @brief Base schema for user data.
+ */
+
+// --- UserCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating a new user.
+ */
+
+// --- UserUpdate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for updating an existing user.
+ */
+
+// --- User (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for user data in API responses.
+ */
+
+// --- DatasetReviewSchemas (backend/src/schemas/dataset_review.py)
+/**!
+ * @brief Thin facade re-exporting all dataset review API schemas from decomposed sub-modules.
+ */
+
+// --- DatasetReviewSchemaComposites (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Composite Pydantic DTOs for clarification, preview, run context, and session summary/detail responses.
+ */
+
+// --- ClarificationOptionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification option DTO.
+ */
+
+// --- ClarificationAnswerDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification answer DTO with feedback.
+ */
+
+// --- ClarificationQuestionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification question DTO with nested options and answer.
+ */
+
+// --- ClarificationSessionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification session DTO with nested questions.
+ */
+
+// --- CompiledPreviewDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Compiled preview DTO with fingerprint and session version.
+ */
+
+// --- DatasetRunContextDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Run context DTO with launch audit data and session version.
+ */
+
+// --- SessionSummary (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Lightweight session summary DTO for list responses.
+ */
+
+// --- SessionDetail (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Full session detail DTO with all nested aggregates for detail views.
+ */
+
+// --- DatasetReviewSchemaDtos (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Pydantic DTOs for session, profile, findings, collaborators, and semantic field API payloads.
+ */
+
+// --- SessionCollaboratorDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Collaborator DTO for session access control.
+ */
+
+// --- DatasetProfileDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Dataset profile DTO with business summary and confidence metadata.
+ */
+
+// --- ValidationFindingDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Validation finding DTO with resolution tracking.
+ */
+
+// --- SemanticSourceDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic source DTO with trust level and status.
+ */
+
+// --- SemanticCandidateDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic candidate DTO with match type and confidence score.
+ */
+
+// --- SemanticFieldEntryDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic field entry DTO with nested candidates and session version.
+ */
+
+// --- ImportedFilterDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Imported filter DTO with confidence and recovery status.
+ */
+
+// --- TemplateVariableDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Template variable DTO with mapping status.
+ */
+
+// --- ExecutionMappingDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Execution mapping DTO with approval state and session version.
+ */
+
+// --- HealthSchemas (backend/src/schemas/health.py)
+/**!
+ * @brief Pydantic schemas for dashboard health summary.
+ */
+
+// --- DashboardHealthItem (backend/src/schemas/health.py)
+/**!
+ * @brief Represents the latest health status of a single dashboard.
+ */
+
+// --- HealthSummaryResponse (backend/src/schemas/health.py)
+/**!
+ * @brief Aggregated health summary for all dashboards.
+ */
+
+// --- ProfileSchemas (backend/src/schemas/profile.py)
+/**!
+ * @brief Defines API schemas for profile preference persistence, security read-only snapshot, and Superset account lookup.
+ * @invariant Schema shapes stay stable for profile UI states and backend preference contracts.
+ */
+
+// --- ProfilePermissionState (backend/src/schemas/profile.py)
+/**!
+ * @brief Represents one permission badge state for profile read-only security view.
+ */
+
+// --- ProfileSecuritySummary (backend/src/schemas/profile.py)
+/**!
+ * @brief Read-only security and access snapshot for current user.
+ */
+
+// --- ProfilePreference (backend/src/schemas/profile.py)
+/**!
+ * @brief Represents persisted profile preference for a single authenticated user.
+ */
+
+// --- ProfilePreferenceUpdateRequest (backend/src/schemas/profile.py)
+/**!
+ * @brief Request payload for updating current user's profile settings.
+ */
+
+// --- ProfilePreferenceResponse (backend/src/schemas/profile.py)
+/**!
+ * @brief Response envelope for profile preference read/update endpoints.
+ */
+
+// --- SupersetAccountLookupRequest (backend/src/schemas/profile.py)
+/**!
+ * @brief Query contract for Superset account lookup by selected environment.
+ */
+
+// --- SupersetAccountCandidate (backend/src/schemas/profile.py)
+/**!
+ * @brief Canonical account candidate projected from Superset users payload.
+ */
+
+// --- SupersetAccountLookupResponse (backend/src/schemas/profile.py)
+/**!
+ * @brief Response envelope for Superset account lookup (success or degraded mode).
+ */
+
+// --- SettingsSchemas (backend/src/schemas/settings.py)
+/**!
+ * @brief Pydantic schemas for application settings and automation policies.
+ */
+
+// --- NotificationChannel (backend/src/schemas/settings.py)
+/**!
+ * @brief Structured notification channel definition for policy-level custom routing.
+ */
+
+// --- ValidationPolicyBase (backend/src/schemas/settings.py)
+/**!
+ * @brief Base schema for validation policy data.
+ */
+
+// --- ValidationPolicyCreate (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for creating a new validation policy.
+ */
+
+// --- ValidationPolicyUpdate (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for updating an existing validation policy.
+ */
+
+// --- ValidationPolicyResponse (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for validation policy response data.
+ */
+
+// --- TranslationScheduleItem (backend/src/schemas/settings.py)
+/**!
+ * @brief Response schema for a translation schedule item with joined job name.
+ */
+
+// --- TranslateSchemas (backend/src/schemas/translate.py)
+/**!
+ * @brief Pydantic v2 schemas for translation API request/response serialization.
+ */
+
+// --- TranslateJobCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for creating a new translation job.
+ */
+
+// --- TranslateJobUpdate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for updating an existing translation job.
+ */
+
+// --- TranslateJobResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation job API responses.
+ */
+
+// --- DatasourceColumnResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for datasource column metadata response.
+ */
+
+// --- DatasourceColumnsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for datasource columns endpoint response.
+ */
+
+// --- DuplicateJobResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for duplicate job response.
+ */
+
+// --- DictionaryCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for creating a new terminology dictionary.
+ */
+
+// --- DictionaryImport (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for importing entries into a terminology dictionary.
+ */
+
+// --- DictionaryResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for terminology dictionary API responses.
+ */
+
+// --- DictionaryEntryCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for adding/editing a dictionary entry with language pair support.
+ */
+
+// --- DictionaryEntryResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for dictionary entry API responses.
+ */
+
+// --- DictionaryImportResult (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for dictionary import result.
+ */
+
+// --- PreviewRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for triggering a translation preview.
+ */
+
+// --- PreviewRowUpdate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for approving/editing/rejecting a preview row.
+ */
+
+// --- PreviewAcceptResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for preview accept response.
+ */
+
+// --- CostEstimate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for cost estimation in preview response.
+ */
+
+// --- TermCorrectionSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting a term correction in a translation preview.
+ */
+
+// --- TermCorrectionBulkSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting multiple term corrections atomically.
+ */
+
+// --- CorrectionConflictResult (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for reporting conflicts in correction submission.
+ */
+
+// --- CorrectionSubmitResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for correction submission response.
+ */
+
+// --- ScheduleResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for schedule API responses.
+ */
+
+// --- NextExecutionResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for next execution preview.
+ */
+
+// --- TranslationRunResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation run API responses.
+ */
+
+// --- RunDetailResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for detailed run response including records, events, and config snapshot.
+ */
+
+// --- RunHistoryFilter (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for filtering run history.
+ */
+
+// --- RunListResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for paginated run list response.
+ */
+
+// --- AggregatedMetricsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for aggregated per-job metrics.
+ */
+
+// --- TranslationPreviewLanguageResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language preview data in API responses.
+ */
+
+// --- PreviewRow (backend/src/schemas/translate.py)
+/**!
+ * @brief A single row in a translation preview showing original and translated content side by side.
+ */
+
+// --- TranslationPreviewResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation preview session API responses.
+ */
+
+// --- TranslationBatchResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation batch API responses.
+ */
+
+// --- MetricsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation metrics API responses.
+ */
+
+// --- TranslationLanguageResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language translation data in API responses.
+ */
+
+// --- TranslationRunLanguageStatsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language statistics in run API responses.
+ */
+
+// --- OverrideLanguageRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for manually overriding the detected source language of a translation.
+ */
+
+// --- BulkFindReplaceRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for bulk find-and-replace within translations for a target language.
+ */
+
+// --- InlineEditRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for inline editing a translated value on a completed run result.
+ */
+
+// --- BulkReplacePreviewItem (backend/src/schemas/translate.py)
+/**!
+ * @brief A single item in a bulk replace preview list.
+ */
+
+// --- BulkReplaceResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Response for bulk find-and-replace operation.
+ */
+
+// --- InlineCorrectionSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting an inline correction for a specific translated record.
+ */
+
+// --- TargetSchemaValidationRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for requesting target table schema validation.
+ */
+
+// --- TargetSchemaColumnInfo (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for a single column in the schema validation response.
+ */
+
+// --- TargetSchemaValidationResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for target table schema validation response.
+ */
+
+// --- ValidationSchemas (backend/src/schemas/validation.py)
+/**!
+ * @brief Pydantic v2 schemas for validation task management and run history API serialization.
+ */
+
+// --- ValidationTaskCreate (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for creating a new validation task (policy).
+ */
+
+// --- ValidationTaskUpdate (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for updating an existing validation task (policy).
+ */
+
+// --- ValidationTaskResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for validation task API responses — includes last run status from join.
+ */
+
+// --- ValidationTaskListResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for paginated task list response.
+ */
+
+// --- ValidationRunResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for validation run history listing.
+ */
+
+// --- ValidationRunListResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for paginated run list response.
+ */
+
+// --- ValidationRunDetailResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for full run detail including parsed issues and raw response.
+ */
+
+// --- TriggerRunResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for trigger-run response — returns spawned task ID.
+ */
+
+// --- ScriptsPackage (backend/src/scripts/__init__.py)
+/**!
+ * @brief Script entrypoint package root.
+ */
+
+// --- CleanReleaseCliScript (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Provide headless CLI commands for candidate registration, artifact import and manifest build.
+ */
+
+// --- build_parser (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Build argparse parser for clean release CLI.
+ */
+
+// --- run_candidate_register (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Register candidate in repository via CLI command.
+ * @post Candidate is persisted in DRAFT status.
+ * @pre Candidate ID must be unique.
+ */
+
+// --- run_artifact_import (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Import single artifact for existing candidate.
+ * @post Artifact is persisted for candidate.
+ * @pre Candidate must exist.
+ */
+
+// --- run_manifest_build (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Build immutable manifest snapshot for candidate.
+ * @post New manifest version is persisted.
+ * @pre Candidate must exist.
+ */
+
+// --- run_compliance_run (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Execute compliance run for candidate with optional manifest fallback.
+ * @post Returns run payload and exit code 0 on success.
+ * @pre Candidate exists and trusted snapshots are configured.
+ */
+
+// --- run_compliance_status (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read run status by run id.
+ * @post Returns run status payload.
+ * @pre Run exists.
+ */
+
+// --- _to_payload (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Serialize domain models for CLI JSON output across SQLAlchemy/Pydantic variants.
+ * @post Returns dictionary payload without mutating value.
+ * @pre value is serializable model or primitive object.
+ */
+
+// --- run_compliance_report (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read immutable report by run id.
+ * @post Returns report payload.
+ * @pre Run and report exist.
+ */
+
+// --- run_compliance_violations (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read run violations by run id.
+ * @post Returns violations payload.
+ * @pre Run exists.
+ */
+
+// --- run_approve (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Approve candidate based on immutable PASSED report.
+ * @post Persists APPROVED decision and returns success payload.
+ * @pre Candidate and report exist; report is PASSED.
+ */
+
+// --- run_reject (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Reject candidate without mutating compliance evidence.
+ * @post Persists REJECTED decision and returns success payload.
+ * @pre Candidate and report exist.
+ */
+
+// --- run_publish (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Publish approved candidate to target channel.
+ * @post Appends ACTIVE publication record and returns payload.
+ * @pre Candidate is approved and report belongs to candidate.
+ */
+
+// --- run_revoke (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Revoke active publication record.
+ * @post Publication record status becomes REVOKED.
+ * @pre Publication id exists and is ACTIVE.
+ */
+
+// --- CleanReleaseTuiScript (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Interactive terminal interface for Enterprise Clean Release compliance validation.
+ * @invariant TUI refuses startup in non-TTY environments; headless flow is CLI/API only.
+ */
+
+// --- TuiFacadeAdapter (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Thin TUI adapter that routes business mutations through application services.
+ * @post Business actions return service results/errors without direct TUI-owned mutations.
+ * @pre repository contains candidate and trusted policy/registry snapshots for execution.
+ */
+
+// --- CleanReleaseTUI (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Curses-based application for compliance monitoring.
+ */
+
+// --- run_checks (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Execute compliance run via facade adapter and update UI state.
+ * @post UI reflects final run/report/violation state from service result.
+ * @pre Candidate and policy snapshots are present in repository.
+ */
+
+// --- bundle_build_mode (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Interactive bundle build screen — select type, enter tag, watch live build output.
+ * @post Subprocess completes (success/failure). Output displayed. User returns via Esc.
+ * @pre TTY is available. Bundle type selected (1 or 2). Tag is non-empty.
+ */
+
+// --- CreateAdminScript (backend/src/scripts/create_admin.py)
+/**!
+ * @brief CLI tool for creating the initial admin user.
+ * @invariant Admin user must have the "Admin" role.
+ */
+
+// --- create_admin (backend/src/scripts/create_admin.py)
+/**!
+ * @brief Creates an admin user and necessary roles/permissions.
+ * @post Admin user exists in auth.db.
+ * @pre username and password provided via CLI.
+ */
+
+// --- DeleteRunningTasksUtil (backend/src/scripts/delete_running_tasks.py)
+/**!
+ * @brief Script to delete tasks with RUNNING status from the database.
+ */
+
+// --- delete_running_tasks (backend/src/scripts/delete_running_tasks.py)
+/**!
+ * @brief Delete all tasks with RUNNING status from the database.
+ * @post All tasks with status 'RUNNING' are removed from the database.
+ * @pre Database is accessible and TaskRecord model is defined.
+ */
+
+// --- InitAuthDbScript (backend/src/scripts/init_auth_db.py)
+/**!
+ * @brief Initializes the auth database and creates the necessary tables.
+ * @invariant Safe to run multiple times (idempotent).
+ */
+
+// --- run_init (backend/src/scripts/init_auth_db.py)
+/**!
+ * @brief Main entry point for the initialization script.
+ * @post auth.db is initialized with the correct schema and seeded permissions.
+ */
+
+// --- SeedPermissionsScript (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Populates the auth database with initial system permissions.
+ * @invariant Safe to run multiple times (idempotent).
+ */
+
+// --- INITIAL_PERMISSIONS (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Canonical bootstrap permission tuples seeded into auth storage.
+ */
+
+// --- seed_permissions (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Inserts missing permissions into the database.
+ * @post All INITIAL_PERMISSIONS exist in the DB.
+ */
+
+// --- SeedSupersetLoadTestScript (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Creates randomized load-test data in Superset by cloning chart configurations and creating dashboards in target environments.
+ * @invariant Created chart and dashboard names are globally unique for one script run.
+ */
+
+// --- _parse_args (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Parses CLI arguments for load-test data generation.
+ * @post Returns validated argument namespace.
+ * @pre Script is called from CLI.
+ */
+
+// --- _extract_result_payload (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Normalizes Superset API payloads that may be wrapped in `result`.
+ * @post Returns the unwrapped object when present.
+ * @pre payload is a JSON-decoded API response.
+ */
+
+// --- _extract_created_id (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Extracts object ID from create/update API response.
+ * @post Returns integer object ID or None if missing.
+ * @pre payload is a JSON-decoded API response.
+ */
+
+// --- _generate_unique_name (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Generates globally unique random names for charts/dashboards.
+ * @post Returns a unique string and stores it in used_names.
+ * @pre used_names is mutable set for collision tracking.
+ */
+
+// --- _resolve_target_envs (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Resolves requested environment IDs from configuration.
+ * @post Returns mapping env_id -> configured environment object.
+ * @pre env_ids is non-empty.
+ */
+
+// --- _build_chart_template_pool (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Builds a pool of source chart templates to clone in one environment.
+ * @post Returns non-empty list of chart payload templates.
+ * @pre Client is authenticated.
+ */
+
+// --- seed_superset_load_data (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Creates dashboards and cloned charts for load testing across target environments.
+ * @post Returns execution statistics dictionary.
+ * @pre Target environments must be reachable and authenticated.
+ */
+
+// --- main (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief CLI entrypoint for Superset load-test data seeding.
+ * @post Prints summary and exits with non-zero status on failure.
+ * @pre Command line arguments are valid.
+ */
+
+// --- test_dataset_dashboard_relations_script (backend/src/scripts/test_dataset_dashboard_relations.py)
+/**!
+ * @brief Tests and inspects dataset-to-dashboard relationship responses from Superset API.
+ */
+
+// --- services (backend/src/services/__init__.py)
+/**!
+ * @brief Package initialization for services module
+ * @note GitService, AuthService, LLMProviderService have circular import issues - import directly when needed
+ */
+
+// --- auth_service (backend/src/services/auth_service.py)
+/**!
+ * @brief Orchestrates credential authentication and ADFS JIT user provisioning.
+ * @invariant Authentication succeeds only for active users with valid credentials; issued sessions encode subject and scopes from assigned roles.
+ * @post User identity verified and session tokens issued according to role scopes.
+ * @pre Core auth models and security utilities available.
+ */
+
+// --- AuthService (backend/src/services/auth_service.py)
+/**!
+ * @brief Provides high-level authentication services.
+ */
+
+// --- CleanReleaseContracts (backend/src/services/clean_release/__init__.py)
+/**!
+ * @brief Publish the canonical semantic root for the clean-release backend service cluster.
+ */
+
+// --- ApprovalService (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Enforce approval/rejection gates over immutable compliance reports.
+ * @invariant Approval is allowed only for PASSED report bound to candidate; decisions are append-only.
+ * @post Approval decision appended; candidate lifecycle advanced
+ * @pre Report with PASSED final_status exists for candidate
+ */
+
+// --- _get_or_init_decisions_store (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Provide append-only in-memory storage for approval decisions.
+ * @post Returns mutable decision list attached to repository.
+ * @pre repository is initialized.
+ */
+
+// --- _latest_decision_for_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Resolve latest approval decision for candidate from append-only store.
+ * @post Returns latest ApprovalDecision or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- _resolve_candidate_and_report (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Validate candidate/report existence and ownership prior to decision persistence.
+ * @post Returns tuple(candidate, report); raises ApprovalGateError on contract violation.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- approve_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Persist immutable APPROVED decision and advance candidate lifecycle to APPROVED.
+ * @post Approval decision is appended and candidate transitions to APPROVED.
+ * @pre Candidate exists, report belongs to candidate, report final_status is PASSED, candidate not already APPROVED.
+ */
+
+// --- reject_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Persist immutable REJECTED decision without promoting candidate lifecycle.
+ * @post Rejected decision is appended; candidate lifecycle is unchanged.
+ * @pre Candidate exists and report belongs to candidate.
+ */
+
+// --- ArtifactCatalogLoader (backend/src/services/clean_release/artifact_catalog_loader.py)
+/**!
+ * @brief Load bootstrap artifact catalogs for clean release real-mode flows.
+ * @invariant Artifact catalog must produce deterministic CandidateArtifact entries with required identity and checksum fields.
+ */
+
+// --- load_bootstrap_artifacts (backend/src/services/clean_release/artifact_catalog_loader.py)
+/**!
+ * @brief Parse artifact catalog JSON into CandidateArtifact models for TUI/bootstrap flows.
+ * @post Returns non-mutated CandidateArtifact models with required fields populated.
+ * @pre path points to readable JSON file; payload is list[artifact] or {"artifacts": list[artifact]}.
+ */
+
+// --- AuditService (backend/src/services/clean_release/audit_service.py)
+/**!
+ * @brief Provide lightweight audit hooks for clean release preparation/check/report lifecycle.
+ * @invariant Audit hooks are append-only log actions.
+ * @post Audit events appended to log
+ * @pre Logger configured
+ */
+
+// --- candidate_service (backend/src/services/clean_release/candidate_service.py)
+/**!
+ * @brief Register release candidates with validated artifacts and advance lifecycle through legal transitions.
+ * @invariant Candidate lifecycle transitions are delegated to domain guard logic.
+ * @post candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.
+ * @pre candidate_id must be unique; artifacts input must be non-empty and valid.
+ */
+
+// --- _validate_artifacts (backend/src/services/clean_release/candidate_service.py)
+/**!
+ * @brief Validate raw artifact payload list for required fields and shape.
+ * @post Returns normalized artifact list or raises ValueError.
+ * @pre artifacts payload is provided by caller.
+ */
+
+// --- ComplianceExecutionService (backend/src/services/clean_release/compliance_execution_service.py)
+/**!
+ * @brief Create and execute compliance runs with trusted snapshots, deterministic stages, violations and immutable report persistence.
+ * @invariant A run binds to exactly one candidate/manifest/policy/registry snapshot set.
+ * @post Candidate-scoped compliance runs persist stage evidence, terminal status, and immutable report artifacts when execution succeeds.
+ * @pre Repository adapters, trusted policy resolution, and deterministic stage implementations are available for the run request.
+ */
+
+// --- ComplianceExecutionResult (backend/src/services/clean_release/compliance_execution_service.py)
+/**!
+ * @brief Return envelope for compliance execution with run/report and persisted stage artifacts.
+ */
+
+// --- ComplianceOrchestrator (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Execute mandatory clean compliance stages and produce final COMPLIANT/BLOCKED/FAILED outcome.
+ * @invariant COMPLIANT is impossible when any mandatory stage fails.
+ * @post OrchestrationResult with compliance status
+ * @pre ManifestService and PolicyEngine are available
+ */
+
+// --- CleanComplianceOrchestrator (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Coordinate clean-release compliance verification stages.
+ */
+
+// --- run_check_legacy (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Legacy wrapper for compatibility with previous orchestrator call style.
+ * @post Returns finalized ComplianceRun produced by orchestrator start->execute->finalize sequence.
+ * @pre repository and identifiers are valid and resolvable by orchestrator dependencies.
+ */
+
+// --- DemoDataService (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Provide deterministic namespace helpers and isolated in-memory repository creation for demo and real modes.
+ * @invariant Demo and real namespaces must never collide for generated physical identifiers.
+ */
+
+// --- resolve_namespace (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Resolve canonical clean-release namespace for requested mode.
+ * @post Returns deterministic namespace key for demo/real separation.
+ * @pre mode is a non-empty string identifying runtime mode.
+ */
+
+// --- build_namespaced_id (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Build storage-safe physical identifier under mode namespace.
+ * @post Returns deterministic "{namespace}::{logical_id}" identifier.
+ * @pre namespace and logical_id are non-empty strings.
+ */
+
+// --- create_isolated_repository (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Create isolated in-memory repository instance for selected mode namespace.
+ * @post Returns repository instance tagged with namespace metadata.
+ * @pre mode is a valid runtime mode marker.
+ */
+
+// --- clean_release_dto (backend/src/services/clean_release/dto.py)
+/**!
+ * @brief Data Transfer Objects for clean release compliance subsystem.
+ */
+
+// --- clean_release_enums (backend/src/services/clean_release/enums.py)
+/**!
+ * @brief Canonical enums for clean release lifecycle and compliance.
+ */
+
+// --- clean_release_exceptions (backend/src/services/clean_release/exceptions.py)
+/**!
+ * @brief Domain exceptions for clean release compliance subsystem.
+ */
+
+// --- clean_release_facade (backend/src/services/clean_release/facade.py)
+/**!
+ * @brief Unified entry point for clean release operations.
+ */
+
+// --- ManifestBuilder (backend/src/services/clean_release/manifest_builder.py)
+/**!
+ * @brief Build deterministic distribution manifest from classified artifact input.
+ * @invariant Equal semantic artifact sets produce identical deterministic hash values.
+ */
+
+// --- build_distribution_manifest (backend/src/services/clean_release/manifest_builder.py)
+/**!
+ * @brief Build DistributionManifest with deterministic hash and validated counters.
+ * @post Returns DistributionManifest with summary counts matching items cardinality.
+ * @pre artifacts list contains normalized classification values.
+ */
+
+// --- ManifestService (backend/src/services/clean_release/manifest_service.py)
+/**!
+ * @brief Build immutable distribution manifests with deterministic digest and version increment.
+ * @invariant Existing manifests are never mutated.
+ * @post New immutable manifest is persisted with incremented version and deterministic digest.
+ * @pre Candidate exists and is PREPARED or MANIFEST_BUILT; artifacts are present.
+ */
+
+// --- build_manifest_snapshot (backend/src/services/clean_release/manifest_service.py)
+/**!
+ * @brief Create a new immutable manifest version for a candidate.
+ * @post Returns persisted DistributionManifest with monotonically incremented version.
+ * @pre Candidate is prepared, artifacts are available, candidate_id is valid.
+ */
+
+// --- clean_release_mappers (backend/src/services/clean_release/mappers.py)
+/**!
+ * @brief Map between domain entities (SQLAlchemy models) and DTOs.
+ */
+
+// --- PolicyEngine (backend/src/services/clean_release/policy_engine.py)
+/**!
+ * @brief Evaluate artifact/source policies for enterprise clean profile with deterministic outcomes.
+ * @invariant Enterprise-clean policy always treats non-registry sources as violations.
+ * @post PolicyDecision returned with approval status
+ * @pre PolicyRepository is accessible
+ */
+
+// --- CleanPolicyEngine (backend/src/services/clean_release/policy_engine.py)
+/**!
+ * @post Deterministic classification and source validation are available.
+ * @pre Active policy exists and is internally consistent.
+ */
+
+// --- PolicyResolutionService (backend/src/services/clean_release/policy_resolution_service.py)
+/**!
+ * @brief Resolve trusted policy and registry snapshots from ConfigManager without runtime overrides.
+ * @invariant Trusted snapshot resolution is based only on ConfigManager active identifiers.
+ * @post ResolutionResult with matched policies
+ * @pre PolicyRepository and Manifest are available
+ */
+
+// --- resolve_trusted_policy_snapshots (backend/src/services/clean_release/policy_resolution_service.py)
+/**!
+ * @brief Resolve immutable trusted policy and registry snapshots using active config IDs only.
+ * @post Returns immutable policy and registry snapshots; runtime override attempts are rejected.
+ * @pre ConfigManager provides active_policy_id and active_registry_id; repository contains referenced snapshots.
+ */
+
+// --- PreparationService (backend/src/services/clean_release/preparation_service.py)
+/**!
+ * @brief Prepare release candidate by policy evaluation and deterministic manifest creation.
+ * @invariant Candidate preparation always persists manifest and candidate status deterministically.
+ */
+
+// --- prepare_candidate_legacy (backend/src/services/clean_release/preparation_service.py)
+/**!
+ * @brief Legacy compatibility wrapper kept for migration period.
+ * @post Delegates to canonical prepare_candidate and preserves response shape.
+ * @pre Same as prepare_candidate.
+ */
+
+// --- PublicationService (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Enforce publication and revocation gates with append-only publication records.
+ * @invariant Publication records are append-only snapshots; revoke mutates only publication status for targeted record.
+ */
+
+// --- _get_or_init_publications_store (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Provide in-memory append-only publication storage.
+ * @post Returns publication list attached to repository.
+ * @pre repository is initialized.
+ */
+
+// --- _latest_publication_for_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Resolve latest publication record for candidate.
+ * @post Returns latest record or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- _latest_approval_for_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Resolve latest approval decision from repository decision store.
+ * @post Returns latest decision object or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- publish_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Create immutable publication record for approved candidate.
+ * @post New ACTIVE publication record is appended.
+ * @pre Candidate exists, report belongs to candidate, latest approval is APPROVED.
+ */
+
+// --- revoke_publication (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Revoke existing publication record without deleting history.
+ * @post Target publication status becomes REVOKED and updated record is returned.
+ * @pre publication_id exists in repository publication store.
+ */
+
+// --- ReportBuilder (backend/src/services/clean_release/report_builder.py)
+/**!
+ * @brief Build and persist compliance reports with consistent counter invariants.
+ * @invariant blocking_violations_count never exceeds violations_count.
+ * @post Returns immutable report payloads with consistent violation counters and operator summary content.
+ * @pre Compliance run is terminal and repository persistence is available for report storage.
+ */
+
+// --- clean_release_repositories (backend/src/services/clean_release/repositories/__init__.py)
+/**!
+ * @brief Export all clean release repositories.
+ */
+
+// --- approval_repository (backend/src/services/clean_release/repositories/approval_repository.py)
+/**!
+ * @brief Persist and query approval decisions.
+ */
+
+// --- artifact_repository (backend/src/services/clean_release/repositories/artifact_repository.py)
+/**!
+ * @brief Persist and query candidate artifacts.
+ */
+
+// --- audit_repository (backend/src/services/clean_release/repositories/audit_repository.py)
+/**!
+ * @brief Persist and query audit logs for clean release operations.
+ */
+
+// --- candidate_repository (backend/src/services/clean_release/repositories/candidate_repository.py)
+/**!
+ * @brief Persist and query release candidates.
+ */
+
+// --- compliance_repository (backend/src/services/clean_release/repositories/compliance_repository.py)
+/**!
+ * @brief Persist and query compliance runs, stage runs, and violations.
+ */
+
+// --- ManifestRepositoryModule (backend/src/services/clean_release/repositories/manifest_repository.py)
+/**!
+ * @brief Persist and query distribution manifests.
+ */
+
+// --- ManifestRepository (backend/src/services/clean_release/repositories/manifest_repository.py)
+/**!
+ * @brief Encapsulates database CRUD operations for DistributionManifest entities.
+ */
+
+// --- policy_repository (backend/src/services/clean_release/repositories/policy_repository.py)
+/**!
+ * @brief Persist and query policy and registry snapshots.
+ */
+
+// --- publication_repository (backend/src/services/clean_release/repositories/publication_repository.py)
+/**!
+ * @brief Persist and query publication records.
+ */
+
+// --- report_repository (backend/src/services/clean_release/repositories/report_repository.py)
+/**!
+ * @brief Persist and query compliance reports.
+ */
+
+// --- RepositoryRelations (backend/src/services/clean_release/repository.py)
+/**!
+ * @brief Provide repository adapter for clean release entities with deterministic access methods.
+ * @invariant Repository operations are side-effect free outside explicit save/update calls.
+ * @post Repository operations exported
+ * @pre In-memory storage initialized
+ */
+
+// --- CleanReleaseRepository (backend/src/services/clean_release/repository.py)
+/**!
+ * @brief Data access object for clean release lifecycle.
+ */
+
+// --- SourceIsolation (backend/src/services/clean_release/source_isolation.py)
+/**!
+ * @brief Validate that all resource endpoints belong to the approved internal source registry.
+ * @invariant Any endpoint outside enabled registry entries is treated as external-source violation.
+ * @post Source isolation violations identified
+ * @pre Source registry configured
+ */
+
+// --- ComplianceStages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Define compliance stage order and helper functions for deterministic run-state evaluation.
+ * @invariant Stage order remains deterministic for all compliance runs.
+ */
+
+// --- build_default_stages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Build default deterministic stage pipeline implementation order.
+ * @post Returns stage instances in mandatory execution order.
+ * @pre None.
+ */
+
+// --- stage_result_map (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Convert stage result list to dictionary by stage name.
+ * @post Returns stage->status dictionary for downstream evaluation.
+ * @pre stage_results may be empty or contain unique stage names.
+ */
+
+// --- missing_mandatory_stages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Identify mandatory stages that are absent from run results.
+ * @post Returns ordered list of missing mandatory stages.
+ * @pre stage_status_map contains zero or more known stage statuses.
+ */
+
+// --- derive_final_status (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Derive final run status from stage results with deterministic blocking behavior.
+ * @post Returns one of PASSED/BLOCKED/ERROR according to mandatory stage outcomes.
+ * @pre Stage statuses correspond to compliance checks.
+ */
+
+// --- ComplianceStageBase (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Define shared contracts and helpers for pluggable clean-release compliance stages.
+ * @invariant Stage execution is deterministic for equal input context.
+ */
+
+// --- ComplianceStageContext (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Immutable input envelope passed to each compliance stage.
+ */
+
+// --- StageExecutionResult (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Structured stage output containing decision, details and violations.
+ */
+
+// --- ComplianceStage (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Protocol for pluggable stage implementations.
+ */
+
+// --- build_stage_run_record (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Build persisted stage run record from stage result.
+ * @post Returns ComplianceStageRun with deterministic identifiers and timestamps.
+ * @pre run_id and stage_name are non-empty.
+ */
+
+// --- build_violation (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Construct a compliance violation with normalized defaults.
+ * @post Returns immutable-style violation payload ready for persistence.
+ * @pre run_id, stage_name, code and message are non-empty.
+ */
+
+// --- data_purity (backend/src/services/clean_release/stages/data_purity.py)
+/**!
+ * @brief Evaluate manifest purity counters and emit blocking violations for prohibited artifacts.
+ * @invariant prohibited_detected_count > 0 always yields BLOCKED stage decision.
+ */
+
+// --- DataPurityStage (backend/src/services/clean_release/stages/data_purity.py)
+/**!
+ * @brief Validate manifest summary for prohibited artifacts.
+ * @post Returns PASSED when no prohibited artifacts are detected, otherwise BLOCKED with violations.
+ * @pre context.manifest.content_json contains summary block or defaults to safe counters.
+ */
+
+// --- internal_sources_only (backend/src/services/clean_release/stages/internal_sources_only.py)
+/**!
+ * @brief Verify manifest-declared sources belong to trusted internal registry allowlist.
+ * @invariant Any source host outside allowed_hosts yields BLOCKED decision with at least one violation.
+ */
+
+// --- InternalSourcesOnlyStage (backend/src/services/clean_release/stages/internal_sources_only.py)
+/**!
+ * @brief Enforce internal-source-only policy from trusted registry snapshot.
+ * @post Returns PASSED when all hosts are allowed; otherwise BLOCKED and violations captured.
+ * @pre context.registry.allowed_hosts is available.
+ */
+
+// --- manifest_consistency (backend/src/services/clean_release/stages/manifest_consistency.py)
+/**!
+ * @brief Ensure run is bound to the exact manifest snapshot and digest used at run creation time.
+ * @invariant Digest mismatch between run and manifest yields ERROR with blocking violation evidence.
+ */
+
+// --- ManifestConsistencyStage (backend/src/services/clean_release/stages/manifest_consistency.py)
+/**!
+ * @brief Validate run/manifest linkage consistency.
+ * @post Returns PASSED when digests match, otherwise ERROR with one violation.
+ * @pre context.run and context.manifest are loaded from repository for same run.
+ */
+
+// --- no_external_endpoints (backend/src/services/clean_release/stages/no_external_endpoints.py)
+/**!
+ * @brief Block manifest payloads that expose external endpoints outside trusted schemes and hosts.
+ * @invariant Endpoint outside allowed scheme/host always yields BLOCKED stage decision.
+ */
+
+// --- NoExternalEndpointsStage (backend/src/services/clean_release/stages/no_external_endpoints.py)
+/**!
+ * @brief Validate endpoint references from manifest against trusted registry.
+ * @post Returns PASSED when all endpoints are trusted, otherwise BLOCKED with endpoint violations.
+ * @pre context.registry includes allowed hosts and schemes.
+ */
+
+// --- dataset_review (backend/src/services/dataset_review/__init__.py)
+/**!
+ * @brief Provides services for dataset-centered orchestration flow.
+ */
+
+// --- ClarificationEngine (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Manage one-question-at-a-time clarification state, deterministic answer persistence, and readiness/finding updates.
+ * @invariant Only one active clarification question may exist at a time; skipped and expert-review items remain unresolved and visible.
+ * @post Active clarification payload exposes one highest-priority unresolved question, and each recorded answer is persisted before pointer/readiness mutation.
+ * @pre Target session contains a persisted clarification aggregate in the current ownership scope.
+ */
+
+// --- ClarificationQuestionPayload (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Typed active-question payload returned to the API layer.
+ */
+
+// --- ClarificationStateResult (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Clarification state result carrying the current session, active payload, and changed findings.
+ */
+
+// --- ClarificationAnswerCommand (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Typed answer command for clarification state mutation.
+ */
+
+// --- ClarificationHelpers (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Pure helper functions for clarification engine — question selection, counting, normalization, finding upsert, and readiness derivation.
+ */
+
+// --- select_next_open_question (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Select the next unresolved question in deterministic priority order.
+ */
+
+// --- count_resolved_questions (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Count questions whose answers fully resolved the ambiguity.
+ */
+
+// --- count_remaining_questions (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Count questions still unresolved or deferred after clarification interaction.
+ */
+
+// --- normalize_answer_value (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Validate and normalize answer payload based on answer kind and active question options.
+ */
+
+// --- build_impact_summary (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Build a compact audit note describing how the clarification answer affects session state.
+ */
+
+// --- upsert_clarification_finding (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Keep one finding per clarification topic aligned with answer outcome and unresolved visibility rules.
+ */
+
+// --- derive_readiness_state (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Recompute readiness after clarification mutation while preserving unresolved visibility semantics.
+ */
+
+// --- derive_recommended_action (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Recompute next-action guidance after clarification mutations.
+ */
+
+// --- SessionEventLoggerModule (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Persist explicit session mutation events for dataset-review audit trails without weakening ownership or approval invariants.
+ * @post Every logged event is committed as an explicit, queryable audit record with deterministic event metadata.
+ * @pre Caller provides an owned session scope and an authenticated actor identifier for each persisted mutation event.
+ */
+
+// --- SessionEventLoggerImports (backend/src/services/dataset_review/event_logger.py)
+/**!
+ */
+
+// --- SessionEventPayload (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Typed input contract for one persisted dataset-review session audit event.
+ */
+
+// --- SessionEventLogger (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Persist explicit dataset-review session audit events with meaningful runtime reasoning logs.
+ * @post Returns the committed session event row with a stable identifier and stored detail payload.
+ * @pre The database session is live and payload identifiers are non-empty.
+ */
+
+// --- DatasetReviewOrchestrator (backend/src/services/dataset_review/orchestrator.py)
+/**!
+ * @brief Coordinate dataset review session startup and lifecycle-safe intake recovery for one authenticated user.
+ * @invariant Launch is blocked unless a current session has no open blocking findings, all launch-sensitive mappings are approved, and a non-stale Superset-generated compiled preview matches the current input fingerprint.
+ * @post state transitions are persisted atomically and emit observable progress for long-running steps.
+ * @pre session mutations must execute inside a persisted session boundary scoped to one authenticated user.
+ */
+
+// --- OrchestratorCommands (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed command and result dataclasses for dataset review orchestration boundary.
+ */
+
+// --- StartSessionCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for starting a dataset review session.
+ */
+
+// --- StartSessionResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Session-start result carrying the persisted session and intake recovery metadata.
+ */
+
+// --- PreparePreviewCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for compiling one Superset-backed session preview.
+ */
+
+// --- PreparePreviewResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Result contract for one persisted compiled preview attempt.
+ */
+
+// --- LaunchDatasetCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for launching one dataset-review session into SQL Lab.
+ */
+
+// --- LaunchDatasetResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Launch result carrying immutable run context and any gate blockers.
+ */
+
+// --- OrchestratorHelpers (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Pure helper methods extracted from DatasetReviewOrchestrator for INV_7 compliance — snapshot, blockers, fingerprint, recovery bootstrap.
+ * @post Helper results are deterministic and do not mutate persistence directly.
+ * @pre Caller provides a loaded session aggregate with hydrated child collections.
+ */
+
+// --- parse_dataset_selection (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Normalize dataset-selection payload into canonical session references.
+ */
+
+// --- build_initial_profile (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Create the first profile snapshot so exports and detail views remain usable immediately after intake.
+ */
+
+// --- build_partial_recovery_findings (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Project partial Superset intake recovery into explicit findings without blocking session usability.
+ * @post Returns warning-level findings that preserve usable but incomplete state.
+ * @pre parsed_context.partial_recovery is true.
+ */
+
+// --- extract_effective_filter_value (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Separate normalized filter payload metadata from the user-facing effective filter value.
+ */
+
+// --- build_execution_snapshot (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Build effective filters, template params, approvals, and fingerprint for preview and launch gating.
+ * @post Returns deterministic execution snapshot for current session state without mutating persistence.
+ * @pre Session aggregate includes imported filters, template variables, and current execution mappings.
+ */
+
+// --- build_launch_blockers (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Enforce launch gates from findings, approvals, and current preview truth.
+ * @post Returns explicit blocker codes for every unmet launch invariant.
+ * @pre execution_snapshot was computed from current session state.
+ */
+
+// --- get_latest_preview (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Resolve the current latest preview snapshot for one session aggregate.
+ */
+
+// --- compute_preview_fingerprint (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Produce deterministic execution fingerprint for preview truth and staleness checks.
+ */
+
+// --- SessionRepositoryMutations (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persistence mutation operations for dataset review session aggregates — profile/findings, recovery state, preview, run context.
+ * @post Session aggregate writes preserve ownership and version semantics.
+ * @pre All mutations execute within authenticated request or task scope.
+ */
+
+// --- save_profile_and_findings (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist profile state and replace validation findings for an owned session in one transaction.
+ * @post stored profile matches the current session and findings are replaced by the supplied collection.
+ * @pre session_id belongs to user_id and the supplied profile/findings belong to the same aggregate scope.
+ */
+
+// --- save_recovery_state (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist imported filters, template variables, and initial execution mappings for one owned session.
+ * @post Recovery state persisted to database.
+ * @pre session_id belongs to user_id.
+ */
+
+// --- save_preview (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist a preview snapshot and mark prior session previews stale.
+ * @post preview is persisted and the session points to the latest preview identifier.
+ * @pre session_id belongs to user_id and preview is prepared for the same session aggregate.
+ */
+
+// --- save_run_context (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist an immutable launch audit snapshot for an owned session.
+ * @post run context is persisted and linked as the latest launch snapshot for the session.
+ * @pre session_id belongs to user_id and run_context targets the same aggregate.
+ */
+
+// --- DatasetReviewSessionRepository (backend/src/services/dataset_review/repositories/session_repository.py)
+/**!
+ * @brief Persist and retrieve dataset review session aggregates, including readiness, findings, semantic decisions, clarification state, previews, and run contexts.
+ * @invariant answers, mapping approvals, preview artifacts, and launch snapshots are never attributed to the wrong user or session.
+ * @post session aggregate reads are structurally consistent and writes preserve ownership and version semantics.
+ * @pre repository operations execute within authenticated request or task scope.
+ */
+
+// --- DatasetReviewSessionVersionConflictError (backend/src/services/dataset_review/repositories/session_repository.py)
+/**!
+ * @brief Signal optimistic-lock conflicts for dataset review session mutations.
+ */
+
+// --- SemanticSourceResolver (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ * @brief Resolve and rank semantic candidates from trusted dictionary-like sources before any inferred fallback.
+ * @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+ * @post candidate ranking follows the configured confidence hierarchy and unresolved fuzzy matches remain reviewable.
+ * @pre selected source and target field set must be known.
+ */
+
+// --- imports (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ */
+
+// --- DictionaryResolutionResult (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ * @brief Carries field-level dictionary resolution output with explicit review and partial-recovery state.
+ */
+
+// --- GitServiceModule (backend/src/services/git/__init__.py)
+/**!
+ * @brief Composed GitService via multiple inheritance from domain-specific mixins.
+ */
+
+// --- GitService (backend/src/services/git/__init__.py)
+/**!
+ * @brief Composed GitService class providing all Git operations — init, clone, branches, commits, push, pull,
+ */
+
+// --- GitServiceBase (backend/src/services/git/_base.py)
+/**!
+ * @brief Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool.
+ */
+
+// --- GitServiceBranchMixin (backend/src/services/git/_branch.py)
+/**!
+ * @brief Branch and commit operations for GitService — gitflow branches, list/create/checkout branches, commit changes (all concurrent-safe via per-dashboard locks).
+ */
+
+// --- GitServiceGiteaMixin (backend/src/services/git/_gitea.py)
+/**!
+ * @brief Gitea API operations for GitService — connection testing, repository CRUD, and pull request creation. Uses shared self._http_client for connection pooling.
+ */
+
+// --- GitServiceMergeMixin (backend/src/services/git/_merge.py)
+/**!
+ * @brief Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks).
+ */
+
+// --- GitServiceRemoteMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief GitHub and GitLab provider operations for GitService — repository creation and PR/MR creation. Uses shared self._http_client for connection pooling.
+ */
+
+// --- GitServiceGithubMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief Mixin providing GitHub API operations for GitService.
+ */
+
+// --- GitServiceGitlabMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief Mixin providing GitLab API operations for GitService.
+ */
+
+// --- GitServiceStatusMixin (backend/src/services/git/_status.py)
+/**!
+ * @brief Status, diff, and commit history operations for GitService (all concurrent-safe via per-dashboard locks).
+ */
+
+// --- GitServiceSyncMixin (backend/src/services/git/_sync.py)
+/**!
+ * @brief Push and pull operations for GitService with origin host auto-alignment (concurrent-safe).
+ */
+
+// --- GitServiceUrlMixin (backend/src/services/git/_url.py)
+/**!
+ * @brief URL helper mixin for GitService — parse, normalize, align, and strip credentials from Git URLs.
+ */
+
+// --- health_service (backend/src/services/health_service.py)
+/**!
+ * @brief Business logic for aggregating dashboard health status from validation records.
+ */
+
+// --- HealthService (backend/src/services/health_service.py)
+/**!
+ * @brief Aggregate latest dashboard validation state and manage persisted health report lifecycle.
+ * @post Exposes health summary aggregation and validation report deletion operations.
+ * @pre Service is constructed with a live SQLAlchemy session and optional config manager.
+ */
+
+// --- llm_prompt_templates (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Provide default LLM prompt templates and normalization helpers for runtime usage.
+ * @invariant All required prompt template keys are always present after normalization.
+ */
+
+// --- DEFAULT_LLM_PROMPTS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default prompt templates used by documentation, dashboard validation, and git commit generation.
+ */
+
+// --- DEFAULT_LLM_PROVIDER_BINDINGS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default provider binding per task domain.
+ */
+
+// --- DEFAULT_LLM_ASSISTANT_SETTINGS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default planner settings for assistant chat intent model/provider resolution.
+ */
+
+// --- normalize_llm_settings (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Ensure llm settings contain stable schema with prompts section and default templates.
+ * @post Returned dict contains prompts with all required template keys.
+ * @pre llm_settings is dictionary-like value or None.
+ */
+
+// --- is_multimodal_model (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Heuristically determine whether model supports image input required for dashboard validation.
+ * @deprecated Use the explicit `db_provider.is_multimodal` flag instead (see migration 9f8e7d6c5b4a).
+ */
+
+// --- resolve_bound_provider_id (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Resolve provider id configured for a task binding with fallback to default provider.
+ * @post Returns configured provider id or fallback id/empty string when not defined.
+ * @pre llm_settings is normalized or raw dict from config.
+ */
+
+// --- render_prompt (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Render prompt template using deterministic placeholder replacement with graceful fallback.
+ * @post Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.
+ * @pre template is a string and variables values are already stringifiable.
+ */
+
+// --- llm_provider (backend/src/services/llm_provider.py)
+/**!
+ * @brief Service for managing LLM provider configurations with encrypted API keys.
+ */
+
+// --- mask_api_key (backend/src/services/llm_provider.py)
+/**!
+ * @brief Mask an API key for safe display, showing first 4 and last 4 characters.
+ * @post Returns "****" for very short keys; "{first 2}...{last 2}" for <=8 chars;
+ * @pre api_key is a plaintext string or None.
+ */
+
+// --- is_masked_or_placeholder (backend/src/services/llm_provider.py)
+/**!
+ * @brief Predicate: True when api_key is None, empty, "********", or contains "...".
+ * @post Returns True only for non-real-key values.
+ * @pre api_key can be None.
+ */
+
+// --- _require_fernet_key (backend/src/services/llm_provider.py)
+/**!
+ * @brief Load and validate the Fernet key used for secret encryption.
+ * @invariant Encryption initialization never falls back to a hardcoded secret.
+ * @post Returns validated key bytes ready for Fernet initialization.
+ * @pre ENCRYPTION_KEY environment variable must be set to a valid Fernet key.
+ */
+
+// --- EncryptionManager (backend/src/services/llm_provider.py)
+/**!
+ * @brief Handles encryption and decryption of sensitive data like API keys.
+ * @invariant Uses only a validated secret key from environment.
+ * @post Manager exposes reversible encrypt/decrypt operations for persisted secrets.
+ * @pre ENCRYPTION_KEY is configured with a valid Fernet key before instantiation.
+ */
+
+// --- LLMProviderService (backend/src/services/llm_provider.py)
+/**!
+ * @brief Service to manage LLM provider lifecycle.
+ */
+
+// --- MaintenancePackage (backend/src/services/maintenance/__init__.py)
+/**!
+ * @brief Maintenance Banner service package. Re-exports all public orchestrators and helpers.
+ */
+
+// --- MaintenanceBannerRenderer (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Banner text rendering and rebuild helpers. Build aggregated markdown from
+ */
+
+// --- build_banner_text (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Build aggregated banner markdown text from events using settings template.
+ */
+
+// --- _build_banner_text_for_dashboard (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Build aggregated banner text for a banner based on all active events linked to it.
+ */
+
+// --- rebuild_banner (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Rebuild aggregated banner text for a banner and update the Superset chart.
+ */
+
+// --- MaintenanceChartManager (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Chart operations for maintenance banners: create/get banner charts, process
+ */
+
+// --- ensure_banner_chart (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Get or create a MaintenanceDashboardBanner for a dashboard in the target environment.
+ */
+
+// --- _process_dashboards_for_start (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Process each dashboard for a start maintenance event: ensure banner chart,
+ */
+
+// --- _process_states_for_end (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Process each dashboard state for an end maintenance event: if other events
+ */
+
+// --- MaintenanceDashboardScanner (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Dashboard discovery and filtering helpers for maintenance banner feature.
+ */
+
+// --- find_affected_dashboards (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Find all dashboard IDs whose datasets reference any of the given tables.
+ */
+
+// --- _get_linked_dashboards (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Fetch linked dashboards for a dataset from Superset.
+ */
+
+// --- _apply_dashboard_filters (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Apply scope (published/draft/all), excluded, and forced filters from settings.
+ */
+
+// --- _resolve_dashboard_title (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Resolve dashboard title from Superset by ID.
+ */
+
+// --- MaintenanceOrchestrators (backend/src/services/maintenance/_orchestrators.py)
+/**!
+ * @brief C4 orchestrators for maintenance event lifecycle: start, end, end-all.
+ */
+
+// --- build_idempotency_key (backend/src/services/maintenance/_orchestrators.py)
+/**!
+ * @brief Build idempotency key from (tables, start_time, end_time). Sorted lowercased tables, ISO timestamps.
+ * @post Returns a tuple of (frozenset(str), str|None, str|None) for DB comparison.
+ * @pre tables is a list of strings. start_time is a datetime or None. end_time is a datetime or None.
+ */
+
+// --- mapping_service (backend/src/services/mapping_service.py)
+/**!
+ * @brief Orchestrates database fetching and fuzzy matching suggestions.
+ * @invariant Suggestions are based on database names.
+ * @post Exposes stateless mapping suggestion orchestration over configured environments.
+ * @pre source/target environment identifiers are provided by caller.
+ */
+
+// --- MappingService (backend/src/services/mapping_service.py)
+/**!
+ * @brief Service for handling database mapping logic.
+ * @post Provides client resolution and mapping suggestion methods.
+ * @pre config_manager exposes get_environments() with environment objects containing id.
+ */
+
+// --- notifications (backend/src/services/notifications/__init__.py)
+/**!
+ * @brief Notification service package root.
+ */
+
+// --- providers (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Defines abstract base and concrete implementations for external notification delivery.
+ * @invariant Sensitive credentials must be handled via encrypted config.
+ * @post Each provider exposes async send contract returning boolean delivery outcome.
+ * @pre Provider configuration dictionaries are supplied by trusted configuration sources.
+ */
+
+// --- NotificationProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Abstract base class for all notification providers.
+ */
+
+// --- SMTPProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via SMTP.
+ */
+
+// --- TelegramProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via Telegram Bot API.
+ */
+
+// --- SlackProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via Slack Webhooks or API.
+ */
+
+// --- service (backend/src/services/notifications/service.py)
+/**!
+ * @brief Orchestrates notification routing based on user preferences and policy context.
+ * @invariant NotificationService maintains singleton pattern for per-channel notifications
+ * @post Notification dispatched via configured providers
+ * @pre channel_config is loaded
+ */
+
+// --- NotificationService (backend/src/services/notifications/service.py)
+/**!
+ * @brief Routes validation reports to appropriate users and channels.
+ * @post Service can resolve targets and dispatch provider sends without mutating validation records.
+ * @pre Service receives a live DB session and configuration manager with notification payload settings.
+ */
+
+// --- profile_preference_service (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Profile preference persistence — read, update, and normalize user dashboard filter preferences
+ */
+
+// --- ProfilePreferenceService (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Handles profile preference persistence, validation, and token encryption.
+ * @post Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.
+ * @pre db session is active.
+ */
+
+// --- get_my_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return current user's persisted preference or default non-configured view.
+ * @post Returned payload belongs to current_user only.
+ * @pre current_user is authenticated.
+ */
+
+// --- get_dashboard_filter_binding (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return only dashboard-filter fields required by dashboards listing hot path.
+ * @post Returns normalized username and profile-default filter toggles without security summary expansion.
+ * @pre current_user is authenticated.
+ */
+
+// --- update_my_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Validate and persist current user's profile preference in self-scoped mode.
+ * @post Preference row for current_user is created/updated when validation passes.
+ * @pre current_user is authenticated and payload is provided.
+ */
+
+// --- _to_preference_payload (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Map ORM preference row to API DTO with token metadata.
+ * @post Returns normalized ProfilePreference object.
+ * @pre preference row can contain nullable optional fields.
+ */
+
+// --- _build_default_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Delegate to ProfileUtils.build_default_preference.
+ */
+
+// --- _get_preference_row (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return persisted preference row for user or None.
+ */
+
+// --- _get_or_create_preference_row (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return existing preference row or create new unsaved row.
+ */
+
+// --- profile_service (backend/src/services/profile_service.py)
+/**!
+ * @brief Composite facade orchestrating profile preference persistence, Superset account lookup,
+ */
+
+// --- ProfileService (backend/src/services/profile_service.py)
+/**!
+ * @brief Facade that composes ProfilePreferenceService, SupersetLookupService, and
+ */
+
+// --- ProfileUtils (backend/src/services/profile_utils.py)
+/**!
+ * @brief Pure utility helpers for profile data sanitization, normalization, and secret masking.
+ */
+
+// --- ProfileValidationError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Domain validation error for profile preference update requests.
+ */
+
+// --- EnvironmentNotFoundError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Raised when environment_id from lookup request is unknown in app configuration.
+ */
+
+// --- ProfileAuthorizationError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Raised when caller attempts cross-user preference mutation.
+ */
+
+// --- sanitize_text (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize optional text into trimmed form or None.
+ */
+
+// --- sanitize_secret (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize secret input into trimmed form or None.
+ */
+
+// --- sanitize_username (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize raw username into trimmed form or None for empty input.
+ */
+
+// --- normalize_username (backend/src/services/profile_utils.py)
+/**!
+ * @brief Apply deterministic trim+lower normalization for actor matching.
+ */
+
+// --- normalize_start_page (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize supported start page aliases to canonical values.
+ */
+
+// --- normalize_density (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize supported density aliases to canonical values.
+ */
+
+// --- mask_secret_value (backend/src/services/profile_utils.py)
+/**!
+ * @brief Build a safe display value for sensitive secrets.
+ */
+
+// --- validate_update_payload (backend/src/services/profile_utils.py)
+/**!
+ * @brief Validate username/toggle constraints for preference mutation.
+ * @post Returns validation errors list; empty list means valid.
+ */
+
+// --- build_default_preference (backend/src/services/profile_utils.py)
+/**!
+ * @brief Build non-persisted default preference DTO for unconfigured users.
+ */
+
+// --- normalize_owner_tokens (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize owners payload into deduplicated lower-cased tokens.
+ */
+
+// --- rbac_permission_catalog (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Discovers declared RBAC permissions from API routes/plugins and synchronizes them into auth database.
+ */
+
+// --- HAS_PERMISSION_PATTERN (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Regex pattern for extracting has_permission("resource", "ACTION") declarations.
+ */
+
+// --- ROUTES_DIR (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Absolute directory path where API route RBAC declarations are defined.
+ */
+
+// --- _iter_route_files (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Iterates API route files that may contain RBAC declarations.
+ * @post Yields Python files excluding test and cache directories.
+ * @pre ROUTES_DIR points to backend/src/api/routes.
+ */
+
+// --- _discover_route_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Extracts explicit has_permission declarations from API route source code.
+ * @post Returns unique set of (resource, action) pairs declared in route guards.
+ * @pre Route files are readable UTF-8 text files.
+ */
+
+// --- _discover_route_permissions_cached (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Cache route permission discovery because route source files are static during normal runtime.
+ * @post Returns stable discovered route permission pairs without repeated filesystem scans.
+ * @pre None.
+ */
+
+// --- _discover_plugin_execute_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Derives dynamic task permissions of form plugin:{plugin_id}:EXECUTE from plugin registry.
+ * @post Returns unique plugin EXECUTE permissions if loader is available.
+ * @pre plugin_loader is optional and may expose get_all_plugin_configs.
+ */
+
+// --- _discover_plugin_execute_permissions_cached (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Cache dynamic plugin EXECUTE permission pairs by normalized plugin id tuple.
+ * @post Returns stable permission tuple without repeated plugin catalog expansion.
+ * @pre plugin_ids is a deterministic tuple of plugin ids.
+ */
+
+// --- discover_declared_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Builds canonical RBAC permission catalog from routes and plugin registry.
+ * @post Returns union of route-declared and dynamic plugin EXECUTE permissions.
+ * @pre plugin_loader may be provided for dynamic task plugin permission discovery.
+ */
+
+// --- sync_permission_catalog (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Persists missing RBAC permission pairs into auth database.
+ * @post Missing permissions are inserted; existing permissions remain untouched.
+ * @pre declared_permissions is an iterable of (resource, action) tuples.
+ */
+
+// --- reports (backend/src/services/reports/__init__.py)
+/**!
+ * @brief Report service package root.
+ */
+
+// --- normalizer (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Convert task manager task objects into canonical unified TaskReport entities with deterministic fallback behavior.
+ * @invariant Normalizer instance maintains consistent field order
+ * @post Returns Normalizer output with normalized fields
+ * @pre session is active and valid
+ */
+
+// --- status_to_report_status (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Normalize internal task status to canonical report status.
+ * @post Always returns one of canonical ReportStatus values.
+ * @pre status may be known or unknown string/enum value.
+ */
+
+// --- build_summary (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Build deterministic user-facing summary from task payload and status.
+ * @post Returns non-empty summary text.
+ * @pre report_status is canonical; plugin_id may be unknown.
+ */
+
+// --- extract_error_context (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Extract normalized error context and next actions for failed/partial reports.
+ * @post Returns ErrorContext for failed/partial when context exists; otherwise None.
+ * @pre task is a valid Task object.
+ */
+
+// --- normalize_task_report (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Convert one Task to canonical TaskReport envelope.
+ * @post Returns TaskReport with required fields and deterministic fallback behavior.
+ * @pre task has valid id and plugin_id fields.
+ */
+
+// --- report_service (backend/src/services/reports/report_service.py)
+/**!
+ * @brief Aggregate, normalize, filter, and paginate task reports for unified list/detail API use cases.
+ * @invariant ReportService maintains consistent report structure
+ * @post Returns Report with generated summary
+ * @pre session is active and valid
+ */
+
+// --- ReportsService (backend/src/services/reports/report_service.py)
+/**!
+ * @brief Service layer for list/detail report retrieval and normalization.
+ * @invariant Service methods are read-only over task history source.
+ * @post Provides deterministic list/detail report responses.
+ * @pre TaskManager dependency is initialized.
+ */
+
+// --- type_profiles (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Deterministic mapping of plugin/task identifiers to canonical report task types and fallback profile metadata.
+ */
+
+// --- PLUGIN_TO_TASK_TYPE (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Maps plugin identifiers to normalized report task types.
+ */
+
+// --- TASK_TYPE_PROFILES (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Profile metadata registry for each normalized task type.
+ */
+
+// --- resolve_task_type (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Resolve canonical task type from plugin/task identifier with guaranteed fallback.
+ * @post Always returns one of TaskType enum values.
+ * @pre plugin_id may be None or unknown.
+ */
+
+// --- get_type_profile (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Return deterministic profile metadata for a task type.
+ * @post Returns a profile dict and never raises for unknown types.
+ * @pre task_type may be known or unknown.
+ */
+
+// --- ResourceServiceModule (backend/src/services/resource_service.py)
+/**!
+ * @brief Shared service for fetching resource data with Git status and task status
+ * @invariant All resources include metadata about their current state
+ */
+
+// --- ResourceService (backend/src/services/resource_service.py)
+/**!
+ * @brief Provides centralized access to resource data with enhanced metadata
+ */
+
+// --- security_badge_service (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Builds security summary and permission badges for profile UI — role extraction,
+ */
+
+// --- SecurityBadgeService (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Builds security summary with role names and permission badges for profile UI display.
+ * @post build_security_summary returns ProfileSecuritySummary with deterministic sorted permissions.
+ * @pre plugin_loader may be None for degraded permission discovery.
+ */
+
+// --- build_security_summary (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Build read-only security snapshot with role and permission badges.
+ * @post Returns deterministic security projection for profile UI.
+ * @pre current_user is authenticated.
+ */
+
+// --- _collect_user_permission_pairs (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Collect effective permission tuples from current user's roles.
+ * @post Returns unique normalized (resource, ACTION) tuples.
+ * @pre current_user can include role/permission graph.
+ */
+
+// --- _format_permission_key (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Convert normalized permission pair to compact UI key.
+ */
+
+// --- SqlTableExtractorModule (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Three-phase SQL+Jinja table name extractor for virtual datasets as per FR-003.
+ */
+
+// --- detect_jinja_spans (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 1: Split raw SQL text into Jinja spans and SQL spans.
+ * @post Returns a list of (span_type: str, text: str) tuples.
+ * @pre raw_sql is a string (possibly empty).
+ */
+
+// --- extract_tables_from_jinja (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 2: Extract "schema.table" references from Jinja string values.
+ */
+
+// --- is_string_literal (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Check if a sqlparse Token is a string literal (not a schema.table identifier).
+ * @post Returns True if the token is a string/Single/Literal.String.
+ * @pre token is a sqlparse Token.
+ */
+
+// --- extract_tables_from_sql_span (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 3: Extract schema.table references from SQL text using regex + sqlparse filtering.
+ */
+
+// --- extract_tables_from_sql (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Three-phase entry point: extract all schema.table references from raw SQL+Jinja text.
+ * @post Returns a set of lowercased fully-qualified table names (schema.table format).
+ * @pre raw_sql is a string (possibly empty).
+ */
+
+// --- superset_lookup_service (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Environment-scoped Superset account lookup with degradation fallback for network failures.
+ */
+
+// --- SupersetLookupService (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Resolves environments and queries Superset users in selected environment,
+ */
+
+// --- _resolve_environment (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Resolve environment model from configured environments by id.
+ * @post Returns environment object when found else None.
+ * @pre environment_id is provided.
+ */
+
+// --- ValidationRunService (backend/src/services/validation_run_service.py)
+/**!
+ * @brief Business logic for validation run queries: list, detail, delete.
+ */
+
+// --- _resolve_task_name (backend/src/services/validation_run_service.py)
+/**!
+ */
+
+// --- ValidationService (backend/src/services/validation_service.py)
+/**!
+ * @brief Business logic for validation task CRUD and trigger-run.
+ */
+
+// --- ValidationTaskService (backend/src/services/validation_service.py)
+/**!
+ * @brief Validation task (policy) CRUD with provider validation and trigger-run.
+ */
+
+// --- _validate_provider (backend/src/services/validation_service.py)
+/**!
+ */
+
+// --- _validate_environment (backend/src/services/validation_service.py)
+/**!
+ */
+
+// --- _policy_to_response (backend/src/services/validation_service.py)
+/**!
+ */
+
+// --- TestSessionConfig (backend/tests/conftest.py)
+/**!
+ * @brief Shared pytest fixtures and session configuration for backend tests.
+ * @post Database tables exist before test session executes.
+ * @pre All test modules use sys.path patching to import from src/.
+ */
+
+// --- TestArchiveParser (backend/tests/core/migration/test_archive_parser.py)
+/**!
+ * @brief Unit tests for MigrationArchiveParser ZIP extraction contract.
+ */
+
+// --- test_extract_objects_from_zip_collects_all_types (backend/tests/core/migration/test_archive_parser.py)
+/**!
+ * @brief Verify archive parser collects dashboard/chart/dataset YAML objects into typed buckets.
+ */
+
+// --- TestDryRunOrchestrator (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Unit tests for MigrationDryRunService diff and risk computation contracts.
+ */
+
+// --- _load_fixture (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Load canonical migration dry-run fixture payload used by deterministic orchestration assertions.
+ */
+
+// --- test_migration_dry_run_service_builds_diff_and_risk (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Verify dry-run orchestration returns stable diff summary and required risk codes.
+ */
+
+// --- test_git_service_get_repo_path_guard (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_get_repo_path_recreates_base_dir (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_superset_client_import_dashboard_guard (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_init_repo_reclones_when_path_is_not_a_git_repo (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_configure_identity_updates_repo_local_config (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- TestGitServiceGiteaPr (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Validate Gitea PR creation fallback behavior when configured server URL is stale.
+ * @invariant A 404 from primary Gitea URL retries once against remote-url host when different.
+ */
+
+// --- test_derive_server_url_from_remote_strips_credentials (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Ensure helper returns host base URL and removes embedded credentials.
+ * @post Result is scheme+host only.
+ * @pre remote_url is an https URL with username/token.
+ */
+
+// --- test_create_gitea_pull_request_retries_with_remote_host_on_404 (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Verify create_gitea_pull_request retries with remote URL host after primary 404.
+ * @post Method returns success payload from fallback request.
+ * @pre primary server_url differs from remote_url host.
+ */
+
+// --- test_create_gitea_pull_request_returns_branch_error_when_target_missing (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Ensure Gitea 404 on PR creation is mapped to actionable target-branch validation error.
+ * @post Service raises HTTPException 400 with explicit missing target branch message.
+ * @pre PR create call returns 404 and target branch is absent.
+ */
+
+// --- TestMappingService (backend/tests/core/test_mapping_service.py)
+/**!
+ * @brief Unit tests for the IdMappingService matching UUIDs to integer IDs.
+ */
+
+// --- test_sync_environment_upserts_correctly (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_id_returns_integer (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_ids_batch_returns_dict (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_updates_existing_mapping (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_skips_resources_without_uuid (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_handles_api_error_gracefully (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_id_returns_none_for_missing (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_ids_batch_returns_empty_for_empty_input (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_mapping_service_alignment_with_test_data (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_requires_existing_env (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_deletes_stale_mappings (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- TestMigrationEngine (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Unit tests for MigrationEngine's cross-filter patching algorithms.
+ */
+
+// --- MockMappingService (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Deterministic mapping service double for native filter ID remapping scenarios.
+ * @invariant Returns mappings only for requested UUID keys present in seeded map.
+ */
+
+// --- _write_dashboard_yaml (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Serialize dashboard metadata into YAML fixture with json_metadata payload for patch tests.
+ */
+
+// --- test_patch_dashboard_metadata_replaces_chart_ids (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify native filter target chartId values are remapped via mapping service results.
+ */
+
+// --- test_patch_dashboard_metadata_replaces_dataset_ids (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify native filter target datasetId values are remapped via mapping service results.
+ */
+
+// --- test_patch_dashboard_metadata_skips_when_no_metadata (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure dashboard files without json_metadata are left unchanged by metadata patching.
+ */
+
+// --- test_patch_dashboard_metadata_handles_missing_targets (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify patching updates mapped targets while preserving unmapped native filter IDs.
+ */
+
+// --- test_extract_chart_uuids_from_archive (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify chart archive scan returns complete local chart id-to-uuid mapping.
+ */
+
+// --- test_transform_yaml_replaces_database_uuid (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure dataset YAML database_uuid fields are replaced when source UUID mapping exists.
+ */
+
+// --- test_transform_yaml_ignores_unmapped_uuid (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure transform_yaml leaves dataset files untouched when database_uuid is not mapped.
+ */
+
+// --- test_transform_zip_end_to_end (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Validate full ZIP transform pipeline remaps datasets and dashboard cross-filter chart IDs.
+ */
+
+// --- test_transform_zip_invalid_path (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify transform_zip returns False when source archive path does not exist.
+ */
+
+// --- test_transform_yaml_nonexistent_file (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify transform_yaml raises FileNotFoundError for missing YAML source files.
+ */
+
+// --- test_clean_release_cli (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Smoke tests for the redesigned clean release CLI.
+ */
+
+// --- test_cli_candidate_register_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify candidate-register command exits successfully for valid required arguments.
+ */
+
+// --- test_cli_manifest_build_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify candidate-register/artifact-import/manifest-build smoke path succeeds end-to-end.
+ */
+
+// --- test_cli_compliance_run_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify compliance run/status/violations/report commands complete for prepared candidate.
+ * @invariant SimpleNamespace substitutes for GlobalSettings — any field rename in GlobalSettings will silently not propagate here; re-verify on GlobalSettings schema changes.
+ */
+
+// --- test_cli_release_gate_commands_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify approve/reject/publish/revoke release-gate commands execute with valid fixtures.
+ */
+
+// --- TestCleanReleaseTui (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @brief Unit tests for the interactive curses TUI of the clean release process.
+ * @invariant TUI initializes, handles hotkeys (F5, F10) and safely falls back without TTY.
+ */
+
+// --- test_headless_fallback (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_initial_render (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_run_checks_f5 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_exit_f10 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_clear_history_f7 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_real_mode_bootstrap_imports_artifacts_catalog (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_clean_release_tui_v2 (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Smoke tests for thin-client TUI action dispatch and blocked transition behavior.
+ */
+
+// --- _build_mock_stdscr (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Build deterministic curses screen mock with default terminal geometry and exit key.
+ */
+
+// --- test_tui_f5_dispatches_run_action (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify F5 key dispatch invokes run_checks exactly once before graceful exit.
+ */
+
+// --- test_tui_f5_run_smoke_reports_blocked_state (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify blocked compliance state is surfaced after F5-triggered run action.
+ */
+
+// --- test_tui_non_tty_refuses_startup (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify non-TTY execution returns exit code 2 with actionable stderr guidance.
+ */
+
+// --- test_tui_f8_blocked_without_facade_binding (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify F8 path reports disabled action instead of mutating hidden facade state.
+ */
+
+// --- TestApprovalService (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Define approval gate contracts for approve/reject operations over immutable compliance evidence.
+ * @invariant Approval is allowed only for PASSED report bound to candidate; duplicate approve and foreign report must be rejected.
+ */
+
+// --- _seed_candidate_with_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Seed candidate and report fixtures for approval gate tests.
+ * @post Repository contains candidate and report linked by candidate_id.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- test_approve_rejects_blocked_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure approve is rejected when latest report final status is not PASSED.
+ * @post approve_candidate raises ApprovalGateError.
+ * @pre Candidate has BLOCKED report.
+ */
+
+// --- test_approve_rejects_foreign_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure approve is rejected when report belongs to another candidate.
+ * @post approve_candidate raises ApprovalGateError.
+ * @pre Candidate exists, report candidate_id differs.
+ */
+
+// --- test_approve_rejects_duplicate_approve (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure repeated approve decision for same candidate is blocked.
+ * @post Second approve_candidate call raises ApprovalGateError.
+ * @pre Candidate has already been approved once.
+ */
+
+// --- test_reject_persists_decision_without_promoting_candidate_state (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure reject decision is immutable and does not promote candidate to APPROVED.
+ * @post reject_candidate persists REJECTED decision; candidate status remains unchanged.
+ * @pre Candidate has PASSED report and CHECK_PASSED lifecycle state.
+ */
+
+// --- test_reject_then_publish_is_blocked (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure latest REJECTED decision blocks publication gate.
+ * @post publish_candidate raises PublicationGateError.
+ * @pre Candidate is rejected for passed report.
+ */
+
+// --- test_candidate_manifest_services (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Test lifecycle and manifest versioning for release candidates.
+ */
+
+// --- test_candidate_lifecycle_transitions (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify release candidate allows legal status transitions and rejects forbidden back-transitions.
+ */
+
+// --- test_manifest_versioning_and_immutability (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify manifest versions increment monotonically and older snapshots remain queryable.
+ */
+
+// --- _valid_artifacts (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Provide canonical valid artifact payload used by candidate registration tests.
+ */
+
+// --- test_register_candidate_rejects_duplicate_candidate_id (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify duplicate candidate_id registration is rejected by service invariants.
+ */
+
+// --- test_register_candidate_rejects_malformed_artifact_input (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify candidate registration rejects artifact payloads missing required fields.
+ */
+
+// --- test_register_candidate_rejects_empty_artifact_set (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify candidate registration rejects empty artifact collections.
+ */
+
+// --- test_manifest_service_rebuild_creates_new_version (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify repeated manifest build creates a new incremented immutable version.
+ */
+
+// --- test_manifest_service_existing_manifest_cannot_be_mutated (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify existing manifest snapshot remains immutable when rebuilding newer manifest version.
+ */
+
+// --- test_manifest_service_rejects_missing_candidate (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify manifest build fails with missing candidate identifier.
+ */
+
+// --- TestComplianceExecutionService (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Validate stage pipeline and run finalization contracts for compliance execution.
+ * @invariant Missing manifest prevents run startup; failed execution cannot finalize as PASSED.
+ */
+
+// --- _seed_with_candidate_policy_registry (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Build deterministic repository state for run startup tests.
+ * @post Returns repository with candidate, policy and registry; manifest is optional.
+ * @pre candidate_id and snapshot ids are non-empty.
+ */
+
+// --- test_run_without_manifest_rejected (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure compliance run cannot start when manifest is unresolved.
+ * @post start_check_run raises ValueError and no run is persisted.
+ * @pre Candidate/policy exist but manifest is missing.
+ */
+
+// --- test_task_crash_mid_run_marks_failed (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure execution crash conditions force FAILED run status.
+ * @post execute_stages persists run with FAILED status.
+ * @pre Run exists, then required dependency becomes unavailable before execute_stages.
+ */
+
+// --- test_blocked_run_finalization_blocks_report_builder (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure blocked runs require blocking violations before report creation.
+ * @post finalize keeps BLOCKED and report_builder rejects zero blocking violations.
+ * @pre Manifest contains prohibited artifacts leading to BLOCKED decision.
+ */
+
+// --- TestComplianceTaskIntegration (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify clean release compliance runs execute through TaskManager lifecycle with observable success/failure outcomes.
+ * @invariant Compliance execution triggered as task produces terminal task status and persists run evidence.
+ */
+
+// --- _seed_repository (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Prepare deterministic candidate/policy/registry/manifest fixtures for task integration tests.
+ * @post Returns initialized repository and identifiers for compliance run startup.
+ * @pre with_manifest controls manifest availability.
+ */
+
+// --- CleanReleaseCompliancePlugin (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief TaskManager plugin shim that executes clean release compliance orchestration.
+ */
+
+// --- _PluginLoaderStub (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Provide minimal plugin loader contract used by TaskManager in integration tests.
+ * @invariant has_plugin/get_plugin only acknowledge the seeded compliance plugin id.
+ */
+
+// --- _make_task_manager (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Build TaskManager with mocked persistence services for isolated integration tests.
+ * @post Returns TaskManager ready for async task execution.
+ */
+
+// --- _wait_for_terminal_task (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Poll task registry until target task reaches terminal status.
+ * @post Returns task with SUCCESS or FAILED status, otherwise raises TimeoutError.
+ * @pre task_id exists in manager registry.
+ */
+
+// --- test_compliance_run_executes_as_task_manager_task (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify successful compliance execution is observable as TaskManager SUCCESS task.
+ * @post Task ends with SUCCESS; run is persisted with SUCCEEDED status and task binding.
+ * @pre Candidate, policy and manifest are available in repository.
+ */
+
+// --- test_compliance_run_missing_manifest_marks_task_failed (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify missing manifest startup failure is surfaced as TaskManager FAILED task.
+ * @post Task ends with FAILED and run history remains empty.
+ * @pre Candidate/policy exist but manifest is absent.
+ */
+
+// --- TestDemoModeIsolation (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Verify demo and real mode namespace isolation contracts before TUI integration.
+ */
+
+// --- test_resolve_namespace_separates_demo_and_real (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Ensure namespace resolver returns deterministic and distinct namespaces.
+ * @post Demo and real namespaces are different and stable.
+ * @pre Mode names are provided as user/runtime strings.
+ */
+
+// --- test_build_namespaced_id_prevents_cross_mode_collisions (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Ensure ID generation prevents demo/real collisions for identical logical IDs.
+ * @post Produced physical IDs differ by namespace prefix.
+ * @pre Same logical candidate id is used in two different namespaces.
+ */
+
+// --- test_create_isolated_repository_keeps_mode_data_separate (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Verify demo and real repositories do not leak state across mode boundaries.
+ * @post Candidate mutations in one mode are not visible in the other mode.
+ * @pre Two repositories are created for distinct modes.
+ */
+
+// --- TestPolicyResolutionService (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Verify trusted policy snapshot resolution contract and error guards.
+ * @invariant Resolution uses only ConfigManager active IDs and rejects runtime override attempts.
+ */
+
+// --- _config_manager (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Build deterministic ConfigManager-like stub for tests.
+ * @invariant Only settings.clean_release.active_policy_id and active_registry_id are populated; any other settings field access raises AttributeError.
+ * @post Returns object exposing get_config().settings.clean_release active IDs.
+ * @pre policy_id and registry_id may be None or non-empty strings.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_missing_profile (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure resolution fails when trusted profile is not configured.
+ * @post Raises PolicyResolutionError with missing trusted profile reason.
+ * @pre active_policy_id is None.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_missing_registry (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure resolution fails when trusted registry is not configured.
+ * @post Raises PolicyResolutionError with missing trusted registry reason.
+ * @pre active_registry_id is None and active_policy_id is set.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_rejects_override_attempt (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure runtime override attempt is rejected even if snapshots exist.
+ * @post Raises PolicyResolutionError with override forbidden reason.
+ * @pre valid trusted snapshots exist in repository and override is provided.
+ */
+
+// --- TestPublicationService (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Define publication gate contracts over approved candidates and immutable publication records.
+ * @invariant Publish requires approval; revoke requires existing publication; republish after revoke is allowed as a new record.
+ */
+
+// --- _seed_candidate_with_passed_report (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Seed candidate/report fixtures for publication gate scenarios.
+ * @post Repository contains candidate and PASSED report.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- test_publish_without_approval_rejected (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure publish action is blocked until candidate is approved.
+ * @post publish_candidate raises PublicationGateError.
+ * @pre Candidate has PASSED report but status is not APPROVED.
+ */
+
+// --- test_revoke_unknown_publication_rejected (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure revocation is rejected for unknown publication id.
+ * @post revoke_publication raises PublicationGateError.
+ * @pre Repository has no matching publication record.
+ */
+
+// --- test_republish_after_revoke_creates_new_active_record (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure republish after revoke is allowed and creates a new ACTIVE record.
+ * @post New publish call returns distinct publication id with ACTIVE status.
+ * @pre Candidate is APPROVED and first publication has been revoked.
+ */
+
+// --- TestReportAuditImmutability (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Validate report snapshot immutability expectations and append-only audit hook behavior for US2.
+ * @invariant Built reports are immutable snapshots; audit hooks produce append-only event traces.
+ */
+
+// --- _terminal_run (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Build deterministic terminal run fixture for report snapshot tests.
+ * @post Returns a terminal ComplianceRun suitable for report generation.
+ * @pre final_status is a valid ComplianceDecision value.
+ */
+
+// --- test_report_builder_sets_immutable_snapshot_flag (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Ensure generated report payload is marked immutable and persisted as snapshot.
+ * @post Built report has immutable=True and repository stores same immutable object.
+ * @pre Terminal run exists.
+ */
+
+// --- test_repository_rejects_report_overwrite_for_same_report_id (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Define immutability contract that report snapshots cannot be overwritten by same identifier.
+ * @post Second save for same report id is rejected with explicit immutability error.
+ * @pre Existing report with id is already persisted.
+ */
+
+// --- test_audit_hooks_emit_append_only_event_stream (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Verify audit hooks emit one event per action call and preserve call order.
+ * @post Three calls produce three ordered info entries with molecular prefixes.
+ * @pre Logger backend is patched.
+ */
+
+// --- SupersetCompatibilityMatrixTests (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Verifies Superset preview and SQL Lab endpoint fallback strategy used by dataset-review orchestration.
+ */
+
+// --- make_adapter (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Build an adapter with a mock Superset client and deterministic environment for compatibility tests.
+ */
+
+// --- test_preview_prefers_supported_client_method_before_network_fallback (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms preview compilation uses a supported client method first when the capability exists.
+ */
+
+// --- test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms preview fallback walks the compatibility matrix from preferred to legacy endpoints until one returns compiled SQL.
+ */
+
+// --- test_sql_lab_launch_falls_back_to_legacy_execute_endpoint (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms SQL Lab launch falls back from modern to legacy execute endpoint and preserves canonical session reference extraction.
+ */
+
+// --- TestAPIKeyAuth (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Contract tests for API key authentication — valid key, invalid, revoked, expired, missing permission,
+ */
+
+// --- test_no_header_returns_none (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief No X-API-Key header → returns None.
+ */
+
+// --- test_valid_key_returns_principal (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Valid API key → returns APIKeyPrincipal with correct fields.
+ */
+
+// --- test_invalid_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Invalid API key → 401.
+ */
+
+// --- test_revoked_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Revoked (active=False) API key → 401.
+ */
+
+// --- test_expired_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Expired API key → 401.
+ */
+
+// --- test_api_key_auth_valid (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Valid API key with matching permission → 202.
+ */
+
+// --- test_api_key_auth_wrong_permission (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief API key lacks required permission → 403.
+ */
+
+// --- test_api_key_auth_revoked (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Revoked API key → 401.
+ */
+
+// --- test_api_key_auth_expired (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Expired API key → 401.
+ */
+
+// --- test_api_key_auth_invalid (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Non-existent key → 401.
+ */
+
+// --- test_api_key_auth_environment_scope (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Key scoped to ss-dev, request for ss-prod → 400.
+ */
+
+// --- test_api_key_auth_environment_scope_ok (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Key scoped to ss-dev, request for ss-dev → 202.
+ */
+
+// --- test_jwt_precedence (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Both valid API key + valid JWT → JWT takes precedence.
+ */
+
+// --- TestAPIKeyModel (backend/tests/test_api_key_model.py)
+/**!
+ * @brief Contract tests for the APIKey SQLAlchemy model — creation, hash storage, and field constraints.
+ */
+
+// --- clean_db (backend/tests/test_api_key_model.py)
+/**!
+ * @brief In-memory SQLite fixture for APIKey model tests.
+ */
+
+// --- test_create_api_key (backend/tests/test_api_key_model.py)
+/**!
+ * @brief Create APIKey with required fields and verify defaults.
+ */
+
+// --- test_key_hash_unique (backend/tests/test_api_key_model.py)
+/**!
+ * @brief key_hash is unique — duplicate raises IntegrityError.
+ */
+
+// --- test_prefix_length (backend/tests/test_api_key_model.py)
+/**!
+ * @brief prefix is exactly 11 characters.
+ */
+
+// --- test_active_default_true (backend/tests/test_api_key_model.py)
+/**!
+ * @brief active column defaults to True.
+ */
+
+// --- TestAPIKeyRoutes (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Contract tests for admin API key CRUD endpoints — list, create (raw key present), revoke, idempotent revoke.
+ */
+
+// --- test_list_empty (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief No keys → returns empty list.
+ */
+
+// --- test_list_with_keys (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Keys exist → returns list without raw_key or key_hash fields.
+ */
+
+// --- test_create_valid (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Valid request → 201 with raw_key, prefix, id.
+ */
+
+// --- test_create_missing_name (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Missing name → 400 or 422.
+ */
+
+// --- test_create_empty_permissions (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Empty permissions → 400 or 422.
+ */
+
+// --- test_revoke_valid (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke existing active key → 200 with status=revoked.
+ */
+
+// --- test_revoke_already_revoked (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke already revoked key → 404.
+ */
+
+// --- test_revoke_not_found (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke non-existent key → 404.
+ */
+
+// --- TestAuth (backend/tests/test_auth.py)
+/**!
+ * @brief Covers authentication service/repository behavior and auth bootstrap helpers.
+ */
+
+// --- test_create_admin_creates_user_with_optional_email (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_create_admin_is_idempotent_for_existing_user (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_ensure_encryption_key_generates_backend_env_file (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_ensure_encryption_key_reuses_existing_env_file_value (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_ensure_encryption_key_prefers_process_environment (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- TestConstantsAuditFixes (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Verify Class 5 fix — hardcoded values extracted to named module-level constants.
+ */
+
+// --- test_page_size_constant_exists (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief DEFAULT_PAGE_SIZE contract: importable, int > 0 (not yet defined in source).
+ */
+
+// --- test_llm_analysis_timeout_constants (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Named timeout constants should exist per RATIONALE comment (not yet defined).
+ */
+
+// --- test_base_dir_constant_replaces_parents (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief BASE_DIR resolves to backend/ root, not __file__-dependent relative path.
+ */
+
+// --- test_git_service_repositorys_typo_regression (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief services/git/_base.py still has "repositorys" (old typo) at line 148 — known bug.
+ */
+
+// --- test_git_default_repos_path_constant (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief DEFAULT_GIT_REPOS_PATH should be defined per RATIONALE (not yet defined).
+ */
+
+// --- test_superset_client_module_loads (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief superset_client._base is importable (no dependency on crashing modules).
+ */
+
+// --- test_constants_are_immutable (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Module-level constants use int/str types (immutable by convention).
+ */
+
+// --- TestCoreScheduler (backend/tests/test_core_scheduler.py)
+/**!
+ * @brief Verify SchedulerService load_schedules and translation job add/remove contracts.
+ */
+
+// --- test_load_schedules_reloads_translation_schedules (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_add_and_remove_translation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_remove_nonexistent_translation_job_no_error (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_add_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_load_schedules_loads_validation_policies (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_creates_tasks (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_skips_missing_policy (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_skips_inactive_policy (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_skips_no_dashboards (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_remove_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_remove_nonexistent_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_reload_validation_policy_adds_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_reload_validation_policy_removes_job_when_policy_gone (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- TestDashboardsApi (backend/tests/test_dashboards_api.py)
+/**!
+ * @brief Comprehensive contract-driven tests for Dashboard Hub API
+ */
+
+// --- test_get_dashboard_tasks_history_success (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_get_dashboard_tasks_history_sorting (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_get_dashboard_thumbnail_env_not_found (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_get_dashboard_thumbnail_202 (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_migrate_dashboards_pre_checks (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_backup_dashboards_pre_checks (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_backup_dashboards_with_schedule (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_task_matches_dashboard_logic (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- TestDeprecationAuditFixes (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Verify Class 7 fix — is_multimodal_model should emit DeprecationWarning.
+ */
+
+// --- test_is_multimodal_model_emits_warning (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief is_multimodal_model should emit DeprecationWarning (shim not yet implemented).
+ */
+
+// --- test_multimodal_model_returns_true (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Known multimodal models (gpt-4o, claude-3, gemini) return True.
+ */
+
+// --- test_text_only_model_returns_false (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Text-only models (embedding, whisper, rerank) return False.
+ */
+
+// --- test_empty_model_returns_false (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Empty or None model name returns False without error.
+ */
+
+// --- test_case_insensitive_matching (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Model name matching is case-insensitive.
+ */
+
+// --- test_deprecation_comment_exists (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief The source module documents the @DEPRECATED rationale in the region header.
+ */
+
+// --- TestLayoutUtils (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Contract tests for layout utility functions — _estimate_markdown_height.
+ */
+
+// --- test_empty_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Empty string returns minimum height 19.
+ */
+
+// --- test_single_line_text (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Short text without padding returns expected computed height.
+ */
+
+// --- test_content_with_padding (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Content with padding:12 — 24px added to content height.
+ */
+
+// --- test_very_long_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Very long content (3000 chars) capped at max height 200.
+ */
+
+// --- test_html_only_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief HTML-only content (no visible text) returns minimum height 19.
+ */
+
+// --- test_log_persistence (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Unit tests for TaskLogPersistenceService.
+ */
+
+// --- TestLogPersistence (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test suite for TaskLogPersistenceService.
+ */
+
+// --- test_add_logs_single (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding a single log entry.
+ * @post Log entry persisted to database.
+ * @pre Service and session initialized.
+ */
+
+// --- test_add_logs_batch (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding multiple log entries in batch.
+ * @post All log entries persisted to database.
+ * @pre Service and session initialized.
+ */
+
+// --- test_add_logs_empty (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding empty log list (should be no-op).
+ * @post No logs added.
+ * @pre Service initialized.
+ */
+
+// --- test_get_logs_by_task_id (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs by task ID.
+ * @post Returns logs for the specified task.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_filters (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with level and source filters.
+ * @post Returns filtered logs.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_pagination (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with pagination.
+ * @post Returns paginated logs.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_search (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with search query.
+ * @post Returns logs matching search query.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_log_stats (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving log statistics.
+ * @post Returns LogStats model with counts by level and source.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_sources (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving unique log sources.
+ * @post Returns list of unique sources.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_task (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting logs by task ID.
+ * @post Logs for the task are deleted.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_tasks (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting logs for multiple tasks.
+ * @post Logs for all specified tasks are deleted.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_tasks_empty (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting with empty list (no-op).
+ * @post No error, no deletion.
+ * @pre Service initialized.
+ */
+
+// --- TestLogger (backend/tests/test_logger.py)
+/**!
+ * @brief Unit tests for the custom logger CoT JSON formatters and configuration context manager.
+ * @invariant All required log statements must correctly check the threshold.
+ */
+
+// --- test_belief_scope_success_coherence (backend/tests/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs REFLECT marker on success.
+ * @post Logs are verified to contain REFLECT marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_reason_not_visible_at_info (backend/tests/test_logger.py)
+/**!
+ * @brief Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.
+ * @post REASON/REFLECT markers are not captured at INFO level.
+ * @pre belief_scope is available. caplog fixture is used.
+ */
+
+// --- test_cot_json_formatter_output (backend/tests/test_logger.py)
+/**!
+ * @brief Test that CotJsonFormatter produces valid JSON with expected fields.
+ */
+
+// --- test_cot_json_formatter_plain_message (backend/tests/test_logger.py)
+/**!
+ * @brief Test that CotJsonFormatter wraps plain messages (no extra) with default marker.
+ */
+
+// --- TestLoggingAuditFixes (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief Verify Class 2 fix — no bare `except: pass` patterns remain in src/.
+ */
+
+// --- _collect_src_files (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief Collect all .py files under src/ excluding test/ and mock/ directories.
+ */
+
+// --- test_except_pass_replaced_with_log (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief AST audit: bare `except: pass` nodes are absent from src/ source files.
+ */
+
+// --- test_plugin_loader_uses_logger_not_print (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py (src/core/) uses logger for error/warning, not print().
+ */
+
+// --- test_plugin_loader_imports_logger (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py imports a logger or _logger for structured reporting.
+ */
+
+// --- test_plugin_loader_logger_calls_exist (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py references logger.error/warning/info in its code.
+ */
+
+// --- test_maintenance_api (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Contract tests for Maintenance Banner API endpoints — T016, T025.
+ */
+
+// --- test_start_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Valid request returns 202 with task_id and maintenance_id.
+ */
+
+// --- test_start_missing_tables (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Missing tables field returns 422.
+ */
+
+// --- test_start_end_time_before_start (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief end_time before start_time returns 400.
+ */
+
+// --- test_start_too_many_tables (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief More than 100 tables returns 422 (Pydantic validation).
+ */
+
+// --- test_start_idempotency (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Same (tables, start, end) returns already_active.
+ */
+
+// --- test_end_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Valid maintenance_id returns 202.
+ */
+
+// --- test_end_not_found (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Non-existent maintenance_id returns 404.
+ */
+
+// --- test_end_all_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief end-all returns 202.
+ */
+
+// --- test_list_events (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Returns active and completed events.
+ */
+
+// --- test_expired_event_auto_ends (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event past end_time with ACTIVE status → create_task called with auto-end params.
+ */
+
+// --- test_future_end_time_skipped (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event with future end_time → no task created, skipped by < now filter.
+ */
+
+// --- test_no_end_time_skipped (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event with end_time=None → no task created, skipped by isnot(None) filter.
+ */
+
+// --- test_list_banners (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Returns list of active banners.
+ */
+
+// --- test_get_settings (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief GET returns settings.
+ */
+
+// --- test_put_settings (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief PUT updates settings.
+ */
+
+// --- test_maintenance_service (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Integration tests for MaintenanceService — T018, T026, T026a.
+ */
+
+// --- test_basic_key (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Basic idempotency key with tables and times.
+ */
+
+// --- test_key_without_end_time (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Idempotency key with None end_time.
+ */
+
+// --- test_key_table_sorting (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Tables are sorted alphabetically in frozenset.
+ */
+
+// --- test_empty_tables (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Empty tables list returns empty.
+ */
+
+// --- test_table_based_match (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Table-based dataset matching.
+ */
+
+// --- test_virtual_dataset_match (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Virtual SQL dataset matching via SqlTableExtractor.
+ */
+
+// --- test_superset_api_failure (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Superset API failure propagates.
+ */
+
+// --- test_creates_new_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No existing banner — creates new chart and banner row.
+ */
+
+// --- test_returns_existing_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Existing active banner — returns it.
+ */
+
+// --- test_chart_creation_failure (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Chart creation failure propagates.
+ */
+
+// --- test_single_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Single event — direct substitution.
+ */
+
+// --- test_multiple_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Multiple events — combined message.
+ */
+
+// --- test_empty_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Empty events list returns empty string.
+ */
+
+// --- test_missing_variables (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Missing variables replaced with empty string.
+ */
+
+// --- test_html_escaping (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Message is HTML-escaped.
+ */
+
+// --- test_happy_path (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Happy path: event with matching dashboards.
+ */
+
+// --- test_no_matching_dashboards (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No dashboards match the tables.
+ */
+
+// --- test_event_not_found (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Event ID not in DB.
+ */
+
+// --- test_already_processed_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Event already ACTIVE — idempotent.
+ */
+
+// --- test_rebuild_active_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Active banner with active state — rebuilds text.
+ */
+
+// --- test_banner_not_found (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Banner ID not found.
+ */
+
+// --- test_end_active_event_single_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief End event with single active dashboard — banner removed entirely.
+ */
+
+// --- test_end_event_shared_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Two events, same dashboard — ending one rebuilds banner, doesn't delete.
+ */
+
+// --- test_end_already_completed_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Already completed event — idempotent.
+ */
+
+// --- test_end_all_active_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief End all active events.
+ */
+
+// --- test_no_active_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No active events.
+ */
+
+// --- test_mixed_active_and_completed (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Mix of active and completed events — only active get ended.
+ */
+
+// --- TestResourceHubs (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Contract tests for resource hub dashboards/datasets listing and pagination boundary validation.
+ */
+
+// --- test_dashboards_api (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify GET /api/dashboards contract compliance
+ */
+
+// --- mock_deps (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Provide dependency override fixture for resource hub route tests.
+ * @invariant unconstrained mock — no spec= enforced; attribute typos will silently pass
+ */
+
+// --- test_get_dashboards_not_found (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint returns 404 for unknown environment identifier.
+ */
+
+// --- test_get_dashboards_search (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint search filter returns matching subset.
+ */
+
+// --- test_datasets_api (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify GET /api/datasets contract compliance
+ */
+
+// --- test_get_datasets_not_found (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint returns 404 for unknown environment identifier.
+ */
+
+// --- test_get_datasets_search (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint search filter returns matching dataset subset.
+ */
+
+// --- test_get_datasets_service_failure (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint surfaces backend fetch failure as HTTP 503.
+ */
+
+// --- test_pagination_boundaries (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify pagination validation for GET endpoints
+ */
+
+// --- test_get_dashboards_pagination_zero_page (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint rejects page=0 with HTTP 400 validation error.
+ */
+
+// --- test_get_dashboards_pagination_oversize (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint rejects oversized page_size with HTTP 400.
+ */
+
+// --- test_get_datasets_pagination_zero_page (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint rejects page=0 with HTTP 400.
+ */
+
+// --- test_get_datasets_pagination_oversize (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint rejects oversized page_size with HTTP 400.
+ */
+
+// --- TestSecurityAuditFixes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Verify Class 1 security audit fixes — env-only secrets, crash-early, CORS parsing.
+ */
+
+// --- test_missing_secret_key_crashes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig.validate_secret_key raises ValueError when value is empty (crash-early).
+ */
+
+// --- test_missing_auth_db_url_crashes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig.validate_auth_db_url raises ValueError when URL is empty and DEV_MODE is off.
+ */
+
+// --- test_auth_db_dev_fallback_works (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief When DEV_MODE=true and AUTH_DATABASE_URL is unset, dev fallback is used without crash.
+ */
+
+// --- test_allowed_origins_parsing (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief os.getenv("ALLOWED_ORIGINS").split(",") correctly parses comma-separated origins.
+ */
+
+// --- test_cors_wildcard_default (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief When ALLOWED_ORIGINS is not set, default returns ["*"].
+ */
+
+// --- test_cors_parsing_single_value (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Single origin returns single-element list.
+ */
+
+// --- test_cors_parsing_with_trailing_spaces (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Origins with trailing spaces are preserved (no strip).
+ */
+
+// --- test_database_url_env_override (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief DATABASE_URL env var takes precedence over POSTGRES_URL.
+ */
+
+// --- test_database_url_postgres_fallback (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief POSTGRES_URL is used when DATABASE_URL is unset.
+ */
+
+// --- test_database_url_raises_when_both_unset (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief RuntimeError is expected when both DATABASE_URL and POSTGRES_URL are unset (non-dev).
+ */
+
+// --- test_auth_config_module_contract (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig contract: the class exists, validators are documented.
+ */
+
+// --- test_sql_table_extractor (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Unit tests for SqlTableExtractor — T017. Verifies three-phase extraction of schema.table references from SQL+Jinja.
+ */
+
+// --- test_simple_select (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Happy path: simple SELECT with FROM schema.table.
+ */
+
+// --- test_multiple_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief JOIN with multiple schema-qualified tables.
+ */
+
+// --- test_empty_input (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Empty string returns empty set.
+ */
+
+// --- test_no_schema_qualified_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Unqualified table names are NOT matched.
+ */
+
+// --- test_case_insensitive (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Matching is case-insensitive; result is lowercased.
+ */
+
+// --- test_string_literal_false_positive (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Date literal like '2026.04.30' must NOT be matched as schema.table.
+ */
+
+// --- test_jinja_string_concat (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Table reference inside Jinja {{ 'raw.sales' }} as a direct string.
+ */
+
+// --- test_jinja_set_block (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Table name in Jinja {% set %} block string value.
+ */
+
+// --- test_mixed_jinja_and_sql (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Mixed Jinja string and plain SQL schema.table references.
+ */
+
+// --- test_cte_with_schema_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief CTE body with schema-qualified table references.
+ */
+
+// --- test_jinja_comment_excluded (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Jinja comment {# ... #} content should not produce table extraction (no string patterns inside comments).
+ */
+
+// --- TestStorageAuditFixes (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief Verify Class 7 typo fix — "repositorys" → "repositories" across all storage/git modules.
+ */
+
+// --- test_repository_typo_fixed (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief FileCategory.REPOSITORY equals "repositories", NOT "repositorys".
+ */
+
+// --- test_repo_path_default_fixed (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief StorageConfig().repo_path defaults to "repositories".
+ */
+
+// --- test_storage_model_compiles (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief All storage model classes import without errors.
+ */
+
+// --- test_backup_category_unchanged (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief FileCategory.BACKUP still equals "backups" (not affected by typo fix).
+ */
+
+// --- test_storage_config_fields_have_correct_types (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief StorageConfig fields are all strings with correct defaults.
+ */
+
+// --- TestStorageConfigMigration (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify StorageConfig root_path change from "backups" to "/app/storage",
+ */
+
+// --- TestStorageConfigDefaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify StorageConfig default field values after the root_path change.
+ */
+
+// --- test_root_path_default (backend/tests/test_storage_config.py)
+/**!
+ * @brief StorageConfig().root_path must equal "/app/storage" (was "backups").
+ */
+
+// --- test_root_path_is_string (backend/tests/test_storage_config.py)
+/**!
+ * @brief root_path is always a str (type safety).
+ */
+
+// --- test_other_defaults_unchanged (backend/tests/test_storage_config.py)
+/**!
+ * @brief Other StorageConfig fields were not affected by the root_path change.
+ */
+
+// --- test_global_settings_propagates_storage (backend/tests/test_storage_config.py)
+/**!
+ * @brief GlobalSettings().storage.root_path inherits the StorageConfig default.
+ */
+
+// --- test_override_root_path (backend/tests/test_storage_config.py)
+/**!
+ * @brief Explicit root_path overrides the default.
+ */
+
+// --- TestConfigManagerDefaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify ConfigManager produces correct defaults when no config.json exists.
+ */
+
+// --- test_init_falls_to_defaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief ConfigManager(…nonexistent…) loads defaults when both DB and config.json are absent.
+ */
+
+// --- test_default_config_root_path (backend/tests/test_storage_config.py)
+/**!
+ * @brief _default_config() hardcodes root_path == "/app/storage" via StorageConfig default.
+ */
+
+// --- test_features_from_env_still_applied (backend/tests/test_storage_config.py)
+/**!
+ * @brief Even without config.json, _apply_features_from_env runs during default init.
+ */
+
+// --- TestValidatePath (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify ConfigManager.validate_path contract.
+ */
+
+// --- test_validate_path_creates_directory (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path creates the target directory and returns (True, "OK").
+ */
+
+// --- test_validate_path_already_exists (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path succeeds when the directory already exists.
+ */
+
+// --- test_validate_path_nonexistent_root (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path returns False for a path under / (non-writable by non-root).
+ */
+
+// --- test_validate_path_read_only_parent (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path returns False when the parent directory is not writable.
+ */
+
+// --- TestGitPluginConfigIntegration (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify GitPlugin uses shared config_manager from src.dependencies (no config.json fallback).
+ */
+
+// --- test_git_plugin_uses_shared_config_manager (backend/tests/test_storage_config.py)
+/**!
+ * @brief GitPlugin.__init__ picks up the shared config_manager from src.dependencies.
+ */
+
+// --- test_git_plugin_fallback_creates_new (backend/tests/test_storage_config.py)
+/**!
+ * @brief When from src.dependencies import config_manager fails,
+ */
+
+// --- TestRegressionGuard (backend/tests/test_storage_config.py)
+/**!
+ * @brief Guard against regressions in existing test contracts and stale assertions.
+ */
+
+// --- test_existing_test_would_fail (backend/tests/test_storage_config.py)
+/**!
+ * @brief Existing test_storage_audit_fixes.py still asserts root_path=="backups" (WRONG).
+ */
+
+// --- test_storage_settings_endpoint_shape (backend/tests/test_storage_config.py)
+/**!
+ * @brief The API response shape for storage settings is still StorageConfig.
+ */
+
+// --- test_task_manager (backend/tests/test_task_manager.py)
+/**!
+ * @brief Unit tests for TaskManager lifecycle, CRUD, log buffering, and filtering.
+ * @invariant TaskManager state changes are deterministic and testable with mocked dependencies.
+ */
+
+// --- _make_manager (backend/tests/test_task_manager.py)
+/**!
+ */
+
+// --- _cleanup_manager (backend/tests/test_task_manager.py)
+/**!
+ */
+
+// --- test_task_persistence (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Unit tests for TaskPersistenceService.
+ */
+
+// --- TestTaskPersistenceHelpers (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test suite for TaskPersistenceService static helper methods.
+ */
+
+// --- test_json_load_if_needed_none (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with None input.
+ */
+
+// --- test_json_load_if_needed_dict (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with dict input.
+ */
+
+// --- test_json_load_if_needed_list (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with list input.
+ */
+
+// --- test_json_load_if_needed_json_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with JSON string.
+ */
+
+// --- test_json_load_if_needed_empty_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with empty/null strings.
+ */
+
+// --- test_json_load_if_needed_plain_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with non-JSON string.
+ */
+
+// --- test_json_load_if_needed_integer (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with integer.
+ */
+
+// --- test_parse_datetime_none (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with None.
+ */
+
+// --- test_parse_datetime_datetime_object (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with datetime object.
+ */
+
+// --- test_parse_datetime_iso_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with ISO string.
+ */
+
+// --- test_parse_datetime_invalid_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with invalid string.
+ */
+
+// --- test_parse_datetime_integer (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with non-string, non-datetime.
+ */
+
+// --- TestTaskPersistenceService (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test suite for TaskPersistenceService CRUD operations.
+ */
+
+// --- setup_class (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Setup in-memory test database.
+ */
+
+// --- teardown_class (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Dispose of test database.
+ */
+
+// --- setup_method (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Clean task_records table before each test.
+ */
+
+// --- test_persist_task_new (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting a new task creates a record.
+ * @post TaskRecord exists in database.
+ * @pre Empty database.
+ */
+
+// --- test_persist_task_update (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test updating an existing task.
+ * @post Task record updated with new status.
+ * @pre Task already persisted.
+ */
+
+// --- test_persist_task_with_logs (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting a task with log entries.
+ * @post Logs serialized as JSON in task record.
+ * @pre Task has logs attached.
+ */
+
+// --- test_persist_task_failed_extracts_error (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test that FAILED task extracts last error message.
+ * @post record.error contains last error message.
+ * @pre Task has FAILED status with ERROR logs.
+ */
+
+// --- test_persist_tasks_batch (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting multiple tasks.
+ * @post All task records created.
+ * @pre Empty database.
+ */
+
+// --- test_load_tasks (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks from database.
+ * @post Returns list of Task objects with correct data.
+ * @pre Tasks persisted.
+ */
+
+// --- test_load_tasks_with_status_filter (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks filtered by status.
+ * @post Returns only tasks matching status filter.
+ * @pre Tasks with different statuses persisted.
+ */
+
+// --- test_load_tasks_with_limit (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks with limit.
+ * @post Returns at most `limit` tasks.
+ * @pre Multiple tasks persisted.
+ */
+
+// --- test_delete_tasks (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test deleting tasks by ID list.
+ * @post Specified tasks deleted, others remain.
+ * @pre Tasks persisted.
+ */
+
+// --- test_delete_tasks_empty_list (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test deleting with empty list (no-op).
+ * @post No error, no changes.
+ * @pre None.
+ */
+
+// --- test_persist_task_with_datetime_in_params (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test json_serializable handles datetime in params.
+ * @post Params serialized correctly.
+ * @pre Task params contain datetime values.
+ */
+
+// --- test_persist_task_resolves_environment_slug_to_existing_id (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Ensure slug-like environment token resolves to environments.id before persisting task.
+ * @post task_records.environment_id stores actual environments.id and does not violate FK.
+ * @pre environments table contains env with name convertible to provided slug token.
+ */
+
+// --- TranslateCorrectionTests (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Tests for term correction API endpoints and DictionaryManager correction methods.
+ */
+
+// --- test_submit_correction_creates_entry (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify that a correction creates a new dictionary entry.
+ */
+
+// --- test_submit_correction_conflict_detected (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify conflict detection when entry already exists.
+ */
+
+// --- test_submit_correction_overwrite (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify that correction overwrites existing entry.
+ */
+
+// --- test_bulk_corrections_atomic (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify bulk corrections are applied atomically.
+ */
+
+// --- test_api_correction_missing_dict (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify POST corrections without dictionary_id returns 422.
+ */
+
+// --- test_api_bulk_corrections (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify POST /corrections/bulk works.
+ */
+
+// --- TestTranslateExecutorFilter (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @brief Verify TranslationExecutor._filter_new_keys contracts — key dedup, empty-set, guard triggers.
+ */
+
+// --- test_no_prior_run_returns_all_rows (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_filters_existing_keys (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_composite_keys (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_all_keys_existing_returns_empty (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_empty_key_cols_returns_all_rows (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_null_source_data_handled (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_prior_run_no_records_returns_all (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_key_cols_none_returns_all (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- TranslateHistoryTests (backend/tests/test_translate_history.py)
+/**!
+ * @brief Tests for run history list/detail endpoints and metrics aggregation.
+ */
+
+// --- test_list_runs_empty (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify runs list returns empty result initially.
+ */
+
+// --- test_list_runs_with_data (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify runs list returns data when runs exist.
+ */
+
+// --- test_list_runs_filter_job_id (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify filtering runs by job_id works.
+ */
+
+// --- test_list_runs_filter_status (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify filtering runs by status works.
+ */
+
+// --- test_get_run_detail (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify run detail returns config_snapshot, records, events.
+ */
+
+// --- test_get_job_metrics (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics endpoint returns aggregated data.
+ */
+
+// --- test_get_all_metrics (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify global metrics endpoint returns data.
+ */
+
+// --- test_metrics_empty_job (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics for job with no runs returns zeros.
+ */
+
+// --- test_run_detail_not_found (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify 404 on non-existent run detail.
+ */
+
+// --- test_list_runs_includes_language_info (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify run list includes target_languages, total_translated, and language_stats.
+ */
+
+// --- test_metrics_per_language_breakdown (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics endpoint returns per_language_metrics.
+ */
+
+// --- test_metric_snapshot_stores_per_language (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify MetricSnapshot stores per_language_metrics via prune_expired.
+ */
+
+// --- test_combined_metrics_live_and_snapshot (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify combined metrics merge live + snapshot per-language data.
+ */
+
+// --- TranslateJobTests (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Tests for translation job CRUD endpoints and service layer with column validation.
+ */
+
+// --- valid_job_payload (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Standard valid payload for creating a translation job.
+ */
+
+// --- MockConfigManager (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Mock ConfigManager for service tests that returns a test environment.
+ */
+
+// --- db_session (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Create a fresh DB session with transaction rollback for each test.
+ */
+
+// --- mock_api_deps (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Override FastAPI dependencies (including get_db with in-memory SQLite) for API route tests.
+ */
+
+// --- client (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief FastAPI TestClient for API route tests.
+ */
+
+// --- test_create_job_valid (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a valid job payload creates a job successfully.
+ */
+
+// --- test_create_job_missing_translation_column (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that creating a job with datasource but no translation column raises ValueError.
+ */
+
+// --- test_create_job_invalid_upsert_strategy (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that an invalid upsert strategy is rejected.
+ */
+
+// --- test_get_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be retrieved by ID.
+ */
+
+// --- test_get_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that getting a non-existent job raises ValueError.
+ */
+
+// --- test_list_jobs (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that listing jobs returns all created jobs.
+ */
+
+// --- test_list_jobs_with_status_filter (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that listing jobs with a status filter works.
+ */
+
+// --- test_update_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be updated.
+ */
+
+// --- test_delete_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be deleted.
+ */
+
+// --- test_duplicate_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be duplicated.
+ */
+
+// --- test_duplicate_job_custom_name (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be duplicated with a custom name.
+ */
+
+// --- test_detect_virtual_columns (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify virtual column detection from column metadata.
+ */
+
+// --- test_get_dialect_from_database (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify dialect extraction from Superset database records.
+ */
+
+// --- test_get_dialect_from_database_unsupported (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that unsupported dialects raise ValueError.
+ */
+
+// --- test_api_create_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify POST /api/translate/jobs returns 201 with valid payload.
+ */
+
+// --- test_api_list_jobs (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify GET /api/translate/jobs returns 200.
+ */
+
+// --- test_api_get_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify GET non-existent job returns 404.
+ */
+
+// --- test_api_delete_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify DELETE non-existent job returns 404.
+ */
+
+// --- test_api_duplicate_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify duplicating a non-existent job returns 404.
+ */
+
+// --- test_api_create_job_422_missing_name (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify POST with missing required fields returns 422.
+ */
+
+// --- test_api_datasource_columns_missing_env (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify datasource columns endpoint without env_id returns 422.
+ */
+
+// --- test_api_datasource_columns_bad_env (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify datasource columns with unknown env returns 400.
+ */
+
+// --- test_api_update_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify PUT non-existent job returns 404.
+ */
+
+// --- TranslateSchedulerTests (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Tests for TranslationScheduler CRUD and APScheduler integration.
+ */
+
+// --- test_create_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule creation with valid params.
+ */
+
+// --- test_update_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule update.
+ */
+
+// --- test_delete_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule deletion.
+ */
+
+// --- test_enable_disable_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify enable/disable toggle.
+ */
+
+// --- test_get_schedule_not_found (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify ValueError on getting non-existent schedule.
+ */
+
+// --- test_list_active_schedules (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify listing only active schedules.
+ */
+
+// --- test_get_next_executions (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify next execution time computation.
+ */
+
+// --- test_get_next_executions_invalid (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify invalid cron returns empty list.
+ */
+
+// --- TestTranslateSchedulerExecution (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @brief Verify execute_scheduled_translation contracts — trigger_type dispatch, baseline expiry fallback.
+ */
+
+// --- test_new_key_only_mode (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_baseline_expired_fallback (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_full_mode_default (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_inactive_schedule_skips (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_schedule_not_found_skips (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_baseline_expired_full_mode (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_execution_error_handled (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- TestTranslateSchedulerGuard (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @brief Verify execute_scheduled_translation concurrency guard and stale-PENDING clearance contracts.
+ */
+
+// --- test_concurrent_run_skips (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- test_recent_pending_run_not_stale (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- test_stale_pending_cleared_and_proceeds (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- test_multiple_stale_pending_all_cleared (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- docker.backend.Dockerfile (docker/backend.Dockerfile)
+/**!
+ * @brief Backend Dockerfile — Python 3.11 slim + Playwright + entrypoint с установкой сертификатов.
+ * @post Образ с backend API, Playwright, entrypoint для bootstrap admin и установки сертификатов.
+ * @pre Docker builder context — корень проекта. backend/ и docker/ доступны.
+ */
+
+// --- docker.backend.entrypoint (docker/backend.entrypoint.sh)
+/**!
+ * @brief Container entrypoint — установка корп. сертификатов, Playwright (lazy), bootstrap admin,
+ */
+
+// --- docker.backend.entrypoint.install_certificates (docker/backend.entrypoint.sh)
+/**!
+ * @brief Устанавливает корпоративные .crt сертификаты из CERTS_PATH в системное хранилище Debian.
+ * @pre CERTS_PATH указывает на директорию (может быть пуста или не существовать).
+ */
+
+// --- docker.backend.entrypoint.bootstrap_admin (docker/backend.entrypoint.sh)
+/**!
+ * @brief Создание admin пользователя из переменных окружения (идемпотентно).
+ * @post Admin пользователь создан в БД (если ещё не существовал).
+ * @pre INITIAL_ADMIN_CREATE=true, INITIAL_ADMIN_USERNAME и INITIAL_ADMIN_PASSWORD заданы.
+ */
+
+// --- docker.backend.entrypoint.install_playwright (docker/backend.entrypoint.sh)
+/**!
+ * @brief Lazy установка Playwright Chromium (~377 MB) при первом запуске.
+ * @post Chromium установлен в PLAYWRIGHT_BROWSERS_PATH.
+ * @pre ~/.cache/ms-playwright доступен (можно закешировать volume).
+ */
+
+// --- docker.frontend.Dockerfile (docker/frontend.Dockerfile)
+/**!
+ * @brief Frontend Dockerfile — сборка SvelteKit (node:20) + nginx runtime с опциональным SSL.
+ * @post nginx:alpine образ со статикой SvelteKit, entrypoint для выбора HTTP/SSL конфига.
+ * @pre Docker builder context — корень проекта. frontend/ и docker/ доступны.
+ */
+
+// --- docker.frontend.entrypoint (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Entrypoint для nginx-контейнера — установка корп. CA-сертификатов в Alpine,
+ */
+
+// --- docker.frontend.entrypoint.install_ca_certificates (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Устанавливает .crt файлы из /opt/certs в системное хранилище Alpine.
+ * @post Сертификаты скопированы в /usr/local/share/ca-certificates/ и добавлены в trust.
+ * @pre /opt/certs может быть пуст или не существовать.
+ */
+
+// --- docker.frontend.entrypoint.select_nginx_config (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Определяет, есть ли сертификаты для SSL, и копирует нужный nginx конфиг.
+ * @post Если есть оба файла — /etc/nginx/ssl/ создан, server.crt/key скопированы,
+ * @pre /opt/certs/server.crt и /opt/certs/server.key — опциональные SSL-сертификаты.
+ */
+
+// --- docker.nginx.ssl.conf (docker/nginx.ssl.conf)
+/**!
+ * @brief Nginx config с опциональным SSL — HTTP (порт 80) + HTTPS (порт 443).
+ */
+
+// --- AuthFixture (frontend/e2e/fixtures/auth.fixture.js)
+/**!
+ * @brief Playwright fixture for authenticated browser contexts.
+ */
+
+// --- GlobalSetup (frontend/e2e/fixtures/global-setup.js)
+/**!
+ * @brief Pre-flight check before any E2E tests run.
+ * @post Exits with 1 if either service is down, else sets ENV vars.
+ * @pre Backend and frontend must be reachable.
+ */
+
+// --- ApiHelper (frontend/e2e/helpers/api.helper.js)
+/**!
+ * @brief Helper for backend API calls in E2E tests (settings CRUD, etc.)
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::getToken (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiGet (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiPost (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiPut (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiDelete (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- run-enterprise-clean-e2e (frontend/e2e/run-enterprise-clean-e2e.sh)
+/**!
+ * @brief Enterprise Clean E2E Orchestrator — полный протокол тестирования пустого образа перед передачей.
+ */
+
+// --- EnterpriseCleanSetupE2E (frontend/e2e/tests/enterprise-clean-setup.e2e.js)
+/**!
+ * @brief Stage 1: E2E test for enterprise-clean empty image — first-run setup via StartupEnvironmentWizard.
+@@RATIONALE All 4 tests pass after fixing: (1) button ambiguity — zero-state page and wizard modal both have 'Начать настройку' button, resolved by scoping to wizard modal via .fixed.inset-0.z-50; (2) wizard detection — changed from waitForSelector('text=...') to getByText() with regex for locale-robust matching; (3) form fill — connections.* i18n keys missing in Docker build, switched to placeholder-based locators scoped within wizard; (4) settings navigation — use authPage fixture for consistent login
+@@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues
+ */
+
+// --- GitE2E (frontend/e2e/tests/git.e2e.js)
+/**!
+ * @brief E2E tests for Git integration — config CRUD, connection test.
+ */
+
+// --- LiveProjectCheckE2E (frontend/e2e/tests/live-project-check.e2e.js)
+/**!
+ * @brief Stage 2: E2E test for live project verification — validates dashboard LLM analysis,
+ */
+
+// --- LoginE2E (frontend/e2e/tests/login.e2e.js)
+/**!
+ * @brief E2E tests for login/logout flow.
+ */
+
+// --- MigrationE2E (frontend/e2e/tests/migration.e2e.js)
+/**!
+ * @brief E2E tests for dataset/environment migration and sync.
+ */
+
+// --- SettingsE2E (frontend/e2e/tests/settings.e2e.js)
+/**!
+ * @brief E2E tests for Settings page — environments, LLM providers, Git config.
+ */
+
+// --- SmokeE2E (frontend/e2e/tests/smoke.e2e.js)
+/**!
+ * @brief Golden-path smoke test: login → settings → translate → git → verify.
+ */
+
+// --- TranslationE2E (frontend/e2e/tests/translation.e2e.js)
+/**!
+ * @brief E2E tests for the translation job lifecycle: create → preview → accept → run.
+ */
+
+// --- PlaywrightConfig (frontend/playwright.config.js)
+/**!
+ * @brief Playwright E2E test configuration for ss-tools frontend.
+ * @invariant All E2E tests run against a fully deployed stack (DB + backend + frontend).
+ */
+
+// --- handleValidate:Function (frontend/src/components/DashboardGrid.svelte)
+/**!
+ * @brief Triggers dashboard validation task.
+ */
+
+// --- openGit:Function (frontend/src/components/DashboardGrid.svelte)
+/**!
+ * @brief Opens the Git management modal for a dashboard.
+ */
+
+// --- initializeForm:Function (frontend/src/components/DynamicForm.svelte)
+/**!
+ * @brief Initialize form data with default values from the schema.
+ * @post formData is initialized with default values or empty strings.
+ * @pre schema is provided and contains properties.
+ */
+
+// --- Footer (frontend/src/components/Footer.svelte)
+/**!
+ * @brief Displays the application footer with copyright information.
+ */
+
+// --- updateMapping:Function (frontend/src/components/MappingTable.svelte)
+/**!
+ * @brief Updates a mapping for a specific source database.
+ * @post Parent callback receives normalized mapping payload.
+ * @pre sourceUuid and targetUuid are provided.
+ */
+
+// --- getSuggestion:Function (frontend/src/components/MappingTable.svelte)
+/**!
+ * @brief Finds a suggestion for a source database.
+ * @post Returns matching suggestion object or undefined.
+ * @pre sourceUuid is provided.
+ */
+
+// --- MissingMappingModal (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Prompts the user to provide a database mapping when one is missing during migration.
+ * @invariant Modal blocks migration progress until resolved or cancelled.
+ */
+
+// --- resolve:Function (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Resolves the missing mapping via callback prop.
+ * @post Parent callback receives mapping payload and modal closes.
+ * @pre selectedTargetUuid must be set.
+ */
+
+// --- cancel:Function (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Cancels the mapping resolution modal.
+ * @post Parent cancel callback is invoked and modal is hidden.
+ * @pre Modal is open.
+ */
+
+// --- Navbar (frontend/src/components/Navbar.svelte)
+/**!
+ * @brief Main navigation bar for the application.
+ */
+
+// --- PasswordPrompt (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief A modal component to prompt the user for database passwords when a migration task is paused.
+ */
+
+// --- handleSubmit:Function (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief Validates and forwards passwords to resume the task.
+ * @post Parent resume callback receives passwords payload.
+ * @pre All database passwords must be entered.
+ */
+
+// --- handleCancel:Function (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief Cancels the password prompt.
+ * @post Parent cancel callback is invoked and show is set to false.
+ * @pre Modal is open.
+ */
+
+// --- handleSort:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Toggles sort direction or changes sort column.
+ * @post sortColumn and sortDirection state updated.
+ * @pre column name is provided.
+ */
+
+// --- handleSelectionChange:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Handles individual checkbox changes.
+ * @post selectedIds array updated.
+ * @pre dashboard ID and checked status provided.
+ */
+
+// --- handleSelectAll:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Handles select all checkbox.
+ * @post selectedIds array updated for all paginated items.
+ * @pre checked status provided.
+ */
+
+// --- goToPage:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Changes current page.
+ * @post currentPage state updated if within valid range.
+ * @pre page index is provided.
+ */
+
+// --- getRepositoryStatusToken:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns normalized repository status token for a dashboard.
+ * @post Returns one of loading|no_repo|synced|changes|behind_remote|ahead_remote|diverged|error.
+ * @pre Dashboard exists.
+ */
+
+// --- isRepositoryReady:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Determines whether git actions can run for a dashboard.
+ */
+
+// --- invalidateRepositoryStatuses:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Marks dashboard statuses as loading so they are refetched.
+ */
+
+// --- resolveRepositoryStatusToken:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Converts git status payload into a stable UI status token.
+ */
+
+// --- loadRepositoryStatuses:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Hydrates repository status map for dashboards in repository mode.
+ */
+
+// --- runBulkGitAction:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Executes git action for selected dashboards with limited parallelism.
+ */
+
+// --- handleBulkSync:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkCommit:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkPull:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkPush:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkDelete:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Removes selected repositories from storage and binding table.
+ */
+
+// --- handleManageSelected:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager for exactly one selected dashboard.
+ */
+
+// --- resolveDashboardRef:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Resolves dashboard slug from payload fields.
+ * @post Returns slug string or null if unavailable.
+ * @pre Dashboard metadata is provided.
+ */
+
+// --- openGitManagerForDashboard:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager for provided dashboard metadata.
+ */
+
+// --- handleInitializeRepositories:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager from bulk actions to initialize selected repository.
+ */
+
+// --- getSortStatusValue:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns sort value for status column based on mode.
+ */
+
+// --- getStatusLabel:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns localized label for status column.
+ */
+
+// --- getStatusBadgeClass:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns badge style for status column.
+ */
+
+// --- TaskHistory (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Displays a list of recent tasks with their status and allows selecting them for viewing logs.
+ */
+
+// --- getStatusColor:Function (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Returns the CSS color class for a given task status.
+ * @post Returns tailwind color class string.
+ * @pre status string is provided.
+ */
+
+// --- onDestroy:Function (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Cleans up the polling interval when the component is destroyed.
+ * @post Polling interval is cleared.
+ * @pre Component is being destroyed.
+ */
+
+// --- TaskList (frontend/src/components/TaskList.svelte)
+/**!
+ * @brief Displays a list of tasks with their status and execution details.
+ */
+
+// --- handleTaskClick:Function (frontend/src/components/TaskList.svelte)
+/**!
+ * @brief Forwards the selected task through a callback prop.
+ * @post Parent callback receives task id and task payload.
+ * @pre taskId is provided.
+ */
+
+// --- TaskLogViewer (frontend/src/components/TaskLogViewer.svelte)
+/**!
+ * @brief Displays task logs inline (in drawer) or as modal. Merges real-time WebSocket logs with polled historical logs.
+ * @invariant Real-time logs are always appended without duplicates.
+ */
+
+// --- connect:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Establishes WebSocket connection with exponential backoff and filter parameters.
+ * @post WebSocket instance created and listeners attached.
+ * @pre selectedTask must be set in the store.
+ */
+
+// --- handleFilterChange:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Handles filter changes and reconnects WebSocket with new parameters.
+ * @post WebSocket reconnected with new filter parameters, logs cleared.
+ * @pre event.detail contains source and level filter values.
+ */
+
+// --- fetchTargetDatabases:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Fetches available databases from target environment for mapping.
+ * @post targetDatabases array populated with available databases.
+ * @pre selectedTask must have to_env parameter set.
+ */
+
+// --- handleMappingResolve:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Resolves missing database mapping and continues migration.
+ * @post Mapping created in backend, task resumed with resolution params.
+ * @pre event.detail contains sourceDbUuid, targetDbUuid, targetDbName.
+ */
+
+// --- handlePasswordResume:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Submits passwords and resumes paused migration task.
+ * @post Task resumed with passwords, connection status restored to connected.
+ * @pre event.detail contains passwords object.
+ */
+
+// --- startDataTimeout:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Starts timeout timer to detect idle connection.
+ * @post waitingForData set to true after 5 seconds if no data received.
+ * @pre connectionStatus is 'connected'.
+ */
+
+// --- resetDataTimeout:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Resets data timeout timer when new data arrives.
+ * @post waitingForData reset to false, new timeout started.
+ * @pre dataTimeout must be set.
+ */
+
+// --- Toast (frontend/src/components/Toast.svelte)
+/**!
+ * @brief Displays transient notifications (toasts) in the bottom-right corner.
+ */
+
+// --- TaskLogViewerTest:Module (frontend/src/components/__tests__/task_log_viewer.test.js)
+/**!
+ * @brief Unit tests for TaskLogViewer component by mounting it and observing the DOM.
+ * @invariant Duplicate logs are never appended. Polling only active for in-progress tasks.
+ */
+
+// --- verifySessionAndAccess:Function (frontend/src/components/auth/ProtectedRoute.svelte)
+/**!
+ * @brief Validates session and optional permission gate before allowing protected content render.
+ * @post hasRouteAccess=true only when user identity is valid and permission check (if provided) passes.
+ * @pre auth store is initialized and can provide token/user state; navigation is available.
+ */
+
+// --- handleCreateBackup:Function (frontend/src/components/backups/BackupManager.svelte)
+/**!
+ * @brief Triggers a new backup task for the selected environment.
+ * @post A new task is created on the backend.
+ * @pre selectedEnvId must be a valid environment ID.
+ * @return {Promise}
+ */
+
+// --- handleUpdateSchedule:Function (frontend/src/components/backups/BackupManager.svelte)
+/**!
+ * @brief Updates the backup schedule for the selected environment.
+ * @post Environment config is updated on the backend.
+ * @pre selectedEnvId must be set.
+ */
+
+// --- loadBranches:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Загружает список веток для дашборда.
+ * @post branches обновлен.
+ * @pre dashboardId is provided.
+ */
+
+// --- handleSelect:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Handles branch selection from dropdown.
+ * @post handleCheckout is called with selected branch.
+ * @pre event contains branch name.
+ */
+
+// --- handleCheckout:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Переключает текущую ветку.
+ * @param {string} branchName - Имя ветки.
+ * @post currentBranch обновлен, родительский callback вызван.
+ */
+
+// --- handleCreate:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Создает новую ветку.
+ * @post Новая ветка создана и загружена; showCreate reset.
+ * @pre newBranchName is not empty.
+ */
+
+// --- loadHistory:Function (frontend/src/components/git/CommitHistory.svelte)
+/**!
+ * @brief Fetch commit history from the backend.
+ * @post history state is updated.
+ * @pre dashboardId is valid.
+ */
+
+// --- handleGenerateMessage:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Generates a commit message using LLM.
+ */
+
+// --- loadStatus:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Загружает текущий статус репозитория и diff.
+ * @pre dashboardId должен быть валидным.
+ */
+
+// --- handleCommit:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Создает коммит с указанным сообщением.
+ * @post Коммит создан и модальное окно закрыто.
+ * @pre message не должно быть пустым.
+ */
+
+// --- loadStatus:Watcher (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ */
+
+// --- normalizeEnvStage:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Normalize environment stage with legacy production fallback.
+ * @post Returns DEV/PREPROD/PROD.
+ */
+
+// --- resolveEnvUrl:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Resolve environment URL from consolidated or git-specific payload shape.
+ * @post Returns stable URL string.
+ */
+
+// --- loadEnvironments:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Fetch available environments from API.
+ * @post environments state is populated.
+ */
+
+// --- handleDeploy:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Trigger deployment to selected environment.
+ * @post Deploy request finishes and modal closes on success.
+ * @pre selectedEnv must be set.
+ */
+
+// --- GitInitPanel (frontend/src/components/git/GitInitPanel.svelte)
+/**!
+ * @brief Git initialization panel: select config, create remote repo, init local repo.
+ */
+
+// --- GitManager (frontend/src/components/git/GitManager.svelte)
+/**!
+ * @brief Central Git management UI — thin shell delegating to sub-panels and composable handlers.
+ */
+
+// --- GitMergeDialog (frontend/src/components/git/GitMergeDialog.svelte)
+/**!
+ * @brief Unfinished merge recovery dialog: abort, continue, resolve conflicts.
+ */
+
+// --- GitOperationsPanel (frontend/src/components/git/GitOperationsPanel.svelte)
+/**!
+ * @brief Git server operations panel: pull, push, and deploy actions.
+ */
+
+// --- GitReleasePanel (frontend/src/components/git/GitReleasePanel.svelte)
+/**!
+ * @brief Git release panel: promote branches via MR or direct mode.
+ */
+
+// --- GitWorkspacePanel (frontend/src/components/git/GitWorkspacePanel.svelte)
+/**!
+ * @brief Git workspace panel: sync, commit message input, diff viewer, commit action.
+ */
+
+// --- GitManagerUnfinishedMergeIntegrationTest:Module (frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js)
+/**!
+ * @brief Protect unresolved-merge dialog contract in GitManager pull flow.
+ */
+
+// --- UseGitManager (frontend/src/components/git/useGitManager.js)
+/**!
+ * @brief Composable for GitManager handler functions — extracted to reduce component size per INV_7.
+ */
+
+// --- DocPreview (frontend/src/components/llm/DocPreview.svelte)
+/**!
+ * @brief UI component for previewing generated dataset documentation before saving.
+ */
+
+// --- ProviderConfig (frontend/src/components/llm/ProviderConfig.svelte)
+/**!
+ * @brief UI form for managing LLM provider configurations.
+ */
+
+// --- ValidationReport (frontend/src/components/llm/ValidationReport.svelte)
+/**!
+ * @brief Displays the results of an LLM-based dashboard validation task.
+ */
+
+// --- provider_config_edit_contract_tests:Function (frontend/src/components/llm/__tests__/provider_config.integration.test.js)
+/**!
+ * @brief Validate edit and delete handler wiring plus normalized edit form state mapping.
+ * @post Contract checks ensure edit click cannot degrade into no-op flow.
+ * @pre ProviderConfig component source exists in expected path.
+ */
+
+// --- isDirectory:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Checks if a file object represents a directory.
+ * @param {Object} file - The file object to check.
+ * @post Returns boolean.
+ * @pre file object has mime_type property.
+ * @return {boolean} True if it's a directory, false otherwise.
+ */
+
+// --- formatSize:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Formats file size in bytes into a human-readable string.
+ * @param {number} bytes - The size in bytes.
+ * @post Returns formatted string.
+ * @pre bytes is a number.
+ * @return {string} Formatted size (e.g., "1.2 MB").
+ */
+
+// --- formatDate:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Formats an ISO date string into a localized readable format.
+ * @param {string} dateStr - The date string to format.
+ * @post Returns localized string.
+ * @pre dateStr is a valid date string.
+ * @return {string} Localized date and time.
+ */
+
+// --- handleDownload:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Downloads selected file through authenticated API request.
+ * @post Browser download starts or user sees toast on failure.
+ * @pre file is a non-directory storage entry with category/path.
+ */
+
+// --- handleUpload:Function (frontend/src/components/storage/FileUpload.svelte)
+/**!
+ * @brief Handles the file upload process.
+ * @post The file is uploaded to the server and a success toast is shown.
+ * @pre A file must be selected in the file input.
+ */
+
+// --- handleDrop:Function (frontend/src/components/storage/FileUpload.svelte)
+/**!
+ * @brief Handles the file drop event for drag-and-drop.
+ * @param {DragEvent} event - The drop event.
+ */
+
+// --- LogEntryRow (frontend/src/components/tasks/LogEntryRow.svelte)
+/**!
+ * @brief Renders a single log entry with stacked layout optimized for narrow drawer panels.
+ */
+
+// --- formatTime:Function (frontend/src/components/tasks/LogEntryRow.svelte)
+/**!
+ * @brief Format ISO timestamp to HH:MM:SS
+ */
+
+// --- LogFilterBar (frontend/src/components/tasks/LogFilterBar.svelte)
+/**!
+ * @brief Compact filter toolbar for logs — level, source, and text search in a single dense row.
+ */
+
+// --- TaskLogPanel (frontend/src/components/tasks/TaskLogPanel.svelte)
+/**!
+ * @brief Combines log filtering and display into a single cohesive light-themed panel.
+ * @invariant Must always display logs in chronological order and respect auto-scroll preference.
+ */
+
+// --- TaskResultPanel (frontend/src/components/tasks/TaskResultPanel.svelte)
+/**!
+ * @brief Displays formatted task result summary with status badges and result details.
+ */
+
+// --- handleRunDebug:Function (frontend/src/components/tools/DebugTool.svelte)
+/**!
+ * @brief Triggers the debug task.
+ * @post Task is started and polling begins.
+ * @pre Required fields are selected.
+ * @return {Promise}
+ */
+
+// --- startPolling:Function (frontend/src/components/tools/DebugTool.svelte)
+/**!
+ * @brief Polls for task completion.
+ * @param {string} taskId - ID of the task.
+ * @post Polls until success/failure.
+ * @pre Task ID is valid.
+ * @return {void}
+ */
+
+// --- MapperTool (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief UI component for mapping dataset column verbose names using Superset SQL Lab or Excel files.
+ */
+
+// --- fetchData:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Fetches environments.
+ * @post envs array is populated.
+ * @pre None.
+ */
+
+// --- handleRunMapper:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Triggers the MapperPlugin task via new sqllab/excel sources.
+ * @post Mapper task is started and selectedTask is updated.
+ * @pre selectedEnv and datasetId are set; source-specific fields are valid.
+ */
+
+// --- handleGenerateDocs:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Triggers the LLM Documentation task.
+ * @post Documentation task is started.
+ * @pre selectedEnv and datasetId are set.
+ */
+
+// --- Counter (frontend/src/lib/Counter.svelte)
+/**!
+ * @brief Simple counter demo component
+ */
+
+// --- ApiModule (frontend/src/lib/api.js)
+/**!
+ * @brief Handles all communication with the backend API via fetch wrappers with auth, error normalization, and toast feedback.
+ */
+
+// --- ReportsApiTest (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+ */
+
+// --- ReportsApiTest:Module (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+ * @invariant Pure functions produce deterministic output. Async wrappers propagate structured errors.
+ */
+
+// --- TestBuildReportQueryString:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate query string construction from filter options.
+ * @post Correct URLSearchParams string produced.
+ * @pre Options object with various filter fields.
+ */
+
+// --- TestNormalizeApiError:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate error normalization for UI-state mapping.
+ * @post Always returns {message, code, retryable} object.
+ * @pre Various error types (Error, string, object).
+ */
+
+// --- TestGetReportsAsync:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate getReports and getReportDetail with mocked api.fetchApi.
+ * @post Functions call correct endpoints and propagate results/errors.
+ * @pre api.fetchApi is mocked via vi.mock.
+ */
+
+// --- AssistantApi (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, conversation management, and history retrieval.
+ */
+
+// --- AssistantApi:Module (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, and history retrieval.
+ * @invariant All assistant requests must use requestApi wrapper (no native fetch).
+ */
+
+// --- sendAssistantMessage:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Send a user message to assistant orchestrator endpoint.
+ * @post Returns assistant response object with deterministic state.
+ * @pre payload.message is a non-empty string.
+ */
+
+// --- buildAssistantSeedMessage:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Compose visible assistant seed text from context label and prompt body.
+ * @post Returns trimmed seed message string for prefilled input.
+ * @pre prompt contains the user-visible request.
+ */
+
+// --- confirmAssistantOperation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Confirm a pending risky assistant operation.
+ * @post Returns execution response (started/success/failed).
+ * @pre confirmationId references an existing pending token.
+ */
+
+// --- cancelAssistantOperation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Cancel a pending risky assistant operation.
+ * @post Operation is cancelled and cannot be executed by this token.
+ * @pre confirmationId references an existing pending token.
+ */
+
+// --- getAssistantHistory:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Retrieve paginated assistant conversation history.
+ * @post Returns a paginated payload with history items.
+ * @pre page/pageSize are positive integers.
+ */
+
+// --- getAssistantConversations:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Retrieve paginated conversation list for assistant sidebar/history switcher.
+ * @post Returns paginated conversation summaries.
+ * @pre page/pageSize are positive integers.
+ */
+
+// --- deleteAssistantConversation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Soft-delete or hard-delete a conversation.
+ * @post Returns success status.
+ * @pre conversationId string is provided.
+ */
+
+// --- DatasetReviewApi (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and session DTO normalization.
+ */
+
+// --- DatasetReviewApi:Module (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Provide shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and refreshed session DTO normalization.
+ */
+
+// --- buildDatasetReviewRequestOptions:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Attach optimistic-lock session version header when the current version is known.
+ * @post Returns requestApi-compatible options object.
+ * @pre sessionVersion may be null when no loaded session version exists yet.
+ */
+
+// --- requestDatasetReviewApi:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Proxy dataset review mutations through requestApi with optional optimistic-lock headers.
+ * @post Executes requestApi with X-Session-Version only when a session version is known.
+ * @pre endpoint and method are valid requestApi inputs.
+ */
+
+// --- isDatasetReviewConflictError:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Detect optimistic-lock conflicts from dataset review mutations.
+ * @post Returns true when the mutation failed with 409 conflict semantics.
+ * @pre error may be null or a normalized API error.
+ */
+
+// --- getDatasetReviewConflictMessage:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Return explicit 409-style guidance for stale dataset review mutations.
+ * @post Returns a user-facing conflict message string.
+ * @pre error may be null or a normalized API error.
+ */
+
+// --- extractDatasetReviewVersion:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Resolve the latest session version from refreshed DTO fragments.
+ * @post Returns the newest known session version or null.
+ * @pre payload may be a session summary, a detail payload, or a mutation fragment.
+ */
+
+// --- normalizeDatasetReviewDetail:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Normalize refreshed session-detail DTOs into the legacy route-friendly workspace shape.
+ * @post Returns a shape with flattened summary fields plus refreshed collections and version metadata.
+ * @pre detail may already be legacy-flat or refreshed with nested session/session_version fields.
+ */
+
+// --- MaintenanceApi (frontend/src/lib/api/maintenance.js)
+/**!
+ * @brief API client for Maintenance Banner endpoints. Uses requestApi for all calls.
+ */
+
+// --- frontend/src/lib/api/maintenance.js::startMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::endMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::endAllMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::getSettings (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::updateSettings (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::listEvents (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::listDashboardBanners (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- ReportsApi (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Wrapper-based reports API client for list/detail retrieval through the shared API wrapper.
+ * @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+ * @pre Shared API wrapper is configured for the current frontend auth/session context.
+ */
+
+// --- ReportsApi:Module (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Wrapper-based reports API client for list/detail retrieval without direct native fetch usage.
+ * @invariant Uses existing api wrapper methods and returns structured errors for UI-state mapping.
+ * @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+ * @pre Shared API wrapper is configured for the current frontend auth/session context.
+ */
+
+// --- buildReportQueryString:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Build query string for reports list endpoint from filter options.
+ * @post Returns URL query string without leading '?'.
+ * @pre options is an object with optional report query fields.
+ */
+
+// --- normalizeApiError:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Convert unknown API exceptions into deterministic UI-consumable error objects.
+ * @post Returns structured error object.
+ * @pre error may be Error/string/object.
+ */
+
+// --- getReports:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Fetch unified report list using existing request wrapper.
+ * @post Returns parsed payload or structured error for UI-state mapping.
+ * @pre valid auth context for protected endpoint.
+ */
+
+// --- getReportDetail:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Fetch one report detail by report_id.
+ * @post Returns parsed detail payload or structured error object.
+ * @pre reportId is non-empty string; valid auth context.
+ */
+
+// --- TranslateApi (frontend/src/lib/api/translate.js)
+/**!
+ * @brief Barrel module re-exporting all translate API functions from domain-split modules.
+ */
+
+// --- TargetSchemaApiTest (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief Unit tests for checkTargetTableSchema API client fetch wrapper.
+ */
+
+// --- test_success (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief Happy path — API returns full validation result.
+ */
+
+// --- test_api_error (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief API error returns fallback response with error message.
+ */
+
+// --- test_error_string_fallback (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief String error is captured as message.
+ */
+
+// --- TranslateCorrectionsApi (frontend/src/lib/api/translate/corrections.js)
+/**!
+ * @brief API client for translation corrections — inline edits, dictionary submission, bulk find-and-replace, CSV download.
+ */
+
+// --- TranslateDatasourcesApi (frontend/src/lib/api/translate/datasources.js)
+/**!
+ * @brief API client for translation datasources — column fetching, preview, row-level review actions.
+ */
+
+// --- TranslateDictionariesApi (frontend/src/lib/api/translate/dictionaries.js)
+/**!
+ * @brief API client for translation dictionary CRUD — list, create, update, delete, entries, import.
+ */
+
+// --- TranslateJobsApi (frontend/src/lib/api/translate/jobs.js)
+/**!
+ * @brief API client for translation job CRUD — list, create, update, delete, duplicate.
+ */
+
+// --- TranslateRunsApi (frontend/src/lib/api/translate/runs.js)
+/**!
+ * @brief API client for translation run control — trigger, status, history, records, retry, cancel, metrics.
+ */
+
+// --- TranslateSchedulesApi (frontend/src/lib/api/translate/schedules.js)
+/**!
+ * @brief API client for translation job scheduling — CRUD, enable/disable, next executions.
+ */
+
+// --- TranslateTargetSchemaApi (frontend/src/lib/api/translate/target-schema.js)
+/**!
+ * @brief API client for target table schema validation.
+ */
+
+// --- frontend/src/lib/api/translate/target-schema.js::checkTargetTableSchema (frontend/src/lib/api/translate/target-schema.js)
+/**!
+ */
+
+// --- ValidationApi (frontend/src/lib/api/validation.js)
+/**!
+ * @brief API client functions for the Validation section — tasks and runs CRUD.
+ */
+
+// --- buildParams:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @brief Build URLSearchParams from a params object, skipping null/undefined/empty values.
+ * @param {Record} params
+ */
+
+// --- frontend/src/lib/api/validation.js::buildParams (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchTasks (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- createTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {Record} data
+ */
+
+// --- frontend/src/lib/api/validation.js::createTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- updateTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id @param {Record} data
+ */
+
+// --- frontend/src/lib/api/validation.js::updateTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- deleteTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id @param {boolean} [deleteRuns]
+ */
+
+// --- frontend/src/lib/api/validation.js::deleteTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- triggerRun:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::triggerRun (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- duplicateTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::duplicateTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchRuns:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {{ task_id?: string, dashboard_id?: string, environment_id?: string, status?: string, date_from?: string, date_to?: string, page?: number, page_size?: number }} [params]
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchRuns (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchRunDetail:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchRunDetail (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- deleteRun:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::deleteRun (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- PermissionsTest (frontend/src/lib/auth/__tests__/permissions.test.js)
+/**!
+ * @brief Verifies frontend RBAC permission parsing and access checks.
+ */
+
+// --- PermissionsTest:Module (frontend/src/lib/auth/__tests__/permissions.test.js)
+/**!
+ * @brief Verifies frontend RBAC permission parsing and access checks.
+ */
+
+// --- PermissionsModule (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Shared frontend RBAC utilities for route guards, permission checks, and menu visibility based on user roles.
+ */
+
+// --- Permissions:Module (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Shared frontend RBAC utilities for route guards and menu visibility.
+ * @invariant Admin role always bypasses explicit permission checks.
+ */
+
+// --- normalizePermissionRequirement:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Convert permission requirement string to canonical resource/action tuple.
+ * @post Returns normalized object with action in uppercase.
+ * @pre Permission can be "resource" or "resource:ACTION" where resource itself may contain ":".
+ */
+
+// --- isAdminUser:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Determine whether user has Admin role.
+ * @post Returns true when at least one role name equals "Admin" (case-insensitive).
+ * @pre user can be null or partially populated.
+ */
+
+// --- hasPermission:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Check if user has a required resource/action permission.
+ * @post Returns true when requirement is empty, user is admin, or matching permission exists.
+ * @pre user contains roles with permissions from /api/auth/me payload.
+ */
+
+// --- AuthStore (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Manages the global authentication state including JWT token, user profile, and login/logout lifecycle.
+ */
+
+// --- authStore:Store (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Manages the global authentication state on the frontend.
+ */
+
+// --- AuthState:Interface (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Defines the structure of the authentication state.
+ */
+
+// --- frontend/src/lib/auth/store.ts::AuthState (frontend/src/lib/auth/store.ts)
+/**!
+ */
+
+// --- createAuthStore:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Creates and configures the auth store with helper methods.
+ * @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+ * @pre No preconditions - initialization function.
+ * @return {Writable}
+ */
+
+// --- frontend/src/lib/auth/store.ts::createAuthStore (frontend/src/lib/auth/store.ts)
+/**!
+ * @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+ * @pre No preconditions - initialization function.
+ */
+
+// --- setToken:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Updates the store with a new JWT token.
+ * @param {string} token - The JWT access token.
+ * @post Store updated with new token, isAuthenticated set to true.
+ * @pre token must be a valid JWT string.
+ */
+
+// --- setUser:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Sets the current user profile data.
+ * @param {any} user - The user profile object.
+ * @post Store updated with user, isAuthenticated true, loading false.
+ * @pre User object must contain valid profile data.
+ */
+
+// --- logout:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Clears authentication state and storage.
+ * @post Auth token removed from localStorage, store reset to initial state.
+ * @pre User is currently authenticated.
+ */
+
+// --- setLoading:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Updates the loading state.
+ * @param {boolean} loading - Loading status.
+ * @post Store loading state updated.
+ * @pre None.
+ */
+
+// --- AssistantClarificationCard (frontend/src/lib/components/assistant/AssistantClarificationCard.svelte)
+/**!
+ * @brief Render the active dataset-review clarification queue inside AssistantChatPanel so users can answer, skip, defer, and resume questions without leaving the assistant workspace.
+ * @post Clarification queue state is readable in-chat and answer mutations refresh the active question state without requiring a dedicated dialog.
+ * @pre sessionId belongs to the current dataset review workspace and the assistant drawer is open for session-scoped work.
+ */
+
+// --- readJson:Function (frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js)
+/**!
+ * @brief Read and parse JSON fixture file from disk.
+ * @post Returns parsed object representation.
+ * @pre filePath points to existing UTF-8 JSON file.
+ */
+
+// --- AssistantClarificationIntegrationTest:Module (frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js)
+/**!
+ * @brief Verify AssistantChatPanel hosts the resumable dataset-review clarification flow inside the assistant drawer and refreshes workspace session state after answering.
+ */
+
+// --- AssistantFirstMessageIntegrationTest:Module (frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js)
+/**!
+ * @brief Verify first optimistic user message stays visible while a new conversation request is pending.
+ * @invariant Starting a new conversation must not trigger history reload that overwrites the first local user message.
+ */
+
+// --- assistant_first_message_tests:Function (frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js)
+/**!
+ * @brief Guard optimistic first-message UX against history reload race in new conversation flow.
+ * @post First user message remains visible before pending send request resolves.
+ * @pre Assistant panel renders with open state and mocked network dependencies.
+ */
+
+// --- CompiledSQLPreview (frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte)
+/**!
+ * @brief Present the exact Superset-generated compiled SQL preview, expose readiness or staleness clearly, and preserve readable recovery paths when preview generation fails.
+ * @post Users can distinguish missing, pending, ready, stale, and error preview states and can trigger only Superset-backed preview generation.
+ * @pre Session id is available and preview state comes from the current ownership-scoped session detail payload.
+ */
+
+// --- ExecutionMappingReview (frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte)
+/**!
+ * @brief Review imported-filter to template-variable mappings, surface effective values and blockers, and require explicit approval for warning-sensitive execution inputs before preview or launch.
+ * @post Users can review effective mapping values, approve warning-sensitive transformations, or manually override them while unresolved required-value blockers remain visible.
+ * @pre Session id, execution mappings, imported filters, and template variables belong to the current ownership-scoped session payload.
+ */
+
+// --- LaunchConfirmationPanel (frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte)
+/**!
+ * @brief Summarize final execution context, surface launch blockers explicitly, and confirm only a gate-complete SQL Lab launch request.
+ * @post Users can see why launch is blocked or confirm a run-ready launch with explicit SQL Lab handoff evidence.
+ * @pre Session detail, mappings, findings, preview state, and latest run context belong to the current ownership-scoped session payload.
+ */
+
+// --- SemanticLayerReview (frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte)
+/**!
+ * @brief Surface field-level semantic decisions with provenance, confidence, candidate acceptance, and manual override safeguards for US2 review flow.
+ * @post Users can review the current semantic value, accept a candidate, apply manual override, and lock or unlock field state without violating backend provenance rules.
+ * @pre Session id is available and semantic field entries come from the current ownership-scoped session detail payload.
+ */
+
+// --- SourceIntakePanel (frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte)
+/**!
+ * @brief Collect initial dataset source input through Superset link paste or dataset selection entry paths.
+ */
+
+// --- ValidationFindingsPanel (frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte)
+/**!
+ * @brief Present validation findings grouped by severity with explicit resolution and actionability signals.
+ */
+
+// --- SourceIntakePanelUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js)
+/**!
+ * @brief Verify source intake entry paths, validation feedback, and submit payload behavior for US1.
+ */
+
+// --- DatasetReviewUs2WorkspaceUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js)
+/**!
+ * @brief Verify US2 dataset review surfaces keep semantic review actionable, route clarification through AssistantChatPanel, and preserve explicit preview/mapping gates.
+ */
+
+// --- DatasetReviewUs3UxTests:Module (frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js)
+/**!
+ * @brief Verify US3 mapping review, Superset preview, and launch confirmation UX contracts.
+ */
+
+// --- ValidationFindingsPanelUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js)
+/**!
+ * @brief Verify grouped findings visibility, empty state, and remediation jump behavior for US1.
+ */
+
+// --- HealthMatrix (frontend/src/lib/components/health/HealthMatrix.svelte)
+/**!
+ * @brief Visual grid summary representing dashboard health status counts.
+ */
+
+// --- PolicyForm (frontend/src/lib/components/health/PolicyForm.svelte)
+/**!
+ * @brief Form for creating and editing validation policies.
+ * @post Form submission forwards the current draft to onSave and cancel delegates dismissal to the parent callback without mutating external state directly.
+ * @pre Parent provides callable onSave/onCancel handlers and an environments collection that may be empty but remains array-like.
+ */
+
+// --- ScheduleAtAGlance (frontend/src/lib/components/health/ScheduleAtAGlance.svelte)
+/**!
+ * @brief Compact weekly schedule widget showing active validation tasks with day grid, time windows, and cross-referenced health status.
+ */
+
+// --- Sidebar (frontend/src/lib/components/layout/Sidebar.svelte)
+/**!
+ * @brief Persistent left sidebar with grouped sections (Resources/Operations/System), expand/collapse, health indicators, RBAC filtering, profile footer.
+ */
+
+// --- disconnectWebSocket:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Disconnects the active WebSocket connection
+ * @post ws is closed and set to null
+ * @pre ws may or may not be initialized
+ */
+
+// --- loadRecentTasks:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Load recent tasks for list mode display
+ * @post recentTasks array populated with task list
+ * @pre User is on task drawer or api is ready.
+ */
+
+// --- selectTask:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Select a task from list to view details
+ * @post drawer state updated to show task details
+ * @pre task is a valid task object
+ */
+
+// --- goBackToList:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Return to task list view from task details
+ * @post Drawer switches to list view and reloads tasks
+ * @pre Drawer is open and activeTaskId is set
+ */
+
+// --- SidebarNavigationTest:Module (frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js)
+/**!
+ * @brief Verifies RBAC-based sidebar sections and category visibility.
+ */
+
+// --- BreadcrumbsContractTest:Module (frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for Breadcrumbs.svelte logic and UX annotations
+ */
+
+// --- SidebarStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js)
+/**!
+ * @brief Unit tests for Sidebar.svelte component
+ */
+
+// --- TaskDrawerStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js)
+/**!
+ * @brief Unit tests for TaskDrawer.svelte component
+ */
+
+// --- TopNavbarStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js)
+/**!
+ * @brief Unit tests for TopNavbar.svelte component
+ */
+
+// --- PageContracts (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Contract implemented by all Svelte route pages — defines page-level behavior and routing structure.
+ */
+
+// --- NavigationContracts (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Contract for navigation structure — sidebar sections, route categories, and menu item hierarchy.
+ */
+
+// --- SidebarNavigation:Module (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Build sidebar navigation sections and categories filtered by user permissions and feature flags.
+ * @invariant Admin role can access all categories and subitems through permission utility.
+ */
+
+// --- isItemAllowed:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Check whether a single menu node can be shown for a given user.
+ * @post Returns true when no permission is required or permission check passes.
+ * @pre item can contain optional requiredPermission/requiredAction.
+ */
+
+// --- isFeatureEnabled:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ */
+
+// --- buildSidebarSections:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Build translated sidebar sections with categories, filtered by RBAC permissions and feature flags.
+ * @post Returns only sections/categories/subitems available for provided user and enabled features.
+ * @pre i18nState provides nav labels; user can be null; features default to {} (all enabled).
+ */
+
+// --- ReportCardTest:Module (frontend/src/lib/components/reports/__tests__/report_card.ux.test.js)
+/**!
+ * @brief Test UX states and transitions for ReportCard component
+ * @invariant Each test asserts at least one observable UX contract outcome.
+ */
+
+// --- ReportDetailIntegrationTest:Module (frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js)
+/**!
+ * @brief Validate detail-panel behavior for failed reports and recovery guidance visibility.
+ * @invariant Failed report detail exposes actionable next actions when available.
+ */
+
+// --- ReportDetailUxTest:Module (frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js)
+/**!
+ * @brief Test UX states and recovery for ReportDetailPanel component
+ * @invariant Detail UX tests keep placeholder-safe rendering and recovery visibility verifiable.
+ */
+
+// --- [EXT:frontend:ReportTypeProfiles]Test:Module (frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js)
+/**!
+ * @brief Validate report type profile mapping and unknown fallback behavior.
+ * @invariant Unknown task_type always resolves to the fallback profile.
+ */
+
+// --- ReportsFilterPerformanceTest:Module (frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js)
+/**!
+ * @brief Guard test for report filter responsiveness on moderate in-memory dataset.
+ */
+
+// --- ReportsListTest:Module (frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js)
+/**!
+ * @brief Test ReportsList component iteration and event forwarding.
+ */
+
+// --- ReportsPageTest:Module (frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js)
+/**!
+ * @brief Integration-style checks for unified mixed-type reports rendering expectations.
+ * @invariant Mixed fixture includes all supported report types in one list.
+ */
+
+// --- ReportTypeProfiles:Module (frontend/src/lib/components/reports/reportTypeProfiles.js)
+/**!
+ * @brief Deterministic mapping from report task_type to visual profile with one fallback.
+ */
+
+// --- getReportTypeProfile:Function (frontend/src/lib/components/reports/reportTypeProfiles.js)
+/**!
+ * @brief Resolve visual profile by task type with guaranteed fallback.
+ * @post Returns one profile object.
+ * @pre taskType may be known/unknown/empty.
+ */
+
+// --- ApiKeysTab (frontend/src/lib/components/settings/ApiKeysTab.svelte)
+/**!
+ * @brief API Key management tab — list, generate (one-time reveal), and revoke API keys.
+ */
+
+// --- BulkCorrectionSidebar (frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte)
+/**!
+ * @brief Component component: lib/components/translate/BulkCorrectionSidebar.svelte
+ */
+
+// --- BulkReplaceModal (frontend/src/lib/components/translate/BulkReplaceModal.svelte)
+/**!
+ * @brief Modal dialog for bulk find-and-replace on translated values within a completed run.
+ */
+
+// --- CorrectionCell (frontend/src/lib/components/translate/CorrectionCell.svelte)
+/**!
+ * @brief Inline-editable cell for translation run results with edit-save-cancel UX and submit-to-dictionary flow.
+ */
+
+// --- ScheduleConfig (frontend/src/lib/components/translate/ScheduleConfig.svelte)
+/**!
+ * @brief Component component: lib/components/translate/ScheduleConfig.svelte
+ */
+
+// --- TargetSchemaHint (frontend/src/lib/components/translate/TargetSchemaHint.svelte)
+/**!
+ * @brief Подсказка о колонках целевой таблицы + кнопка "Проверить схему".
+ */
+
+// --- TermCorrectionPopup (frontend/src/lib/components/translate/TermCorrectionPopup.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TermCorrectionPopup.svelte
+ */
+
+// --- TranslationMetricsDashboard (frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationMetricsDashboard.svelte
+ */
+
+// --- TranslationPreview (frontend/src/lib/components/translate/TranslationPreview.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationPreview.svelte
+ */
+
+// --- TranslationRunGlobalIndicator (frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte)
+/**!
+ * @brief Persistent rich progress panel for active translation runs, rendered in root layout.
+ */
+
+// --- TranslationRunProgress (frontend/src/lib/components/translate/TranslationRunProgress.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationRunProgress.svelte
+ */
+
+// --- TranslationRunResult (frontend/src/lib/components/translate/TranslationRunResult.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationRunResult.svelte
+ */
+
+// --- TargetSchemaHintTest (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Contract-focused unit tests for TargetSchemaHint.svelte component.
+ */
+
+// --- test_component_exists (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Verify component file exists.
+ */
+
+// --- test_ux_state_contracts (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component contains required UX state tags.
+ */
+
+// --- test_props_definition (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component accepts required props.
+ */
+
+// --- test_button_check_disabled_logic (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Button disabled logic: canCheck derived checks all required props.
+ */
+
+// --- test_idle_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Idle state shows hint text and check button.
+ */
+
+// --- test_checking_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Checking state shows spinner and disables button.
+ */
+
+// --- test_complete_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Complete state shows result with green/yellow/red indicators.
+ */
+
+// --- test_error_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Error state shows connection error message.
+ */
+
+// --- test_i18n_usage (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component uses i18n _() for all user-facing strings with fallbacks.
+ */
+
+// --- test_abort_controller (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component uses AbortController for request cancellation.
+ */
+
+// --- BulkReplaceModalTests (frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for BulkReplaceModal.svelte component.
+ */
+
+// --- CorrectionCellTests (frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for CorrectionCell.svelte component.
+ */
+
+// --- test_component_file_exists:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify component file exists and has required contracts
+ */
+
+// --- TranslateApiTests:Class (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Unit tests for translate API preview functions.
+ */
+
+// --- test_fetchPreview:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify fetchPreview calls postApi with correct endpoint and payload.
+ */
+
+// --- test_approveRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify approveRow calls requestApi with correct action.
+ */
+
+// --- test_editRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify editRow calls requestApi with edit action and translation.
+ */
+
+// --- test_rejectRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify rejectRow calls requestApi with reject action.
+ */
+
+// --- test_acceptPreview:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify acceptPreview calls postApi with correct endpoint.
+ */
+
+// --- test_fetchPreviewRecords:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify fetchPreviewRecords calls fetchApi with correct endpoint.
+ */
+
+// --- test_normalizeTranslateError:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify API errors are normalized consistently.
+ */
+
+// --- I18nModule (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Centralized internationalization management using Svelte stores with Russian and English locale support persisted in LocalStorage.
+ */
+
+// --- i18n:Module (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Centralized internationalization management using Svelte stores.
+ * @invariant Persistence is handled via LocalStorage.
+ */
+
+// --- locale:Store (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Holds the current active locale string.
+ */
+
+// --- t:Store (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Derived store providing the translation dictionary.
+ */
+
+// --- _:Function (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Get translation by key path.
+ * @param key - Translation key path (e.g., 'nav.dashboard')
+ * @return Translation string or key if not found
+ */
+
+// --- frontend/src/lib/i18n/index.ts::_ (frontend/src/lib/i18n/index.ts)
+/**!
+ */
+
+// --- StoresModule (frontend/src/lib/stores.js)
+/**!
+ * @brief Global Svelte writable stores for plugins, tasks, and UI page state management.
+ */
+
+// --- stores_module:Module (frontend/src/lib/stores.js)
+/**!
+ * @brief Global state management using Svelte stores.
+ */
+
+// --- plugins:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the list of available plugins.
+ */
+
+// --- tasks:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the list of tasks.
+ */
+
+// --- selectedPlugin:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the currently selected plugin.
+ */
+
+// --- selectedTask:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the currently selected task.
+ */
+
+// --- currentPage:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the current page.
+ */
+
+// --- taskLogs:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the logs of the currently selected task.
+ */
+
+// --- fetchPlugins:Function (frontend/src/lib/stores.js)
+/**!
+ * @brief Fetches plugins from the API and updates the plugins store.
+ * @post plugins store is updated with data from the API.
+ * @pre None.
+ */
+
+// --- fetchTasks:Function (frontend/src/lib/stores.js)
+/**!
+ * @brief Fetches tasks from the API and updates the tasks store.
+ * @post tasks store is updated with data from the API.
+ * @pre None.
+ */
+
+// --- [EXT:frontend:AssistantChatTest]s (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Unit tests for assistant chat store validating open/close/toggle, conversation binding, session context, and seed message state transitions.
+ */
+
+// --- [EXT:frontend:AssistantChatTest]:Module (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Validate assistant chat store visibility and conversation binding transitions.
+ * @invariant Each test starts from default closed state.
+ */
+
+// --- assistantChatStore_tests:Function (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Group store unit scenarios for assistant panel behavior.
+ * @post Open/close/toggle/conversation transitions are validated.
+ * @pre Store can be reset to baseline state in beforeEach hook.
+ */
+
+// --- MockEnvPublic (frontend/src/lib/stores/__tests__/mocks/env_public.js)
+/**!
+ */
+
+// --- mock_env_public:Module (frontend/src/lib/stores/__tests__/mocks/env_public.js)
+/**!
+ * @brief Mock for $env/static/public SvelteKit module in vitest
+ */
+
+// --- EnvironmentMock (frontend/src/lib/stores/__tests__/mocks/environment.js)
+/**!
+ * @brief Mock for $app/environment in vitest, supplying browser, dev, and building flags.
+ */
+
+// --- EnvironmentMock:Module (frontend/src/lib/stores/__tests__/mocks/environment.js)
+/**!
+ * @brief Mock for $app/environment in tests
+ */
+
+// --- NavigationMock (frontend/src/lib/stores/__tests__/mocks/navigation.js)
+/**!
+ * @brief Mock for $app/navigation in vitest, supplying goto, push, replace, prefetch, and prefetchRoutes stubs.
+ */
+
+// --- NavigationMock:Module (frontend/src/lib/stores/__tests__/mocks/navigation.js)
+/**!
+ * @brief Mock for $app/navigation in tests
+ * @invariant Includes SvelteKit v1-only APIs (push, prefetchRoutes) as compatibility surface for legacy test consumers; keep until all imports migrate to SvelteKit v2-compatible mocks.
+ */
+
+// --- StateMock (frontend/src/lib/stores/__tests__/mocks/state.js)
+/**!
+ * @brief Mock for $app/state page data in vitest route/component tests, supplying default params, route, URL, status, and data.
+ */
+
+// --- state_mock:Module (frontend/src/lib/stores/__tests__/mocks/state.js)
+/**!
+ * @brief Mock for AppState in vitest route/component tests.
+ */
+
+// --- StoresMock (frontend/src/lib/stores/__tests__/mocks/stores.js)
+/**!
+ */
+
+// --- StoresMock:Module (frontend/src/lib/stores/__tests__/mocks/stores.js)
+/**!
+ * @brief Mock for $app/stores in tests
+ * @invariant Mocks $app/stores which is a SvelteKit v1 module; SvelteKit v2 uses $app/state. Verify no active test files import this mock before removal.
+ */
+
+// --- SetupTestsModule (frontend/src/lib/stores/__tests__/setupTests.js)
+/**!
+ * @brief Global vitest test setup with mocks for SvelteKit modules ($app/environment, $app/stores, $app/navigation, localStorage).
+ */
+
+// --- setupTests:Module (frontend/src/lib/stores/__tests__/setupTests.js)
+/**!
+ * @brief Global test setup with mocks for SvelteKit modules
+ */
+
+// --- SidebarTest (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Unit tests for sidebar store validating expansion toggles, active item selection, and mobile open/close transitions.
+ */
+
+// --- SidebarTest:Module (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Unit tests for sidebar store
+ * @invariant Sidebar store transitions must be deterministic across desktop/mobile toggles.
+ */
+
+// --- test_sidebar_initial_state:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify initial sidebar store values when no persisted state is available.
+ * @post Default state is { isExpanded: true, activeCategory: 'dashboards', activeItem: '/dashboards', isMobileOpen: false }
+ * @pre No localStorage state
+ * @test Store initializes with default values
+ */
+
+// --- test_toggleSidebar:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify desktop sidebar expansion toggles deterministically.
+ * @post isExpanded is toggled from previous value
+ * @pre Store is initialized
+ * @test toggleSidebar toggles isExpanded state
+ */
+
+// --- test_setActiveItem:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify active-category updates remain deterministic after item selection.
+ * @post activeCategory and activeItem are updated
+ * @pre Store is initialized
+ * @test setActiveItem updates activeCategory and activeItem
+ */
+
+// --- test_mobile_functions:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify mobile sidebar helpers update open-state transitions predictably.
+ * @post isMobileOpen is correctly updated
+ * @pre Store is initialized
+ * @test Mobile functions correctly update isMobileOpen
+ */
+
+// --- TaskDrawerTests (frontend/src/lib/stores/__tests__/taskDrawer.test.js)
+/**!
+ * @brief Unit tests for task drawer store validating open/close, preference-aware opening, resource task mapping, and status-driven cleanup.
+ */
+
+// --- ActivityTestModule (frontend/src/lib/stores/__tests__/test_activity.js)
+/**!
+ * @brief Unit tests validating activity store derived count and recent task tracking behavior.
+ */
+
+// --- ActivityTest:Module (frontend/src/lib/stores/__tests__/test_activity.js)
+/**!
+ * @brief Unit tests for activity store
+ */
+
+// --- DatasetReviewSessionTests (frontend/src/lib/stores/__tests__/test_datasetReviewSession.js)
+/**!
+ * @brief Unit tests for dataset review session store: session set/reset, loading, error, dirty flag, and patch operations.
+ */
+
+// --- DatasetReviewSessionStoreTests:Module (frontend/src/lib/stores/__tests__/test_datasetReviewSession.js)
+/**!
+ * @brief Unit tests for dataset review session store.
+ */
+
+// --- SidebarTestModule (frontend/src/lib/stores/__tests__/test_sidebar.js)
+/**!
+ * @brief Unit tests for sidebar store validating initial state, toggle, navigation, mobile overlay, and localStorage persistence.
+ */
+
+// --- SidebarIntegrationTest:Module (frontend/src/lib/stores/__tests__/test_sidebar.js)
+/**!
+ * @brief Unit tests for sidebar store
+ */
+
+// --- TaskDrawerTestModule (frontend/src/lib/stores/__tests__/test_taskDrawer.js)
+/**!
+ * @brief Unit tests for task drawer store validating open/close transitions, preference-aware opening, and resource-task mapping lifecycle.
+ */
+
+// --- TaskDrawerTest:Module (frontend/src/lib/stores/__tests__/test_taskDrawer.js)
+/**!
+ * @brief Unit tests for task drawer store
+ * @invariant Store state transitions remain deterministic for open/close and task-status mapping.
+ */
+
+// --- ActivityStore (frontend/src/lib/stores/activity.js)
+/**!
+ * @brief Derived store that counts active running tasks for navbar indicator badge.
+ */
+
+// --- activity:Store (frontend/src/lib/stores/activity.js)
+/**!
+ * @brief Track active task count for navbar indicator
+ */
+
+// --- AssistantChatStore (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Control assistant chat panel visibility, conversation binding, session context, and seeded prompts.
+ */
+
+// --- assistantChat:Store (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Control assistant chat panel visibility and active conversation binding.
+ */
+
+// --- toggleAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Toggle assistant panel visibility.
+ * @post isOpen value inverted.
+ * @pre Store is initialized.
+ */
+
+// --- openAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Open assistant panel.
+ * @post isOpen = true.
+ * @pre Store is initialized.
+ */
+
+// --- openAssistantChatWithContext:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Open assistant panel with dataset review session context and optional seeded prompt/focus target.
+ * @post Assistant drawer opens with session binding and visible focus metadata.
+ * @pre Context payload may be partial.
+ */
+
+// --- closeAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Close assistant panel.
+ * @post isOpen = false.
+ * @pre Store is initialized.
+ */
+
+// --- setAssistantConversationId:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Bind current conversation id in UI state.
+ * @post store.conversationId updated.
+ * @pre conversationId is string-like identifier.
+ */
+
+// --- setAssistantDatasetReviewSessionId:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Bind active dataset review session to assistant state.
+ * @post store.datasetReviewSessionId updated.
+ * @pre session identifier may be null when workspace context is cleared.
+ */
+
+// --- setAssistantSeedMessage:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Stage a seeded assistant prompt for contextual send UX.
+ * @post store.seedMessage updated.
+ * @pre seedMessage can be empty to clear staged draft.
+ */
+
+// --- setAssistantFocusTarget:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Track the workspace entity currently referenced by assistant context.
+ * @post store.focusTarget updated.
+ * @pre focusTarget may be null to clear prior focus.
+ */
+
+// --- DatasetReviewSessionStore (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ * @brief Manage active dataset review session state including loading, local edits, error capture, and reset semantics.
+ * @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+ * @pre Consumers provide session-shaped payloads and initialize the store before reading derived session fields.
+ */
+
+// --- datasetReviewSession:Store (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ * @brief Manage active dataset review session state, including loading, local edits, error capture, and reset semantics for the active review workspace.
+ * @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+ * @pre Consumers provide session-shaped payloads when setting or patching state and initialize the store before reading derived session fields.
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setLoading (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setError (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setDirty (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::resetSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::patchSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::getSessionUiPhase (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- EnvironmentContextStore (frontend/src/lib/stores/environmentContext.js)
+/**!
+ * @brief Global selected environment context for navigation, safety cues, and environment-based filtering.
+ */
+
+// --- environmentContext:Store (frontend/src/lib/stores/environmentContext.js)
+/**!
+ * @brief Global selected environment context for navigation and safety cues.
+ */
+
+// --- HealthStore (frontend/src/lib/stores/health.js)
+/**!
+ * @brief Manage dashboard health summary state and failing counts for UI badges.
+ */
+
+// --- health_store:Store (frontend/src/lib/stores/health.js)
+/**!
+ * @brief Manage dashboard health summary state and failing counts for UI badges.
+ */
+
+// --- frontend/src/lib/stores/health.js::createHealthStore (frontend/src/lib/stores/health.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/health.js::refresh (frontend/src/lib/stores/health.js)
+/**!
+ */
+
+// --- MaintenanceStore (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ * @brief Svelte 5 (Runes) store for maintenance banner state. Auto-polls events every 30s via interval.
+ * @return {object} Maintenance store with runes state and methods.
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::createMaintenanceStore (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- MaintenanceStore.state (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- MaintenanceStore.methods (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadEvents (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadDashboardBanners (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadSettings (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::endEvent (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::endAllEvents (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::updateSettings (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::init (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::startPolling (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::stopPolling (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- SidebarStore (frontend/src/lib/stores/sidebar.js)
+/**!
+ * @brief Manage sidebar visibility, expansion state, active navigation item, and mobile overlay.
+ */
+
+// --- sidebar:Store (frontend/src/lib/stores/sidebar.js)
+/**!
+ * @brief Manage sidebar visibility and navigation state
+ * @invariant isExpanded state is always synced with localStorage
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::toggleSidebar (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::setActiveItem (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::setMobileOpen (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::closeMobile (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::toggleMobileSidebar (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- TaskDrawerStore (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ * @brief Manage Task Drawer visibility, active task binding, and resource-to-task mapping.
+ */
+
+// --- taskDrawer:Store (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ * @brief Manage Task Drawer visibility and resource-to-task mapping
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawerForTask (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::setTaskDrawerAutoOpenPreference (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::getTaskDrawerAutoOpenPreference (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawerForTaskIfPreferred (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawer (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::closeDrawer (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::updateResourceTask (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::getTaskForResource (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- TranslationRunStore (frontend/src/lib/stores/translationRun.js)
+/**!
+ * @brief Global store for active translation run progress — survives page navigation.
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::clearOnCompleteCallback (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::startTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::stopTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::resetTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::updateTranslationRunState (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::pollStatus (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- ToastsModule (frontend/src/lib/toasts.js)
+/**!
+ * @brief Manages toast notifications using a Svelte writable store with deduplication and auto-removal.
+ */
+
+// --- toasts_module:Module (frontend/src/lib/toasts.js)
+/**!
+ * @brief Manages toast notifications using a Svelte writable store.
+ */
+
+// --- toasts:Data (frontend/src/lib/toasts.js)
+/**!
+ * @brief Writable store containing the list of active toasts.
+ */
+
+// --- addToast:Function (frontend/src/lib/toasts.js)
+/**!
+ * @brief Adds a new toast message.
+ * @param duration (number) - Duration in ms before the toast is removed.
+ * @post New toast is added to the store and scheduled for removal.
+ * @pre message string is provided.
+ */
+
+// --- removeToast:Function (frontend/src/lib/toasts.js)
+/**!
+ * @brief Removes a toast message by ID.
+ * @param id (string) - The ID of the toast to remove.
+ * @post Toast is removed from the store.
+ * @pre id is provided.
+ */
+
+// --- Button (frontend/src/lib/ui/Button.svelte)
+/**!
+ * @brief Standardized button component with variants and loading states.
+ * @invariant Supports accessible labels and keyboard navigation.
+ */
+
+// --- Card (frontend/src/lib/ui/Card.svelte)
+/**!
+ * @brief Standardized container with padding and elevation.
+ */
+
+// --- Icon (frontend/src/lib/ui/Icon.svelte)
+/**!
+ * @brief Render the shared inline SVG icon set with consistent sizing and stroke props.
+ * @invariant Icon output remains aria-hidden because labels belong to the interactive parent.
+ */
+
+// --- Input (frontend/src/lib/ui/Input.svelte)
+/**!
+ * @brief Standardized text input component with label and error handling.
+ * @invariant Consistent spacing and focus states.
+ */
+
+// --- LanguageSwitcher (frontend/src/lib/ui/LanguageSwitcher.svelte)
+/**!
+ * @brief Dropdown component to switch between supported languages.
+ */
+
+// --- PageHeader (frontend/src/lib/ui/PageHeader.svelte)
+/**!
+ * @brief Standardized page header with title and action area.
+ */
+
+// --- Select (frontend/src/lib/ui/Select.svelte)
+/**!
+ * @brief Standardized dropdown selection component.
+ */
+
+// --- ui:Module (frontend/src/lib/ui/index.ts)
+/**!
+ * @brief Central export point for standardized UI components.
+ * @invariant All components exported here must follow Semantic Protocol.
+ */
+
+// --- UtilsModule (frontend/src/lib/utils.js)
+/**!
+ */
+
+// --- Utils:Module (frontend/src/lib/utils.js)
+/**!
+ * @brief General utility functions (class merging)
+ */
+
+// --- frontend/src/lib/utils.js::cn (frontend/src/lib/utils.js)
+/**!
+ */
+
+// --- DebounceModule (frontend/src/lib/utils/debounce.js)
+/**!
+ */
+
+// --- Debounce:Module (frontend/src/lib/utils/debounce.js)
+/**!
+ * @brief Debounce utility for limiting function execution rate
+ */
+
+// --- frontend/src/lib/utils/debounce.js::debounce (frontend/src/lib/utils/debounce.js)
+/**!
+ */
+
+// --- onMount:Function (frontend/src/pages/Dashboard.svelte)
+/**!
+ * @brief Fetch plugins when the component mounts.
+ * @post plugins store is populated with available tools.
+ * @pre Component is mounting.
+ */
+
+// --- selectPlugin:Function (frontend/src/pages/Dashboard.svelte)
+/**!
+ * @brief Selects a plugin to display its form.
+ * @param {Object} plugin - The plugin object to select.
+ * @post selectedPlugin store is updated.
+ * @pre plugin object is provided.
+ */
+
+// --- loadSettings:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Loads settings from the backend.
+ * @post settings object is populated with backend data.
+ * @pre Component mounted or refresh requested.
+ */
+
+// --- handleSaveGlobal:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Saves global settings to the backend.
+ * @post Backend global settings are updated.
+ * @pre settings.settings contains valid configuration.
+ */
+
+// --- handleAddOrUpdateEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Adds or updates an environment.
+ * @post Environment list is updated on backend and reloaded locally.
+ * @pre newEnv contains valid environment details.
+ */
+
+// --- handleDeleteEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Deletes an environment.
+ * @param {string} id - The ID of the environment to delete.
+ * @post Environment is removed from backend and list is reloaded.
+ * @pre id of environment to delete is provided.
+ */
+
+// --- handleTestEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Tests the connection to an environment.
+ * @param {string} id - The ID of the environment to test.
+ * @post Connection test result is displayed via toast.
+ * @pre Environment ID is valid.
+ */
+
+// --- editEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Sets the form to edit an existing environment.
+ * @param {Object} env - The environment object to edit.
+ * @post newEnv is populated with env data and editingEnvId is set.
+ * @pre env object is provided.
+ */
+
+// --- resetEnvForm:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Resets the environment form.
+ * @post newEnv is reset to initial state and editingEnvId is cleared.
+ * @pre None.
+ */
+
+// --- ErrorPage (frontend/src/routes/+error.svelte)
+/**!
+ * @brief Global error page displaying HTTP status code and error message with navigation back to dashboard.
+ */
+
+// --- RootLayout (frontend/src/routes/+layout.svelte)
+/**!
+ * @brief Root layout component providing global UI structure: Sidebar, TopNavbar, Footer, TaskDrawer, Toasts.
+ * @invariant Sidebar width adapts (ml-60 vs ml-16) based on sidebar expanded state.
+ */
+
+// --- RootLayoutConfig:Module (frontend/src/routes/+layout.ts)
+/**!
+ * @brief Root layout configuration (SPA mode)
+ */
+
+// --- HomePage (frontend/src/routes/+page.svelte)
+/**!
+ * @brief Redirect to preferred start page (dashboards/datasets/reports) based on profile settings, with safe fallback.
+ * @invariant Redirect target resolves to one of /dashboards, /datasets, /reports.
+ */
+
+// --- load:Function (frontend/src/routes/+page.ts)
+/**!
+ * @brief Loads initial plugin data for the dashboard.
+ * @post Returns an object with plugins or an error message.
+ * @pre None.
+ */
+
+// --- frontend/src/routes/+page.ts::load (frontend/src/routes/+page.ts)
+/**!
+ */
+
+// --- openCreateModal:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Initializes state for creating a new role.
+ * @post showModal is true, roleForm is reset.
+ * @pre None.
+ */
+
+// --- openEditModal:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Initializes state for editing an existing role.
+ * @post showModal is true, roleForm is populated.
+ * @pre role object is provided.
+ */
+
+// --- handleSaveRole:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Submits role data (create or update).
+ * @post Role is saved, modal closed, data reloaded.
+ * @pre roleForm contains valid data.
+ */
+
+// --- handleDeleteRole:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Deletes a role after confirmation.
+ * @post Role is deleted if confirmed, data reloaded.
+ * @pre role object is provided.
+ */
+
+// --- handleCreateMapping:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Submits a new AD Group to Role mapping to the backend.
+ * @post A new mapping is created in the database and the table is refreshed.
+ * @pre 'newMapping' object contains valid 'ad_group' and 'role_id'.
+ * @return {Promise}
+ */
+
+// --- loadLoggingConfig:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Fetches current logging configuration from the backend.
+ * @post loggingConfig variable is updated with backend data.
+ * @pre Component is mounted and user has active session.
+ * @return {Promise}
+ */
+
+// --- saveLoggingConfig:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Saves logging configuration to the backend.
+ * @post Configuration is saved and feedback is shown.
+ * @pre loggingConfig contains valid values.
+ * @return {Promise}
+ */
+
+// --- LLMReportPage (frontend/src/routes/admin/settings/llm/+page.svelte)
+/**!
+ * @brief Admin settings page for LLM provider configuration.
+ */
+
+// --- handleSaveUser:Function (frontend/src/routes/admin/users/+page.svelte)
+/**!
+ * @brief Submits user data to the backend (create or update).
+ * @post User created or updated, modal closed, data reloaded.
+ * @pre userForm must be valid.
+ */
+
+// --- handleDeleteUser:Function (frontend/src/routes/admin/users/+page.svelte)
+/**!
+ * @brief Deletes a user after confirmation.
+ * @param {Object} user - The user to delete.
+ * @post User deleted if confirmed, data reloaded.
+ * @pre user object must be valid.
+ */
+
+// --- DashboardHub.normalizeTaskStatus:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize raw task status to stable lowercase token for UI.
+ * @post returns null or normalized token without enum namespace.
+ * @pre status can be enum-like string or null.
+ */
+
+// --- DashboardHub.normalizeValidationStatus:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize validation status to pass/fail/warn/unknown.
+ * @post returns one of pass|fail|warn|unknown.
+ * @pre status can be any scalar.
+ */
+
+// --- DashboardHub.getValidationBadgeClass:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Map validation level to badge class tuple.
+ * @post returns deterministic tailwind class string.
+ * @pre level in pass|fail|warn|unknown.
+ */
+
+// --- DashboardHub.getValidationLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Map normalized validation level to compact UI label.
+ * @post returns uppercase status label.
+ * @pre level in pass|fail|warn|unknown.
+ */
+
+// --- DashboardHub.normalizeOwners:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize owners payload to unique non-empty display labels.
+ * @post Returns owner labels preserving source order.
+ * @pre owners can be null, list of strings, or list of user objects.
+ */
+
+// --- DashboardHub.loadDashboards:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Load full dashboard dataset for current environment and hydrate grid projection.
+ * @post allDashboards, dashboards, pagination and selection state are synchronized.
+ * @pre selectedEnv is not null.
+ */
+
+// --- DashboardHub.handleTemporaryShowAll:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Temporarily disable profile-default dashboard filter for current page context.
+ * @post Next request is sent with override_show_all=true.
+ * @pre Dashboards list is loaded in dashboards_main context.
+ */
+
+// --- DashboardHub.handleRestoreProfileFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Re-enable persisted profile-default filtering after temporary override.
+ * @post Next request is sent with override_show_all=false.
+ * @pre Current page is in override mode.
+ */
+
+// --- DashboardHub.formatDate:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Convert ISO timestamp to locale date string.
+ * @post returns formatted date or "-".
+ * @pre value may be null or invalid date string.
+ */
+
+// --- DashboardHub.getGitSummaryLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute stable text label for git state column.
+ * @post returns localized summary string.
+ * @pre dashboard has git projection fields.
+ */
+
+// --- DashboardHub.getLlmSummaryLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute normalized LLM validation summary label.
+ * @post returns UNKNOWN fallback for missing status.
+ * @pre dashboard may have null lastTask.
+ */
+
+// --- DashboardHub.getColumnCellValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Resolve comparable/filterable display value for any grid column.
+ * @post returns non-empty scalar display value.
+ * @pre column belongs to filterable column set.
+ */
+
+// --- DashboardHub.getFilterOptions:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Build unique sorted value list for a column filter dropdown.
+ * @post returns de-duplicated sorted options.
+ * @pre allDashboards is hydrated.
+ */
+
+// --- DashboardHub.getVisibleFilterOptions:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Apply in-dropdown search over full filter options.
+ * @post returns subset for current filter popover list.
+ * @pre columnFilterSearch contains search token for column.
+ */
+
+// --- DashboardHub.toggleFilterDropdown:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Toggle active column filter popover.
+ * @post openFilterColumn updated.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.toggleFilterValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Add/remove specific filter value and reapply projection.
+ * @post columnFilters updated and grid reprojected from page 1.
+ * @pre value comes from option list of the same column.
+ */
+
+// --- DashboardHub.clearColumnFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Reset selected values for one column.
+ * @post filter cleared and projection refreshed.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.selectAllColumnFilterValues:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Select all currently visible values in filter popover.
+ * @post column filter equals current visible option set.
+ * @pre visible options computed for current search token.
+ */
+
+// --- DashboardHub.updateColumnFilterSearch:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Update local search token for one filter popover.
+ * @post columnFilterSearch updated immutably.
+ * @pre value is text from input.
+ */
+
+// --- DashboardHub.hasColumnFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Determine if column has active selected values.
+ * @post returns boolean activation marker.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.doesDashboardPassColumnFilters:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Evaluate dashboard row against all active column filters.
+ * @post returns true only when row matches every active filter.
+ * @pre dashboard contains projected values for each filterable column.
+ */
+
+// --- DashboardHub.getSortValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute stable comparable sort key for chosen column.
+ * @post returns string/number key suitable for deterministic comparison.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.handleSort:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Toggle or switch sort order and reapply grid projection.
+ * @post sortColumn/sortDirection updated and page reset to 1.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.getSortIndicator:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Return visual indicator for active/inactive sort header.
+ * @post returns one of ↕ | ↑ | ↓.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.applyGridTransforms:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Apply search + column filters + sort + pagination to grid data.
+ * @post filteredDashboards/dashboards/total/totalPages are synchronized.
+ * @pre allDashboards is current source collection.
+ */
+
+// --- DashboardHeader (frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte)
+/**!
+ * @brief Top title area, breadcrumb, Git branch selector, and action buttons for dashboard detail.
+ */
+
+// --- DashboardProfileOverrideIntegrationTest:Module (frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js)
+/**!
+ * @brief Verifies temporary show-all override and restore-on-return behavior for profile-default dashboard filtering.
+ */
+
+// --- HealthCenterPage (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Main page for the Dashboard Health Center showing health matrix table with environment filtering.
+ */
+
+// --- loadData:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Load health summary rows and environment options for the current filter.
+ * @post `healthData` and `environments` reflect latest backend response.
+ * @pre Page is mounted or environment selection changed.
+ */
+
+// --- handleEnvChange:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Apply environment filter and trigger health summary reload.
+ * @post selectedEnvId is updated and new data load starts.
+ * @pre DOM change event carries target value.
+ */
+
+// --- handleDeleteReport:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Delete one health report row with confirmation and optimistic button lock.
+ * @post Row is removed from backend and page data is reloaded on success.
+ * @pre item contains `record_id` from health summary payload.
+ */
+
+// --- HealthPageIntegrationTest:Module (frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js)
+/**!
+ * @brief Lock dashboard health page contract for slug navigation and report deletion.
+ */
+
+// --- DatasetHub (frontend/src/routes/datasets/+page.svelte)
+/**!
+ */
+
+// --- ColumnsTable (frontend/src/routes/datasets/ColumnsTable.svelte)
+/**!
+ * @brief Table of dataset columns with type chips, description, and inline-edit capability.
+ */
+
+// --- DatasetList (frontend/src/routes/datasets/DatasetList.svelte)
+/**!
+ * @brief Renders paginated dataset cards with mapping progress bars, checkboxes, and quick actions.
+ */
+
+// --- DatasetPreview (frontend/src/routes/datasets/DatasetPreview.svelte)
+/**!
+ * @brief Right panel showing dataset detail: header info, columns table, metrics table, linked dashboards. Presentational.
+ */
+
+// --- MetricsTable (frontend/src/routes/datasets/MetricsTable.svelte)
+/**!
+ * @brief Table of dataset metrics with expression, description, and inline-edit capability.
+ */
+
+// --- StatsBar (frontend/src/routes/datasets/StatsBar.svelte)
+/**!
+ * @brief Compact filter pills showing aggregate counts (All, Without mapping, Mapped, Linked).
+ */
+
+// --- DatasetReviewWorkspaceEntry (frontend/src/routes/datasets/review/+page.svelte)
+/**!
+ * @brief Entry route for Dataset Review Workspace — start a new resumable review session or navigate to existing sessions.
+ */
+
+// --- ReviewWorkspaceHeader (frontend/src/routes/datasets/review/ReviewWorkspaceHeader.svelte)
+/**!
+ * @brief Header section for the dataset review workspace with title, description, and status badges.
+ */
+
+// --- ReviewWorkspaceLeftSidebar (frontend/src/routes/datasets/review/ReviewWorkspaceLeftSidebar.svelte)
+/**!
+ * @brief Left sidebar for dataset review workspace: source info, import status, session summary, clarification focus, primary actions.
+ */
+
+// --- ReviewWorkspaceRightRail (frontend/src/routes/datasets/review/ReviewWorkspaceRightRail.svelte)
+/**!
+ * @brief Right rail for dataset review workspace: next action, blockers, health counts, exports, SQL preview, launch panel.
+ */
+
+// --- DatasetReviewWorkspace (frontend/src/routes/datasets/review/[id]/+page.svelte)
+/**!
+ * @brief Main dataset review workspace — thin shell delegating to extracted components.
+ * @deprecated N/A — active workspace page.
+ */
+
+// --- DatasetReviewEntryUxTests (frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js)
+/**!
+ * @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+ */
+
+// --- DatasetReviewEntryUxPageTests (frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js)
+/**!
+ * @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+ */
+
+// --- ReviewWorkspaceHelpers (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ * @brief Shared helper functions for the dataset review workspace.
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildImportMilestones (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildWorkspaceLaunchBlockers (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantSeedPrompt (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantContextPrompt (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getWorkspaceStateLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getRecommendedActionLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getPrimaryActionCtaLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::mergeCollectionItem (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::stringifyValue (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- UseReviewSession (frontend/src/routes/datasets/review/useReviewSession.js)
+/**!
+ * @brief Composable for dataset review session state management — load, update, export, and clarify.
+ */
+
+// --- GitDashboardPage (frontend/src/routes/git/+page.svelte)
+/**!
+ * @brief Git integration page for selecting environments and managing dashboard repositories.
+ */
+
+// --- LoginPage (frontend/src/routes/login/+page.svelte)
+/**!
+ * @brief Provides the user interface for local (username/password) and ADFS SSO authentication.
+ * @invariant Shows both local login form and ADFS SSO button.
+ */
+
+// --- MaintenanceBannerPage (frontend/src/routes/maintenance/+page.svelte)
+/**!
+ * @brief Maintenance Banners management page. Composes SettingsPanel and EventsTable from store.
+ */
+
+// --- ReactiveDashboardFetch:Block (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Automatically fetch dashboards when the source environment is changed.
+ * @post fetchDashboards is called with the new sourceEnvId.
+ * @pre sourceEnvId is not empty.
+ */
+
+// --- handleMappingUpdate:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Saves a mapping to the backend.
+ * @post Mapping is saved and local mappings list is updated.
+ * @pre event.detail contains sourceUuid and targetUuid.
+ */
+
+// --- handleViewLogs:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Opens the log viewer for a specific task.
+ * @post logViewer state updated and showLogViewer set to true.
+ * @pre event.detail contains task object.
+ */
+
+// --- handlePasswordPrompt:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Reactive logic to show password prompt when a task is awaiting input.
+ * @post showPasswordPrompt set to true with request data.
+ * @pre selectedTask status is AWAITING_INPUT.
+ */
+
+// --- ReactivePasswordPrompt:Block (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Monitor selected task for input requests and trigger password prompt.
+ * @post showPasswordPrompt is set to true if input_request is database_password.
+ * @pre $selectedTask is not null and status is AWAITING_INPUT.
+ */
+
+// --- handleResumeMigration:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Resumes a migration task with provided passwords.
+ * @post resumeTask is called and showPasswordPrompt is hidden on success.
+ * @pre event.detail contains passwords.
+ */
+
+// --- startMigration:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Initiates the migration process by sending the selection to the backend.
+ * @post A migration task is created and selectedTask store is updated.
+ * @pre sourceEnvId and targetEnvId are set and different; at least one dashboard is selected.
+ */
+
+// --- startDryRun:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Performs a dry-run migration to identify potential risks and changes.
+ * @post dryRunResult is populated with the pre-flight analysis.
+ * @pre source/target environments and selected dashboards are valid.
+ */
+
+// --- MigrationMappingsPage (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Render and orchestrate mapping management UI for source/target environments with backend persistence.
+ * @invariant Persisted mapping state in backend remains the source of truth for rendered mapping pairs.
+ * @post UI exposes deterministic Idle/Loading/Error/Success states for environment loading, database fetch, and mapping save.
+ * @pre Translation store and API client are available; route is mounted in authenticated UI shell.
+ */
+
+// --- MappingsPageScript:Block (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Define imports, state, and handlers that drive migration mappings page FSM.
+ */
+
+// --- Imports:Block (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ */
+
+// --- UiState:Store (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Maintain local page state for environments, fetched databases, mappings, suggestions, and UX messages.
+ */
+
+// --- belief_scope:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Frontend semantic scope wrapper for CRITICAL trace boundaries without changing business behavior.
+ * @post Executes run exactly once and returns/rejects with the same outcome.
+ * @pre scopeId is non-empty and run is callable.
+ */
+
+// --- fetchDatabases:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Fetch both environment database catalogs, existing mappings, and suggested matches.
+ * @post fetchingDbs=false and sourceDatabases/targetDatabases/mappings/suggestions updated or error set.
+ * @pre sourceEnvId and targetEnvId are both selected and non-empty.
+ */
+
+// --- handleUpdate:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Persist a selected mapping pair and reconcile local mapping list by source database UUID.
+ * @post mapping persisted; local mappings replaced for same source UUID; success or error feedback shown.
+ * @pre event.detail includes sourceUuid/targetUuid and matching source/target database records exist.
+ */
+
+// --- MappingsPageTemplate (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Mapping page template with environment selectors, database mapping table, and action buttons.
+ */
+
+// --- ProfilePage (frontend/src/routes/profile/+page.svelte)
+/**!
+ * @brief User profile page for viewing and editing personal preferences and settings.
+ */
+
+// --- ProfileFixtures:Module (frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js)
+/**!
+ * @brief Shared deterministic fixture inputs for profile page integration tests.
+ * @invariant lookupFailedManualFallback.warning is a hardcoded English string; drift risk if i18n key profile.lookup_error changes without updating this fixture.
+ */
+
+// --- ProfilePreferencesIntegrationTest (frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js)
+/**!
+ * @brief Verifies profile page loads preferences and saves them.
+ */
+
+// --- ProfileSettingsStateIntegrationTest (frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js)
+/**!
+ * @brief Verifies profile loads preferences, allows changes, and saves correctly.
+ */
+
+// --- UnifiedReportsPage (frontend/src/routes/reports/+page.svelte)
+/**!
+ * @brief Unified reports page with task-type and status filtering, list selection, detail panel, and resilient UX states for mixed task types.
+ */
+
+// --- ReportPageContractTest:Module (frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js)
+/**!
+ * @brief Protect the LLM report page from self-triggering screenshot load effects.
+ */
+
+// --- llm_report_screenshot_effect_contract:Function (frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js)
+/**!
+ * @brief Ensure screenshot loading stays untracked from blob-url mutation state.
+ * @post Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.
+ * @pre Report page source exists.
+ */
+
+// --- SettingsPage (frontend/src/routes/settings/+page.svelte)
+/**!
+ * @brief Consolidated Settings Page shell — thin layout that delegates each tab to its own component.
+ * @deprecated N/A
+ * @post Page exposes consolidated settings tabs; each tab manages its own state.
+ * @pre Route is loaded in the authenticated UI shell.
+ */
+
+// --- frontend/src/routes/settings/+page.ts::load (frontend/src/routes/settings/+page.ts)
+/**!
+ */
+
+// --- FeaturesSettings (frontend/src/routes/settings/FeaturesSettings.svelte)
+/**!
+ * @brief Feature flags configuration tab: enable/disable top-level application features.
+ * @post User can toggle feature flags.
+ * @pre settings object with features config is provided.
+ */
+
+// --- LlmSettings (frontend/src/routes/settings/LlmSettings.svelte)
+/**!
+ * @brief LLM configuration tab: providers, bindings, prompts for chatbot and validation.
+ * @post User can configure LLM provider bindings and prompts.
+ * @pre settings object with llm config and llm_providers list is provided.
+ */
+
+// --- LoggingSettings (frontend/src/routes/settings/LoggingSettings.svelte)
+/**!
+ * @brief Logging configuration tab: log level, task log level, belief state toggle.
+ * @post User can adjust logging levels and toggle belief state.
+ * @pre settings object with logging config is provided.
+ */
+
+// --- MigrationMappingsTable (frontend/src/routes/settings/MigrationMappingsTable.svelte)
+/**!
+ * @brief Mappings data table with search, filtering, and pagination for migration sync resources. Isolated from the main MigrationSettings to keep each module < 400 lines.
+ * @post User can search, filter by environment/type, and paginate through resource mappings.
+ * @pre API client initialized, refreshKey provided by parent.
+ */
+
+// --- MigrationSettings (frontend/src/routes/settings/MigrationSettings.svelte)
+/**!
+ * @brief Migration sync configuration tab: cron schedule, sync now, mappings table with filtering and pagination.
+ * @post User can configure sync schedule, trigger sync, and browse resource mappings.
+ * @pre API client initialized.
+ */
+
+// --- StorageSettings (frontend/src/routes/settings/StorageSettings.svelte)
+/**!
+ * @brief Storage configuration tab: root path, backup path, repo path.
+ * @post User can view and edit storage paths.
+ * @pre settings object with storage config is provided.
+ */
+
+// --- SystemSettings (frontend/src/routes/settings/SystemSettings.svelte)
+/**!
+ * @brief System settings tab: timezone configuration and API key management.
+ * @post User can select the application timezone and manage API keys.
+ * @pre settings object is provided with app_timezone field.
+ */
+
+// --- SettingsPageUxTest:Module (frontend/src/routes/settings/__tests__/settings_page.ux.test.js)
+/**!
+ * @brief Test UX states and transitions
+ */
+
+// --- AutomationPage (frontend/src/routes/settings/automation/+page.svelte)
+/**!
+ * @brief Settings page for managing validation policies.
+ */
+
+// --- loadConfigs:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Fetches existing git configurations.
+ * @post configs state is populated.
+ * @pre Component is mounted.
+ */
+
+// --- handleTest:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Tests connection to a git server with current form data.
+ * @post testing state is managed; toast shown with result.
+ * @pre newConfig contains valid provider, url, and pat.
+ */
+
+// --- handleSave:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Saves a new git configuration.
+ * @post New config is saved to DB and added to configs list.
+ * @pre newConfig is valid and tested.
+ */
+
+// --- handleEdit:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Populates the form with an existing config to edit.
+ * @param {Object} config - Configuration object to edit.
+ * @post Form is populated and isEditing state is set.
+ */
+
+// --- resetForm:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Resets the configuration form.
+ */
+
+// --- loadGiteaRepos:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Loads repositories from selected Gitea config.
+ * @post giteaRepos state updated.
+ * @pre selectedGiteaConfigId is set.
+ */
+
+// --- handleCreateGiteaRepo:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Creates new repository on selected Gitea server.
+ * @post Repository created and repos list reloaded.
+ * @pre selectedGiteaConfigId and newGiteaRepo.name are set.
+ */
+
+// --- handleDeleteGiteaRepo:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Deletes repository from selected Gitea server.
+ * @post Repository deleted and repos list reloaded.
+ * @pre selectedGiteaConfigId is set.
+ */
+
+// --- GitSettingsPageUxTest:Module (frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js)
+/**!
+ * @brief Test UX states and transitions for the Git Settings page
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::readTabFromUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::writeTabToUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeTab (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeLlmSettings (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::isDashboardValidationBindingValid (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::getProviderById (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeSupersetBaseUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::resolveEnvStage (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- StorageIndexPage (frontend/src/routes/storage/+page.svelte)
+/**!
+ * @brief Redirect to the backups page as the default storage view.
+ * @invariant Always redirects to /storage/backups.
+ */
+
+// --- BackupsRedirectPage (frontend/src/routes/storage/backups/+page.svelte)
+/**!
+ * @brief Temporary switch to legacy storage browser for backup UX validation.
+ * @invariant Always redirects to /tools/storage.
+ */
+
+// --- fetchEnvironments:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Fetches the list of available environments.
+ * @post environments array is populated, selectedEnvId is set to first env if available.
+ * @pre None.
+ */
+
+// --- fetchDashboards:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Fetches dashboards for a specific environment.
+ * @post dashboards array is populated with metadata for the selected environment.
+ * @pre envId is a valid environment ID.
+ */
+
+// --- filterDashboardsWithRepositories:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Keep only dashboards that already have initialized Git repositories.
+ * @post Returns dashboards with status != NO_REPO.
+ * @pre dashboards list is loaded for selected environment.
+ */
+
+// --- BackupsPage (frontend/src/routes/tools/backups/+page.svelte)
+/**!
+ * @brief Entry point for the Backup Management interface.
+ */
+
+// --- DebugToolPage (frontend/src/routes/tools/debug/+page.svelte)
+/**!
+ * @brief Page for system diagnostics and debugging.
+ */
+
+// --- MapperToolPage (frontend/src/routes/tools/mapper/+page.svelte)
+/**!
+ * @brief Page for the dataset column mapper tool.
+ */
+
+// --- loadFiles:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Fetches the list of files from the server.
+ * @post Updates the `files` array with the latest data.
+ * @pre currentPath is a valid storage path or empty for root.
+ */
+
+// --- resolveStorageQueryFromPath:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Splits UI path into storage API category and category-local subpath.
+ * @post Returns {category, subpath} compatible with /api/storage/files.
+ * @pre uiPath may be empty or start with backups/repositorys.
+ */
+
+// --- handleDelete:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Handles the file deletion process.
+ * @param {CustomEvent} event - The delete event containing category and path.
+ * @post File is deleted and file list is refreshed.
+ * @pre The event contains valid category and path.
+ */
+
+// --- handleNavigate:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Updates the current path and reloads files when navigating into a directory.
+ * @param {CustomEvent} event - The navigation event containing the new path.
+ * @post currentPath is updated and files are reloaded.
+ * @pre The event contains a valid path string.
+ */
+
+// --- navigateUp:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Navigates one level up in the directory structure.
+ * @post currentPath is moved up one directory level.
+ * @pre currentPath is not root.
+ */
+
+// --- updateUploadCategory:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Keeps upload category aligned with the currently viewed top-level folder.
+ * @post uploadCategory is either backups or repositorys.
+ * @pre currentPath can be empty or a slash-delimited path.
+ */
+
+// --- TranslateJobList (frontend/src/routes/translate/+page.svelte)
+/**!
+ */
+
+// --- TranslationJobConfig (frontend/src/routes/translate/[id]/+page.svelte)
+/**!
+ * @brief Translation job configuration page - orchestrates form state, datasource loading, LLM settings, run/schedule tabs.
+ * @deprecated N/A — active page.
+ */
+
+// --- DictionariesPage (frontend/src/routes/translate/dictionaries/+page.svelte)
+/**!
+ */
+
+// --- DictionaryDetailPage (frontend/src/routes/translate/dictionaries/[id]/+page.svelte)
+/**!
+ */
+
+// --- TranslateHistoryPage (frontend/src/routes/translate/history/+page.svelte)
+/**!
+ */
+
+// --- ValidationTaskList (frontend/src/routes/validation/+page.svelte)
+/**!
+ * @brief Validation task list page with status filter, task cards, and create/duplicate/delete actions.
+ * @param {string} status
+ */
+
+// --- ValidationTaskConfig (frontend/src/routes/validation/[id]/+page.svelte)
+/**!
+ * @brief Validation task configuration page with Config and History tabs. Handles new and edit modes.
+ */
+
+// --- ValidationHistory (frontend/src/routes/validation/history/+page.svelte)
+/**!
+ * @brief Validation run history page with filters, metrics summary, and run cards.
+ */
+
+// --- GitServiceContractTests (frontend/src/services/__tests__/gitService.test.js)
+/**!
+ * @brief API client tests ensuring correct endpoints are called per contract for Git service operations.
+ */
+
+// --- gitServiceContractTests:Module (frontend/src/services/__tests__/gitService.test.js)
+/**!
+ * @brief API client tests ensuring correct endpoints are called per contract
+ * @post Returns promotion metadata
+ * @pre Repo initialized
+ */
+
+// --- AdminService (frontend/src/services/adminService.js)
+/**!
+ * @brief Service for Admin-related API calls including User and Role management, AD group mappings, and logging configuration.
+ */
+
+// --- adminService:Module (frontend/src/services/adminService.js)
+/**!
+ * @brief Service for Admin-related API calls (User and Role management).
+ * @invariant All requests must include valid Admin JWT token (handled by api client).
+ */
+
+// --- getUsers:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all registered users from the backend.
+ * @post Returns an array of user objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getUsers (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of user objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates a new local user.
+ * @param {Object} userData - User details (username, email, password, roles, is_active).
+ * @post New user record created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createUser (frontend/src/services/adminService.js)
+/**!
+ * @post New user record created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- getRoles:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all available system roles.
+ * @post Returns an array of role objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getRoles (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of role objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- getADGroupMappings:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches mappings between AD groups and local roles.
+ * @post Returns an array of AD group mapping objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getADGroupMappings (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of AD group mapping objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createADGroupMapping:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates or updates an AD group to Role mapping.
+ * @param {Object} mappingData - Mapping details (ad_group, role_id).
+ * @post New or updated mapping created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createADGroupMapping (frontend/src/services/adminService.js)
+/**!
+ * @post New or updated mapping created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- updateUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates an existing user.
+ * @param {Object} userData - Updated user data.
+ * @post User record updated in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateUser (frontend/src/services/adminService.js)
+/**!
+ * @post User record updated in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- deleteUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Deletes a user.
+ * @param {string} userId - Target user ID.
+ * @post User record removed from auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::deleteUser (frontend/src/services/adminService.js)
+/**!
+ * @post User record removed from auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates a new role.
+ * @param {Object} roleData - Role details (name, description, permissions).
+ * @post New role created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createRole (frontend/src/services/adminService.js)
+/**!
+ * @post New role created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- updateRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates an existing role.
+ * @param {Object} roleData - Updated role data.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateRole (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- deleteRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Deletes a role.
+ * @param {string} roleId - Target role ID.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::deleteRole (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- getPermissions:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all available permissions.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getPermissions (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- getLoggingConfig:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches current logging configuration.
+ * @return {Promise} - Logging config with level, task_log_level, enable_belief_state.
+ */
+
+// --- frontend/src/services/adminService.js::getLoggingConfig (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- updateLoggingConfig:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates logging configuration.
+ * @param {Object} configData - Logging config (level, task_log_level, enable_belief_state).
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateLoggingConfig (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- GitUtils (frontend/src/services/git-utils.js)
+/**!
+ * @brief Shared utility functions extracted from GitManager.svelte.
+ */
+
+// --- frontend/src/services/git-utils.js::normalizeEnvStage (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::stageBadgeClass (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolveCurrentEnvironmentId (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::applyGitflowStageDefaults (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::isNumericDashboardRef (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::getSelectedConfig (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolveDefaultConfig (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolvePushProviderLabel (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::extractHttpHost (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::buildSuggestedRepoName (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::tryParseJsonObject (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::extractUnfinishedMergeContext (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- StorageService (frontend/src/services/storageService.js)
+/**!
+ * @brief Frontend API client for file storage management including list, upload, download, and delete operations.
+ */
+
+// --- storageService:Module (frontend/src/services/storageService.js)
+/**!
+ * @brief Frontend API client for file storage management.
+ */
+
+// --- getStorageAuthHeaders:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Returns headers with Authorization for storage API calls.
+ * @note Unlike api.js getAuthHeaders, this doesn't set Content-Type
+ * @return {Object} Headers object with Authorization if token exists.
+ */
+
+// --- frontend/src/services/storageService.js::getStorageAuthHeaders (frontend/src/services/storageService.js)
+/**!
+ */
+
+// --- encodeStoragePath:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Encodes a storage-relative path preserving slash separators.
+ * @param {string} path - Relative storage path.
+ * @return {string} Encoded path safe for URL segments.
+ */
+
+// --- frontend/src/services/storageService.js::encodeStoragePath (frontend/src/services/storageService.js)
+/**!
+ */
+
+// --- listFiles:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Fetches the list of files for a given category and subpath.
+ * @param {string} [path] - Optional subpath filter.
+ * @post Returns a promise resolving to an array of StoredFile objects.
+ * @pre category and path should be valid strings if provided.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::listFiles (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a promise resolving to an array of StoredFile objects.
+ * @pre category and path should be valid strings if provided.
+ */
+
+// --- uploadFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Uploads a file to the storage system.
+ * @param {string} [path] - Target subpath.
+ * @post Returns a promise resolving to the metadata of the uploaded file.
+ * @pre file must be a valid File object; category must be specified.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::uploadFile (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a promise resolving to the metadata of the uploaded file.
+ * @pre file must be a valid File object; category must be specified.
+ */
+
+// --- deleteFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Deletes a file or directory from storage.
+ * @param {string} path - Relative path of the item.
+ * @post The specified file or directory is removed from storage.
+ * @pre category and path must identify an existing file or directory.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::deleteFile (frontend/src/services/storageService.js)
+/**!
+ * @post The specified file or directory is removed from storage.
+ * @pre category and path must identify an existing file or directory.
+ */
+
+// --- downloadFileUrl:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Returns the URL for downloading a file.
+ * @note Downloads use browser navigation, so auth is handled via cookies
+ * @param {string} path - Relative path of the file.
+ * @post Returns a valid API URL for file download.
+ * @pre category and path must identify an existing file.
+ * @return {string}
+ */
+
+// --- frontend/src/services/storageService.js::downloadFileUrl (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a valid API URL for file download.
+ * @pre category and path must identify an existing file.
+ */
+
+// --- downloadFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Downloads a file using authenticated fetch and saves it in browser.
+ * @param {string} [filename] - Optional preferred filename.
+ * @post Browser download is triggered or an Error is thrown.
+ * @pre category/path identify an existing file and user has READ permission.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::downloadFile (frontend/src/services/storageService.js)
+/**!
+ * @post Browser download is triggered or an Error is thrown.
+ * @pre category/path identify an existing file and user has READ permission.
+ */
+
+// --- TaskService (frontend/src/services/taskService.js)
+/**!
+ * @brief Service for Task Management API interactions: listing, fetching details, resuming, resolving, and clearing tasks.
+ */
+
+// --- getTasks:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch a list of tasks with pagination and optional status filter.
+ * @post Returns a promise resolving to a list of tasks.
+ * @pre limit and offset are numbers.
+ */
+
+// --- frontend/src/services/taskService.js::getTasks (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- getTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch details for a specific task.
+ * @post Returns a promise resolving to task details.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::getTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- getTaskLogs:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch logs for a specific task.
+ * @post Returns a promise resolving to a list of log entries.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::getTaskLogs (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- resumeTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Resume a task that is awaiting input (e.g., passwords).
+ * @post Returns a promise resolving to the updated task object.
+ * @pre taskId and passwords must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::resumeTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- resolveTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Resolve a task that is awaiting mapping.
+ * @post Returns a promise resolving to the updated task object.
+ * @pre taskId and resolutionParams must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::resolveTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- clearTasks:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Clear tasks based on status.
+ * @post Returns a promise that resolves when tasks are cleared.
+ * @pre status is a string or null.
+ */
+
+// --- frontend/src/services/taskService.js::clearTasks (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- ToolsService (frontend/src/services/toolsService.js)
+/**!
+ * @brief Service for generic Task API communication used by Tools — run tasks and poll status.
+ */
+
+// --- runTask:Function (frontend/src/services/toolsService.js)
+/**!
+ * @brief Start a new task for a given plugin.
+ * @post Returns a promise resolving to the task instance.
+ * @pre pluginId and params must be provided.
+ */
+
+// --- frontend/src/services/toolsService.js::runTask (frontend/src/services/toolsService.js)
+/**!
+ */
+
+// --- getTaskStatus:Function (frontend/src/services/toolsService.js)
+/**!
+ * @brief Fetch details for a specific task (to poll status or get result).
+ * @post Returns a promise resolving to task details.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/toolsService.js::getTaskStatus (frontend/src/services/toolsService.js)
+/**!
+ */
+
+// --- BackupTypes (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- frontend/src/types/backup.ts::Backup (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- BackupTypes:Module (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- DashboardTypes (frontend/src/types/dashboard.ts)
+/**!
+ */
+
+// --- DashboardTypes:Module (frontend/src/types/dashboard.ts)
+/**!
+ * @brief TypeScript interfaces for Dashboard entities
+ */
+
+// --- frontend/src/types/dashboard.ts::DashboardMetadata (frontend/src/types/dashboard.ts)
+/**!
+ */
+
+// --- MaintenanceStoreTests (frontend/tests/maintenance-store.test.ts)
+/**!
+ * @brief Unit tests for MaintenanceStore runes-based store.
+ */
+
+// --- MaintenanceComponentTests (frontend/tests/maintenance.test.ts)
+/**!
+ * @brief Component tests for MaintenanceEventsTable and DashboardMaintenanceBadge.
+ */
+
+// --- MergeSpec (merge_spec.py)
+/**!
+ */
+
+// --- merge_spec (merge_spec.py)
+/**!
+ */
+
+// --- BuildOfflineDockerBundle (scripts/build_offline_docker_bundle.sh)
+/**!
+ * @brief Thin wrapper — delegates to ./build.sh bundle (.tar.xz output)
+ */
+
+// --- venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp::ThreadState (venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp)
+/**!
+ */
+
+// --- venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp::PyFatalError (venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp)
+/**!
+ */
+
diff --git a/docs/api/doxygen_stripped.txt b/docs/api/doxygen_stripped.txt
new file mode 100644
index 00000000..bd23d951
--- /dev/null
+++ b/docs/api/doxygen_stripped.txt
@@ -0,0 +1,18019 @@
+// AXIOM Doc Generator — Generated docs
+// Format: doxygen Mode: stripped Contracts: 3195
+// Usage: run through `jsdoc --pedantic` or `doxygen -W` for validation
+
+// --- SrcRoot (backend/src/__init__.py)
+/**!
+ * @brief Canonical backend package root for application, scripts, and tests.
+ */
+
+// --- src.api (backend/src/api/__init__.py)
+/**!
+ * @brief Backend API package root.
+ */
+
+// --- AuthApi (backend/src/api/auth.py)
+/**!
+ * @brief Authentication API endpoints.
+ * @invariant All auth endpoints must return consistent error codes.
+ * @post FastAPI app instance with auth routes registered.
+ * @pre Python environment and dependencies installed; database available.
+ */
+
+// --- login_for_access_token (backend/src/api/auth.py)
+/**!
+ * @brief Authenticates a user and returns a JWT access token.
+ * @post Returns a Token object on success.
+ * @pre form_data contains username and password.
+ */
+
+// --- read_users_me (backend/src/api/auth.py)
+/**!
+ * @brief Retrieves the profile of the currently authenticated user.
+ * @post Returns the current user's data.
+ * @pre Valid JWT token provided.
+ */
+
+// --- logout (backend/src/api/auth.py)
+/**!
+ * @brief Logs out the current user (placeholder for session revocation).
+ * @post Returns success message.
+ * @pre Valid JWT token provided.
+ */
+
+// --- login_adfs (backend/src/api/auth.py)
+/**!
+ * @brief Initiates the ADFS OIDC login flow.
+ * @post Redirects the user to ADFS.
+ */
+
+// --- auth_callback_adfs (backend/src/api/auth.py)
+/**!
+ * @brief Handles the callback from ADFS after successful authentication.
+ * @post Provisions user JIT and returns session token.
+ */
+
+// --- ApiRoutesModule (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Provide lazy route module loading to avoid heavyweight imports during tests.
+ * @invariant Only names listed in __all__ are importable via __getattr__.
+ * @post Route modules are lazily loadable via __getattr__
+ * @pre FastAPI app initialized, route modules available in package
+ */
+
+// --- Route_Group_Contracts (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Declare the canonical route-module registry used by lazy imports and app router inclusion.
+ */
+
+// --- ApiRoutesGetAttr (backend/src/api/routes/__init__.py)
+/**!
+ * @brief Lazily import route module by attribute name.
+ * @post Returns imported submodule or raises AttributeError.
+ * @pre name is module candidate exposed in __all__.
+ */
+
+// --- RoutesTestsConftest (backend/src/api/routes/__tests__/conftest.py)
+/**!
+ * @brief Shared low-fidelity test doubles for API route test modules.
+ */
+
+// --- AssistantApiTests (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Validate assistant API endpoint logic via direct async handler invocation.
+ * @invariant Every test clears assistant in-memory state before execution.
+ */
+
+// --- _dataset_review_session (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Build minimal owned dataset-review session fixture for assistant scoped routing tests.
+ */
+
+// --- _await_none (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Async helper returning None for planner fallback tests.
+ */
+
+// --- test_unknown_command_returns_needs_clarification (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Unknown command should return clarification state and unknown intent.
+ */
+
+// --- test_capabilities_question_returns_successful_help (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Capability query should return deterministic help response.
+ */
+
+// --- test_assistant_message_request_accepts_dataset_review_session_binding (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Assistant request schema should accept active dataset review session binding for scoped orchestration.
+ */
+
+// --- test_dataset_review_scoped_message_uses_masked_filter_context (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant context should mask imported-filter raw values before assistant-visible metadata is persisted.
+ */
+
+// --- test_dataset_review_scoped_command_returns_confirmation_for_mapping_approval (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant commands should route dataset-review mapping approvals into confirmation workflow with bound session metadata.
+ */
+
+// --- test_dataset_review_scoped_command_routes_field_semantics_update (backend/src/api/routes/__tests__/test_assistant_api.py)
+/**!
+ * @brief Session-scoped assistant commands should route semantic field updates through explicit confirmation metadata.
+ */
+
+// --- TestAssistantAuthz (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Verify assistant confirmation ownership, expiration, and deny behavior for restricted users.
+ * @invariant Security-sensitive flows fail closed for unauthorized actors.
+ */
+
+// --- _run_async (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Execute async endpoint handler in synchronous test context.
+ * @post Returns coroutine result or raises propagated exception.
+ * @pre coroutine is awaitable endpoint invocation.
+ */
+
+// --- _FakeTask (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Lightweight task model used for assistant authz tests.
+ * @post Returns task with provided id, status, and user_id accessible as attributes.
+ * @pre task_id is non-empty string.
+ */
+
+// --- _FakeConfigManager (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Provide deterministic environment aliases required by intent parsing.
+ * @invariant get_config() is absent; only get_environments() is emulated. Safe only for routes that do not invoke get_config() on the injected ConfigManager — verify against assistant.py route handler code before adding new test cases that use this fake.
+ * @post get_environments() returns two deterministic SimpleNamespace stubs with id/name.
+ * @pre No external config or DB state is required.
+ */
+
+// --- _other_admin_user (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Build second admin principal fixture for ownership tests.
+ * @post Returns alternate admin-like user stub.
+ * @pre Ownership mismatch scenario needs distinct authenticated actor.
+ */
+
+// --- _limited_user (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Build limited principal without required assistant execution privileges.
+ * @post Returns restricted user stub.
+ * @pre Permission denial scenario needs non-admin actor.
+ */
+
+// --- _FakeDb (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief In-memory DB session double constrained to assistant message/confirmation/audit persistence paths.
+ * @invariant query/add/merge are intentionally narrow and must not claim full SQLAlchemy Session semantics.
+ */
+
+// --- _clear_assistant_state (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Reset assistant process-local state between test cases.
+ * @post Assistant in-memory state dictionaries are cleared.
+ * @pre Assistant globals may contain state from prior tests.
+ */
+
+// --- test_confirmation_owner_mismatch_returns_403 (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Confirm endpoint should reject requests from user that does not own the confirmation token.
+ * @post Second actor receives 403 on confirm operation.
+ * @pre Confirmation token is created by first admin actor.
+ */
+
+// --- test_expired_confirmation_cannot_be_confirmed (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Expired confirmation token should be rejected and not create task.
+ * @post Confirm endpoint raises 400 and no task is created.
+ * @pre Confirmation token exists and is manually expired before confirm request.
+ */
+
+// --- test_limited_user_cannot_launch_restricted_operation (backend/src/api/routes/__tests__/test_assistant_authz.py)
+/**!
+ * @brief Limited user should receive denied state for privileged operation.
+ * @post Assistant returns denied state and does not execute operation.
+ * @pre Restricted user attempts dangerous deploy command.
+ */
+
+// --- TestCleanReleaseApi (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Contract tests for clean release checks and reports endpoints.
+ * @invariant API returns deterministic payload shapes for checks and reports.
+ */
+
+// --- test_start_check_and_get_status_contract (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate checks start endpoint returns expected identifiers and status endpoint reflects the same run.
+ */
+
+// --- test_get_report_not_found_returns_404 (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate reports endpoint returns 404 for an unknown report identifier.
+ */
+
+// --- test_get_report_success (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate reports endpoint returns persisted report payload for an existing report identifier.
+ */
+
+// --- test_prepare_candidate_api_success (backend/src/api/routes/__tests__/test_clean_release_api.py)
+/**!
+ * @brief Validate candidate preparation endpoint returns prepared status and manifest identifier on valid input.
+ */
+
+// --- TestCleanReleaseLegacyCompat (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Compatibility tests for legacy clean-release API paths retained during v2 migration.
+ */
+
+// --- _seed_legacy_repo (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Seed in-memory repository with minimum trusted data for legacy endpoint contracts.
+ * @post Candidate, policy, registry and manifest are available for legacy checks flow.
+ * @pre Repository is empty.
+ */
+
+// --- test_legacy_prepare_endpoint_still_available (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Verify legacy prepare endpoint remains reachable and returns a status payload.
+ */
+
+// --- test_legacy_checks_endpoints_still_available (backend/src/api/routes/__tests__/test_clean_release_legacy_compat.py)
+/**!
+ * @brief Verify legacy checks start/status endpoints remain available during v2 transition.
+ */
+
+// --- TestCleanReleaseSourcePolicy (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Validate API behavior for source isolation violations in clean release preparation.
+ * @invariant External endpoints must produce blocking violation entries.
+ */
+
+// --- _repo_with_seed_data (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Seed repository with candidate, registry, and active policy for source isolation test flow.
+ */
+
+// --- test_prepare_candidate_blocks_external_source (backend/src/api/routes/__tests__/test_clean_release_source_policy.py)
+/**!
+ * @brief Verify candidate preparation is blocked when at least one source host is external to the trusted registry.
+ */
+
+// --- CleanReleaseV2ApiTests (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief API contract tests for redesigned clean release endpoints.
+ */
+
+// --- test_candidate_registration_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate candidate registration endpoint creates a draft candidate with expected identifier contract.
+ */
+
+// --- test_artifact_import_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate artifact import endpoint accepts candidate artifacts and returns success status payload.
+ */
+
+// --- test_manifest_build_contract (backend/src/api/routes/__tests__/test_clean_release_v2_api.py)
+/**!
+ * @brief Validate manifest build endpoint produces manifest payload linked to the target candidate.
+ */
+
+// --- CleanReleaseV2ReleaseApiTests (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief API contract test scaffolding for clean release approval and publication endpoints.
+ */
+
+// --- _seed_candidate_and_passed_report (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Seed repository with approvable candidate and passed report for release endpoint contracts.
+ */
+
+// --- test_release_approve_and_publish_revoke_contract (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Verify approve, publish, and revoke endpoints preserve expected release lifecycle contract.
+ */
+
+// --- test_release_reject_contract (backend/src/api/routes/__tests__/test_clean_release_v2_release_api.py)
+/**!
+ * @brief Verify reject endpoint returns successful rejection decision payload.
+ */
+
+// --- DashboardsApiTests (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Unit tests for dashboards API endpoints.
+ */
+
+// --- test_get_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns a populated response that satisfies the schema contract.
+ * @post Response matches DashboardsResponse schema
+ * @pre env_id exists
+ * @test GET /api/dashboards returns 200 and valid schema
+ */
+
+// --- test_get_dashboards_with_search (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing applies the search filter and returns only matching rows.
+ * @post Filtered result count must match search
+ * @pre search parameter provided
+ * @test GET /api/dashboards filters by search term
+ */
+
+// --- test_get_dashboards_empty (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns an empty payload for an environment without dashboards.
+ */
+
+// --- test_get_dashboards_superset_failure (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing surfaces a 503 contract when Superset access fails.
+ */
+
+// --- test_get_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing returns 404 when the requested environment does not exist.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test GET /api/dashboards returns 404 if env_id missing
+ */
+
+// --- test_get_dashboards_invalid_pagination (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboards listing rejects invalid pagination parameters with 400 responses.
+ * @post Returns 400 error
+ * @pre page < 1 or page_size > 100
+ * @test GET /api/dashboards returns 400 for invalid page/page_size
+ */
+
+// --- test_get_dashboard_detail_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard detail returns charts and datasets for an existing dashboard.
+ * @test GET /api/dashboards/{id} returns dashboard detail with charts and datasets
+ */
+
+// --- test_get_dashboard_detail_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard detail returns 404 when the requested environment is missing.
+ * @test GET /api/dashboards/{id} returns 404 for missing environment
+ */
+
+// --- test_migrate_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard migration request creates an async task and returns its identifier.
+ * @post Returns task_id and create_task was called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@POST/@SIDE_EFFECT: create_task was called
+ * @pre Valid source_env_id, target_env_id, dashboard_ids
+ * @test POST /api/dashboards/migrate creates migration task
+ */
+
+// --- test_migrate_dashboards_no_ids (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard migration rejects empty dashboard identifier lists.
+ * @post Returns 400 error
+ * @pre dashboard_ids is empty
+ * @test POST /api/dashboards/migrate returns 400 for empty dashboard_ids
+ */
+
+// --- test_migrate_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate migration creation returns 404 when the source environment cannot be resolved.
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- test_backup_dashboards_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard backup request creates an async backup task and returns its identifier.
+ * @post Returns task_id and create_task was called
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@POST/@SIDE_EFFECT: create_task was called
+ * @pre Valid env_id, dashboard_ids
+ * @test POST /api/dashboards/backup creates backup task
+ */
+
+// --- test_backup_dashboards_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate backup task creation returns 404 when the target environment is missing.
+ * @pre env_id is a valid environment ID
+ */
+
+// --- test_get_database_mappings_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate database mapping suggestions are returned for valid source and target environments.
+ * @post Returns list of database mappings
+ * @pre Valid source_env_id, target_env_id
+ * @test GET /api/dashboards/db-mappings returns mapping suggestions
+ */
+
+// --- test_get_database_mappings_env_not_found (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate database mapping suggestions return 404 when either environment is missing.
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- test_get_dashboard_tasks_history_filters_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard task history returns only related backup and LLM tasks.
+ * @test GET /api/dashboards/{id}/tasks returns backup and llm tasks for dashboard
+ */
+
+// --- test_get_dashboard_thumbnail_success (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate dashboard thumbnail endpoint proxies image bytes and content type from Superset.
+ * @test GET /api/dashboards/{id}/thumbnail proxies image bytes from Superset
+ */
+
+// --- _build_profile_preference_stub (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Creates profile preference payload stub for dashboards filter contract tests.
+ * @post Returns object compatible with ProfileService.get_my_preference contract.
+ * @pre username can be empty; enabled indicates profile-default toggle state.
+ */
+
+// --- _matches_actor_case_insensitive (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Applies trim + case-insensitive owners OR modified_by matching used by route contract tests.
+ * @post Returns True when bound username matches any owner or modified_by.
+ * @pre owners can be None or list-like values.
+ */
+
+// --- test_get_dashboards_profile_filter_contract_owners_or_modified_by (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering matches owner and modifier aliases using normalized Superset actor values.
+ * @post Response includes only matching dashboards and effective_profile_filter metadata.
+ * @pre Current user has enabled profile-default preference and bound username.
+ * @test GET /api/dashboards applies profile-default filter with owners OR modified_by trim+case-insensitive semantics.
+ */
+
+// --- test_get_dashboards_override_show_all_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate override_show_all bypasses profile-default filtering without changing dashboard list semantics.
+ * @post Response remains unfiltered and effective_profile_filter.applied is false.
+ * @pre Profile-default preference exists but override_show_all=true query is provided.
+ * @test GET /api/dashboards honors override_show_all and disables profile-default filter for current page.
+ */
+
+// --- test_get_dashboards_profile_filter_no_match_results_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering returns an empty dashboard page when no actor aliases match the bound user.
+ * @post Response total is 0 with deterministic pagination and active effective_profile_filter metadata.
+ * @pre Profile-default preference is enabled with bound username and all dashboards are non-matching.
+ * @test GET /api/dashboards returns empty result set when profile-default filter is active and no dashboard actors match.
+ */
+
+// --- test_get_dashboards_page_context_other_disables_profile_default (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate non-dashboard page contexts suppress profile-default filtering and preserve unfiltered results.
+ * @post Response remains unfiltered and metadata reflects source_page=other.
+ * @pre Profile-default preference exists but page_context=other query is provided.
+ * @test GET /api/dashboards does not auto-apply profile-default filter outside dashboards_main page context.
+ */
+
+// --- test_get_dashboards_profile_filter_matches_display_alias_without_detail_fanout (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering reuses resolved Superset display aliases without triggering per-dashboard detail fanout.
+ * @post Route matches by alias (`Superset Admin`) and does not call `SupersetClient.get_dashboard` in list filter path.
+ * @pre Profile-default filter is active, bound username is `admin`, dashboard actors contain display labels.
+ * @test GET /api/dashboards resolves Superset display-name alias once and filters without per-dashboard detail calls.
+ */
+
+// --- test_get_dashboards_profile_filter_matches_owner_object_payload_contract (backend/src/api/routes/__tests__/test_dashboards.py)
+/**!
+ * @brief Validate profile-default filtering accepts owner object payloads once aliases resolve to the bound Superset username.
+ * @post Response keeps dashboards where owner object resolves to bound username alias.
+ * @pre Profile-default preference is enabled and owners list contains dict payloads.
+ * @test GET /api/dashboards profile-default filter matches Superset owner object payloads.
+ */
+
+// --- DatasetReviewApiTests (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify backend US1 dataset review lifecycle, export, parsing, and dictionary-resolution contracts.
+ */
+
+// --- _make_user (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_config_manager (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_us2_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_us3_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- _make_preview_ready_session (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- dataset_review_api_dependencies (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ */
+
+// --- test_parse_superset_link_dashboard_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard links recover dataset context and preserve explicit partial-recovery markers.
+ */
+
+// --- test_parse_superset_link_dashboard_slug_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard slug links resolve through dashboard detail endpoints and recover dataset context.
+ */
+
+// --- test_parse_superset_link_dashboard_permalink_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify dashboard permalink links no longer fail parsing and preserve permalink filter state for partial recovery.
+ */
+
+// --- test_parse_superset_link_dashboard_permalink_recovers_dataset_from_nested_dashboard_state (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify permalink state with nested dashboard id recovers dataset binding and keeps imported filters.
+ */
+
+// --- test_resolve_from_dictionary_prefers_exact_match (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify trusted dictionary exact matches outrank fuzzy candidates and unresolved fields stay explicit.
+ */
+
+// --- test_orchestrator_start_session_preserves_partial_recovery (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify session start persists usable recovery-required state when Superset intake is partial.
+ */
+
+// --- test_orchestrator_start_session_bootstraps_recovery_state (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify session start persists recovered filters, template variables, and initial execution mappings for review workspace bootstrap.
+ */
+
+// --- test_start_session_endpoint_returns_created_summary (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify POST session lifecycle endpoint returns a persisted ownership-scoped summary.
+ */
+
+// --- test_get_session_detail_export_and_lifecycle_endpoints (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Verify lifecycle get/patch/delete plus documentation and validation exports remain ownership-scoped and usable.
+ */
+
+// --- test_get_clarification_state_returns_empty_payload_when_session_has_no_record (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Clarification state endpoint should return a non-blocking empty payload when the session has no clarification aggregate yet.
+ */
+
+// --- test_us2_clarification_endpoints_persist_answer_and_feedback (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Clarification endpoints should expose one current question, persist the answer before advancement, and store feedback on the answer audit record.
+ */
+
+// --- test_us2_field_semantic_override_lock_unlock_and_feedback (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Semantic field endpoints should apply manual overrides with lock/provenance invariants and persist feedback independently.
+ */
+
+// --- test_us3_mapping_patch_approval_preview_and_launch_endpoints (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief US3 execution endpoints should persist manual overrides, preserve explicit approval semantics, return contract-shaped preview truth, and expose audited launch handoff.
+ */
+
+// --- test_us3_preview_response_propagates_refreshed_session_version_for_launch_follow_up (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Preview response should expose the refreshed session version so the normal preview-then-launch UI flow can satisfy optimistic locking without a forced full reload.
+ */
+
+// --- test_us3_preview_endpoint_returns_failed_preview_without_false_dashboard_not_found_contract_drift (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Preview endpoint should preserve API contract and surface generic upstream preview failures without fabricating dashboard-not-found semantics for non-dashboard 404s.
+ */
+
+// --- test_mutation_endpoints_surface_session_version_conflict_payload (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Dataset review mutation endpoints should return deterministic 409 conflict semantics when optimistic-lock versions are stale.
+ */
+
+// --- test_update_session_surfaces_commit_time_session_version_conflict_payload (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Session lifecycle mutation should return deterministic 409 conflict semantics when commit-time optimistic locking rejects a stale write.
+ */
+
+// --- test_execution_snapshot_includes_recovered_imported_filters_without_template_mapping (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Recovered imported filters with values should flow into preview filter context even when no template variable mapping exists.
+ */
+
+// --- test_execution_snapshot_preserves_mapped_template_variables_and_filter_context (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Mapped template variables should still populate template params while contributing their effective filter context.
+ */
+
+// --- test_execution_snapshot_skips_partial_imported_filters_without_values (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Partial imported filters without raw or normalized values must not emit bogus active preview filters.
+ */
+
+// --- test_us3_launch_endpoint_requires_launch_permission (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Launch endpoint should enforce the contract RBAC permission instead of the generic session-manage permission.
+ */
+
+// --- test_semantic_source_version_propagation_preserves_locked_fields (backend/src/api/routes/__tests__/test_dataset_review_api.py)
+/**!
+ * @brief Updated semantic source versions should mark unlocked fields reviewable while preserving locked manual values.
+ */
+
+// --- DatasetsApiTests (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Unit tests for datasets API endpoints.
+ * @invariant Endpoint contracts remain stable for success and validation failure paths.
+ */
+
+// --- test_get_datasets_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate successful datasets listing contract for an existing environment.
+ * @post Response matches DatasetsResponse schema
+ * @pre env_id exists
+ * @test GET /api/datasets returns 200 and valid schema
+ */
+
+// --- test_get_datasets_env_not_found (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing returns 404 when the requested environment does not exist.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test GET /api/datasets returns 404 if env_id missing
+ */
+
+// --- test_get_datasets_invalid_pagination (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing rejects invalid pagination parameters with 400 responses.
+ * @post Returns 400 error
+ * @pre page < 1 or page_size > 100
+ * @test GET /api/datasets returns 400 for invalid page/page_size
+ */
+
+// --- test_map_columns_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns request creates an async mapping task and returns its identifier.
+ * @post Returns task_id
+ * @pre Valid env_id, dataset_ids, source_type (sqllab)
+ * @test POST /api/datasets/map-columns creates mapping task
+ */
+
+// --- test_map_columns_invalid_source_type (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects unsupported source types with a 400 contract response.
+ * @post Returns 400 error
+ * @pre source_type is not 'sqllab' or 'xlsx'
+ * @test POST /api/datasets/map-columns returns 400 for invalid source_type
+ */
+
+// --- test_generate_docs_success (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs request creates an async documentation task and returns its identifier.
+ * @post Returns task_id
+ * @pre Valid env_id, dataset_ids, llm_provider
+ * @test POST /api/datasets/generate-docs creates doc generation task
+ */
+
+// --- test_map_columns_empty_ids (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects empty dataset identifier lists.
+ * @post Returns 400 error
+ * @pre dataset_ids is empty
+ * @test POST /api/datasets/map-columns returns 400 for empty dataset_ids
+ */
+
+// --- test_map_columns_missing_database_id (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate map-columns rejects sqllab source without database_id.
+ * @post Returns 400 error
+ * @test POST /api/datasets/map-columns returns 400 for sqllab without database_id
+ */
+
+// --- test_generate_docs_empty_ids (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs rejects empty dataset identifier lists.
+ * @post Returns 400 error
+ * @pre dataset_ids is empty
+ * @test POST /api/datasets/generate-docs returns 400 for empty dataset_ids
+ */
+
+// --- test_generate_docs_env_not_found (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate generate-docs returns 404 when the requested environment cannot be resolved.
+ * @post Returns 404 error
+ * @pre env_id does not exist
+ * @test POST /api/datasets/generate-docs returns 404 for missing env
+ */
+
+// --- test_get_datasets_superset_failure (backend/src/api/routes/__tests__/test_datasets.py)
+/**!
+ * @brief Validate datasets listing surfaces a 503 contract when Superset access fails.
+ * @post Returns 503 with stable error detail when upstream dataset fetch fails.
+ */
+
+// --- TestGitApi (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief API tests for Git configurations and repository operations.
+ */
+
+// --- DbMock (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief In-memory session double for git route tests with minimal query/filter persistence semantics.
+ * @invariant Supports only the SQLAlchemy-like operations exercised by this test module.
+ */
+
+// --- test_get_git_configs_masks_pat (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate listing git configs masks stored PAT values in API-facing responses.
+ */
+
+// --- test_create_git_config_persists_config (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate creating git config persists supplied server attributes in backing session.
+ */
+
+// --- test_update_git_config_modifies_record (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate updating git config modifies mutable fields while preserving masked PAT semantics.
+ */
+
+// --- SingleConfigDbMock (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ */
+
+// --- test_update_git_config_raises_404_if_not_found (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate updating non-existent git config raises HTTP 404 contract response.
+ */
+
+// --- test_delete_git_config_removes_record (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate deleting existing git config removes record and returns success payload.
+ */
+
+// --- test_test_git_config_validates_connection_successfully (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate test-connection endpoint returns success when provider connectivity check passes.
+ */
+
+// --- MockGitService (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ */
+
+// --- test_test_git_config_fails_validation (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate test-connection endpoint raises HTTP 400 when provider connectivity check fails.
+ */
+
+// --- test_list_gitea_repositories_returns_payload (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate gitea repositories endpoint returns normalized list for GITEA provider configs.
+ */
+
+// --- test_list_gitea_repositories_rejects_non_gitea (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate gitea repositories endpoint rejects non-GITEA providers with HTTP 400.
+ */
+
+// --- test_create_remote_repository_creates_provider_repo (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate remote repository creation endpoint maps provider response into normalized payload.
+ */
+
+// --- test_init_repository_initializes_and_saves_binding (backend/src/api/routes/__tests__/test_git_api.py)
+/**!
+ * @brief Validate repository initialization endpoint creates local repo and persists dashboard binding.
+ */
+
+// --- TestGitStatusRoute (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Validate status endpoint behavior for missing and error repository states.
+ */
+
+// --- test_get_repository_status_returns_no_repo_payload_for_missing_repo (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure missing local repository is represented as NO_REPO payload instead of an API error.
+ * @post Route returns a deterministic NO_REPO status payload.
+ * @pre GitService.get_status raises HTTPException(404).
+ */
+
+// --- test_get_repository_status_propagates_non_404_http_exception (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure HTTP exceptions other than 404 are not masked.
+ * @post Raised exception preserves original status and detail.
+ * @pre GitService.get_status raises HTTPException with non-404 status.
+ */
+
+// --- test_get_repository_diff_propagates_http_exception (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure diff endpoint preserves domain HTTP errors from GitService.
+ * @post Endpoint raises same HTTPException values.
+ * @pre GitService.get_diff raises HTTPException.
+ */
+
+// --- test_get_history_wraps_unexpected_error_as_500 (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure non-HTTP exceptions in history endpoint become deterministic 500 errors.
+ * @post Endpoint returns HTTPException with status 500 and route context.
+ * @pre GitService.get_commit_history raises ValueError.
+ */
+
+// --- test_commit_changes_wraps_unexpected_error_as_500 (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure commit endpoint does not leak unexpected errors as 400.
+ * @post Endpoint raises HTTPException(500) with route context.
+ * @pre GitService.commit_changes raises RuntimeError.
+ */
+
+// --- test_get_repository_status_batch_returns_mixed_statuses (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint returns per-dashboard statuses in one response.
+ * @post Returned map includes resolved status for each requested dashboard ID.
+ * @pre Some repositories are missing and some are initialized.
+ */
+
+// --- test_get_repository_status_batch_marks_item_as_error_on_service_failure (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint marks failed items as ERROR without failing entire request.
+ * @post Failed dashboard status is marked as ERROR.
+ * @pre GitService raises non-HTTP exception for one dashboard.
+ */
+
+// --- test_get_repository_status_batch_deduplicates_and_truncates_ids (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure batch endpoint protects server from oversized payloads.
+ * @post Result contains unique IDs up to configured cap.
+ * @pre request includes duplicate IDs and more than MAX_REPOSITORY_STATUS_BATCH entries.
+ */
+
+// --- test_commit_changes_applies_profile_identity_before_commit (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure commit route configures repository identity from profile preferences before commit call.
+ * @post git_service.configure_identity receives resolved identity and commit proceeds.
+ * @pre Profile preference contains git_username/git_email for current user.
+ */
+
+// --- test_pull_changes_applies_profile_identity_before_pull (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure pull route configures repository identity from profile preferences before pull call.
+ * @post git_service.configure_identity receives resolved identity and pull proceeds.
+ * @pre Profile preference contains git_username/git_email for current user.
+ */
+
+// --- test_get_merge_status_returns_service_payload (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure merge status route returns service payload as-is.
+ * @post Route response contains has_unfinished_merge=True.
+ * @pre git_service.get_merge_status returns unfinished merge payload.
+ */
+
+// --- test_resolve_merge_conflicts_passes_resolution_items_to_service (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure merge resolve route forwards parsed resolutions to service.
+ * @post Service receives normalized list and route returns resolved files.
+ * @pre resolve_data has one file strategy.
+ */
+
+// --- test_abort_merge_calls_service_and_returns_result (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure abort route delegates to service.
+ * @post Route returns aborted status.
+ * @pre Service abort_merge returns aborted status.
+ */
+
+// --- test_continue_merge_passes_message_and_returns_commit (backend/src/api/routes/__tests__/test_git_status_route.py)
+/**!
+ * @brief Ensure continue route passes commit message to service.
+ * @post Route returns committed status and hash.
+ * @pre continue_data.message is provided.
+ */
+
+// --- TestMigrationRoutes (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ * @brief Unit tests for migration API route handlers.
+ */
+
+// --- _mock_env (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ */
+
+// --- _make_sync_config_manager (backend/src/api/routes/__tests__/test_migration_routes.py)
+/**!
+ */
+
+// --- TestProfileApi (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies profile API route contracts for preference read/update and Superset account lookup.
+ */
+
+// --- mock_profile_route_dependencies (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Provides deterministic dependency overrides for profile route tests.
+ * @post Dependencies are overridden for current test and restored afterward.
+ * @pre App instance is initialized.
+ */
+
+// --- profile_route_deps_fixture (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Pytest fixture wrapper for profile route dependency overrides.
+ * @post Yields overridden dependencies and clears overrides after test.
+ * @pre None.
+ */
+
+// --- _build_preference_response (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Builds stable profile preference response payload for route tests.
+ * @post Returns ProfilePreferenceResponse object with deterministic timestamps.
+ * @pre user_id is provided.
+ */
+
+// --- test_get_profile_preferences_returns_self_payload (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies GET /api/profile/preferences returns stable self-scoped payload.
+ * @post Response status is 200 and payload contains current user preference.
+ * @pre Authenticated user context is available.
+ */
+
+// --- test_patch_profile_preferences_success (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies PATCH /api/profile/preferences persists valid payload through route mapping.
+ * @post Response status is 200 with saved preference payload.
+ * @pre Valid request payload and authenticated user.
+ */
+
+// --- test_patch_profile_preferences_validation_error (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies route maps domain validation failure to HTTP 422 with actionable details.
+ * @post Response status is 422 and includes validation messages.
+ * @pre Service raises ProfileValidationError.
+ */
+
+// --- test_patch_profile_preferences_cross_user_denied (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies route maps domain authorization guard failure to HTTP 403.
+ * @post Response status is 403 with denial message.
+ * @pre Service raises ProfileAuthorizationError.
+ */
+
+// --- test_lookup_superset_accounts_success (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies lookup route returns success payload with normalized candidates.
+ * @post Response status is 200 and items list is returned.
+ * @pre Valid environment_id and service success response.
+ */
+
+// --- test_lookup_superset_accounts_env_not_found (backend/src/api/routes/__tests__/test_profile_api.py)
+/**!
+ * @brief Verifies lookup route maps missing environment to HTTP 404.
+ * @post Response status is 404 with explicit message.
+ * @pre Service raises EnvironmentNotFoundError.
+ */
+
+// --- TestReportsApi (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Contract tests for GET /api/reports defaults, pagination, and filtering behavior.
+ * @invariant API response contract contains {items,total,page,page_size,has_next,applied_filters}.
+ */
+
+// --- _make_task (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Build Task fixture with controlled timestamps/status for reports list/detail normalization.
+ */
+
+// --- test_get_reports_default_pagination_contract (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint default pagination and contract keys for mixed task statuses.
+ */
+
+// --- test_get_reports_filter_and_pagination (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint applies task-type/status filters and pagination boundaries.
+ */
+
+// --- test_get_reports_handles_mixed_naive_and_aware_datetimes (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports sorting remains stable when task timestamps mix naive and timezone-aware datetimes.
+ */
+
+// --- test_get_reports_invalid_filter_returns_400 (backend/src/api/routes/__tests__/test_reports_api.py)
+/**!
+ * @brief Validate reports list endpoint rejects unsupported task type filters with HTTP 400.
+ */
+
+// --- TestReportsDetailApi (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Contract tests for GET /api/reports/{report_id} detail endpoint behavior.
+ * @invariant Detail endpoint tests must keep deterministic assertions for success and not-found contracts.
+ */
+
+// --- test_get_report_detail_success (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Validate report detail endpoint returns report body with diagnostics and next actions for existing task.
+ */
+
+// --- test_get_report_detail_not_found (backend/src/api/routes/__tests__/test_reports_detail_api.py)
+/**!
+ * @brief Validate report detail endpoint returns 404 when requested report identifier is absent.
+ */
+
+// --- TestReportsOpenapiConformance (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Validate implemented reports payload shape against OpenAPI-required top-level contract fields.
+ * @invariant List and detail payloads include required contract keys.
+ */
+
+// --- _FakeTaskManager (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Minimal task-manager fake exposing static task list for OpenAPI conformance checks.
+ * @invariant get_all_tasks returns seeded tasks unchanged.
+ */
+
+// --- _admin_user (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Provide admin principal fixture required by reports routes in conformance tests.
+ */
+
+// --- _task (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Construct deterministic task fixture consumed by reports list/detail payload assertions.
+ */
+
+// --- test_reports_list_openapi_required_keys (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Verify reports list endpoint includes all required OpenAPI top-level keys.
+ */
+
+// --- test_reports_detail_openapi_required_keys (backend/src/api/routes/__tests__/test_reports_openapi_conformance.py)
+/**!
+ * @brief Verify reports detail endpoint returns payload containing the report object key.
+ */
+
+// --- test_tasks_logs_module (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Contract testing for task logs API endpoints.
+ */
+
+// --- test_get_task_logs_success (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint returns filtered logs for an existing task.
+ */
+
+// --- test_get_task_logs_not_found (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint returns 404 when the task identifier is missing.
+ */
+
+// --- test_get_task_logs_invalid_limit (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate task logs endpoint enforces query validation for limit lower bound.
+ */
+
+// --- test_get_task_log_stats_success (backend/src/api/routes/__tests__/test_tasks_logs.py)
+/**!
+ * @brief Validate log stats endpoint returns success payload for an existing task.
+ */
+
+// --- AdminApi (backend/src/api/routes/admin.py)
+/**!
+ * @brief Admin API endpoints for user and role management.
+ * @invariant All endpoints in this module require 'Admin' role or 'admin' scope.
+ */
+
+// --- list_users (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all registered users.
+ * @post Returns a list of UserSchema objects.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- create_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new local user.
+ * @post New user is created in the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- update_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Updates an existing user.
+ * @post User record is updated in the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- delete_user (backend/src/api/routes/admin.py)
+/**!
+ * @brief Deletes a user.
+ * @post User record is removed from the database.
+ * @pre Current user has 'Admin' role.
+ */
+
+// --- list_roles (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all available roles.
+ */
+
+// --- create_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new system role with associated permissions.
+ * @post New Role record is created in auth.db.
+ * @pre Role name must be unique.
+ */
+
+// --- update_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Updates an existing role's metadata and permissions.
+ * @post Role record is updated in auth.db.
+ * @pre role_id must be a valid existing role UUID.
+ */
+
+// --- delete_role (backend/src/api/routes/admin.py)
+/**!
+ * @brief Removes a role from the system.
+ * @post Role record is removed from auth.db.
+ * @pre role_id must be a valid existing role UUID.
+ */
+
+// --- list_ad_mappings (backend/src/api/routes/admin.py)
+/**!
+ * @brief Lists all AD Group to Role mappings.
+ */
+
+// --- create_ad_mapping (backend/src/api/routes/admin.py)
+/**!
+ * @brief Creates a new AD Group mapping.
+ */
+
+// --- AdminApiKeyRoutes (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Admin API endpoints for API key management — list, generate (one-time reveal), and revoke.
+ * @invariant DELETE /api/admin/api-keys/{id} soft-deletes (active=False), preserves row for audit.
+ */
+
+// --- ApiKeyCreateRequest (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- ApiKeyCreateResponse (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- ApiKeyListItem (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- ApiKeyRevokeResponse (backend/src/api/routes/admin_api_keys.py)
+/**!
+ */
+
+// --- list_api_keys (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief List all API keys — NEVER returns key_hash or raw_key.
+ * @post Returns list of ApiKeyListItem without sensitive fields.
+ * @pre Requires admin:settings WRITE permission.
+ */
+
+// --- create_api_key (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Generate a new API key — returns raw key ONCE, never stored or retrievable again.
+ * @post Creates APIKey row with SHA-256 hash. Returns raw key in response.
+ * @pre Requires admin:settings WRITE permission. name is required, at least one permission.
+ */
+
+// --- revoke_api_key (backend/src/api/routes/admin_api_keys.py)
+/**!
+ * @brief Revoke an API key by setting active=False. Preserves row for audit.
+ * @post Sets active=False on the key. Returns 404 if already revoked or not found.
+ * @pre Requires admin:settings WRITE permission.
+ */
+
+// --- AssistantAdminRoutes (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief FastAPI route handlers for assistant admin operations — conversation listing, deletion, history, audit.
+ * @invariant Audit endpoint requires tasks:READ permission.
+ */
+
+// --- list_conversations (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Return paginated conversation list for current user with archived flag and last message preview.
+ * @post Conversations are grouped by conversation_id sorted by latest activity descending.
+ * @pre Authenticated user context and valid pagination params.
+ */
+
+// --- delete_conversation (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Soft-delete or hard-delete a conversation and clear its in-memory trace.
+ * @post Conversation records are removed from DB and CONVERSATIONS cache.
+ * @pre conversation_id belongs to current_user.
+ */
+
+// --- get_history (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Retrieve paginated assistant conversation history for current user.
+ * @post Returns persistent messages and mirrored in-memory snapshot for diagnostics.
+ * @pre Authenticated user is available and page params are valid.
+ */
+
+// --- get_assistant_audit (backend/src/api/routes/assistant/_admin_routes.py)
+/**!
+ * @brief Return assistant audit decisions for current user from persistent and in-memory stores.
+ * @post Audit payload is returned in reverse chronological order from DB.
+ * @pre User has tasks:READ permission.
+ */
+
+// --- AssistantCommandParser (backend/src/api/routes/assistant/_command_parser.py)
+/**!
+ * @brief Deterministic RU/EN command text parser that converts user messages into intent payloads.
+ * @invariant Every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+ */
+
+// --- _parse_command (backend/src/api/routes/assistant/_command_parser.py)
+/**!
+ * @brief Deterministically parse RU/EN command text into intent payload.
+ * @invariant every return path includes domain, operation, entities, confidence, risk_level, requires_confirmation.
+ * @post Returns intent dict with domain/operation/entities/confidence/risk fields.
+ * @pre message contains raw user text and config manager resolves environments.
+ */
+
+// --- AssistantDatasetReview (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Dataset review context loading and intent planning for the assistant API.
+ * @invariant Dataset review operations are always scoped to the owner's session.
+ */
+
+// --- _serialize_dataset_review_context (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Build assistant-safe dataset-review context snapshot with masked imported-filter payloads for session-scoped assistant routing.
+ * @post Returns a serializable dictionary containing the complete review context.
+ * @pre session_id is a valid active review session identifier.
+ */
+
+// --- _load_dataset_review_context (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Load owner-scoped dataset-review context for assistant planning and grounded response generation.
+ * @post Returns a loaded context object with session data and findings.
+ * @pre session_id is a valid active review session identifier.
+ */
+
+// --- _extract_dataset_review_target (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Extract structured dataset-review focus target hints embedded in assistant prompts.
+ */
+
+// --- _match_dataset_review_field (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Resolve one semantic field from assistant-visible context by id or user-visible label.
+ */
+
+// --- _extract_quoted_segment (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Extract one quoted assistant command segment after a label token.
+ */
+
+// --- _plan_dataset_review_intent (backend/src/api/routes/assistant/_dataset_review.py)
+/**!
+ * @brief Parse session-scoped dataset-review assistant commands before falling back to generic assistant tool routing.
+ */
+
+// --- AssistantDatasetReviewDispatch (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Dispatch and confirmation handling for dataset-review assistant intents.
+ * @invariant Dataset review dispatch requires valid session version for write operations.
+ */
+
+// --- _dataset_review_conflict_http_exception (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Convert dataset-review optimistic-lock conflicts into shared 409 assistant semantics.
+ */
+
+// --- _dispatch_dataset_review_intent (backend/src/api/routes/assistant/_dataset_review_dispatch.py)
+/**!
+ * @brief Route confirmed dataset-review assistant intents through existing backend dataset-review APIs and orchestration boundaries.
+ * @post Returns a structured response with planned actions and confirmations.
+ * @pre context contains valid session data and user intent.
+ */
+
+// --- AssistantDispatch (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Intent dispatch engine, confirmation summary, and clarification text for the assistant API.
+ * @invariant Unsupported operations are rejected via HTTPException(400).
+ */
+
+// --- _clarification_text_for_intent (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Convert technical missing-parameter errors into user-facing clarification prompts.
+ * @post Returned text is human-readable and actionable for target operation.
+ * @pre state was classified as needs_clarification for current intent/error combination.
+ */
+
+// --- _async_confirmation_summary (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Build human-readable confirmation prompt for an intent before execution.
+ * @post Returns a formatted summary string suitable for display to the user.
+ * @pre actions is a non-empty list of planned review actions.
+ */
+
+// --- _dispatch_intent (backend/src/api/routes/assistant/_dispatch.py)
+/**!
+ * @brief Execute parsed assistant intent via existing task/plugin/git services.
+ * @invariant unsupported operations are rejected via HTTPException(400).
+ * @post Returns response text, optional task id, and UI actions for follow-up.
+ * @pre intent operation is known and actor permissions are validated per operation.
+ */
+
+// --- AssistantHistory (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Conversation history, audit trail, and confirmation persistence helpers for the assistant API.
+ * @invariant Failed persistence attempts always rollback before returning.
+ */
+
+// --- _append_history (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Append conversation message to in-memory history buffer.
+ * @invariant every appended entry includes generated message_id and created_at timestamp.
+ * @post Message entry is appended to CONVERSATIONS key list.
+ * @pre user_id and conversation_id identify target conversation bucket.
+ */
+
+// --- _persist_message (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist assistant/user message record to database.
+ * @invariant failed persistence attempts always rollback before returning.
+ * @post Message row is committed or persistence failure is logged.
+ * @pre db session is writable and message payload is serializable.
+ */
+
+// --- _audit (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Append in-memory audit record for assistant decision trace.
+ * @invariant persisted in-memory audit entry always contains created_at in ISO format.
+ * @post ASSISTANT_AUDIT list for user contains new timestamped entry.
+ * @pre payload describes decision/outcome fields.
+ */
+
+// --- _persist_audit (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist structured assistant audit payload in database.
+ * @post Audit row is committed or failure is logged with rollback.
+ * @pre db session is writable and payload is JSON-serializable.
+ */
+
+// --- _persist_confirmation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Persist confirmation token record to database.
+ * @post Confirmation row exists in persistent storage.
+ * @pre record contains id/user/intent/dispatch/expiry fields.
+ */
+
+// --- _update_confirmation_state (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Update persistent confirmation token lifecycle state.
+ * @post State and consumed_at fields are updated when applicable.
+ * @pre confirmation_id references existing row.
+ */
+
+// --- _load_confirmation_from_db (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Load confirmation token from database into in-memory model.
+ * @post Returns ConfirmationRecord when found, otherwise None.
+ * @pre confirmation_id may or may not exist in storage.
+ */
+
+// --- _ensure_conversation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Resolve active conversation id in memory or create a new one.
+ * @post Returns stable conversation id and updates USER_ACTIVE_CONVERSATION.
+ * @pre user_id identifies current actor.
+ */
+
+// --- _resolve_or_create_conversation (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Resolve active conversation using explicit id, memory cache, or persisted history.
+ * @post Returns conversation id and updates USER_ACTIVE_CONVERSATION cache.
+ * @pre user_id and db session are available.
+ */
+
+// --- _cleanup_history_ttl (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Enforce assistant message retention window by deleting expired rows and in-memory records.
+ * @post Messages older than ASSISTANT_MESSAGE_TTL_DAYS are removed from persistence and memory mirrors.
+ * @pre db session is available and user_id references current actor scope.
+ */
+
+// --- _is_conversation_archived (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Determine archived state for a conversation based on last update timestamp.
+ * @post Returns True when conversation inactivity exceeds archive threshold.
+ * @pre updated_at can be null for empty conversations.
+ */
+
+// --- _coerce_query_bool (backend/src/api/routes/assistant/_history.py)
+/**!
+ * @brief Normalize bool-like query values for compatibility in direct handler invocations/tests.
+ * @post Returns deterministic boolean flag.
+ * @pre value may be bool, string, or FastAPI Query metadata object.
+ */
+
+// --- AssistantLlmPlanner (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief LLM-based intent planning, tool catalog construction, and authorization for the assistant API.
+ * @invariant Tool catalog is filtered by user permissions before being sent to LLM.
+ * @post LLM tool catalog filtered and returned
+ * @pre Assistant routes initialized, user authenticated
+ */
+
+// --- _check_any_permission (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Validate user against alternative permission checks (logical OR).
+ * @post Returns on first successful permission; raises 403-like HTTPException otherwise.
+ * @pre checks list contains resource-action tuples.
+ */
+
+// --- _has_any_permission (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Check whether user has at least one permission tuple from the provided list.
+ * @post Returns True when at least one permission check passes.
+ * @pre current_user and checks list are valid.
+ */
+
+// --- _build_tool_catalog (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Build current-user tool catalog for LLM planner with operation contracts and defaults.
+ * @post Returns list of executable tools filtered by permission and runtime availability.
+ * @pre current_user is authenticated; config/db are available.
+ */
+
+// --- _coerce_intent_entities (backend/src/api/routes/assistant/_llm_planner.py)
+/**!
+ * @brief Normalize intent entity value types from LLM output to route-compatible values.
+ * @post Returned intent has numeric ids coerced where possible and string values stripped.
+ * @pre intent contains entities dict or missing entities.
+ */
+
+// --- AssistantLlmPlannerIntent (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief LLM-based intent planning and authorization for the assistant API — separated from tool catalog.
+ * @invariant Production deployments always require confirmation.
+ * @post Intent planning registered with confirmation gate
+ * @pre Assistant routes initialized, user authenticated
+ */
+
+// --- _plan_intent_with_llm (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief Use active LLM provider to select best tool/operation from dynamic catalog.
+ * @post Returns normalized intent dict when planning succeeds; otherwise None.
+ * @pre tools list contains allowed operations for current user.
+ */
+
+// --- _authorize_intent (backend/src/api/routes/assistant/_llm_planner_intent.py)
+/**!
+ * @brief Validate user permissions for parsed intent before confirmation/dispatch.
+ * @post Returns if authorized; raises HTTPException(403) when denied.
+ * @pre intent.operation is present for known assistant command domains.
+ */
+
+// --- AssistantResolvers (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Environment, dashboard, provider, and task resolution utilities for the assistant API.
+ * @invariant Resolution functions never raise; they return None on failure.
+ */
+
+// --- _extract_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Extract first regex match group from text by ordered pattern list.
+ * @post Returns first matched token or None.
+ * @pre patterns contain at least one capture group.
+ */
+
+// --- _resolve_env_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve environment identifier/name token to canonical environment id.
+ * @post Returns matched environment id or None.
+ * @pre config_manager provides environment list.
+ */
+
+// --- _is_production_env (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Determine whether environment token resolves to production-like target.
+ * @post Returns True for production/prod synonyms, else False.
+ * @pre config_manager provides environments or token text is provided.
+ */
+
+// --- _resolve_provider_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve provider token to provider id with active/default fallback.
+ * @post Returns provider id or None when no providers configured.
+ * @pre db session can load provider list through LLMProviderService.
+ */
+
+// --- _get_default_environment_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve default environment id from settings or first configured environment.
+ * @post Returns default environment id or None when environment list is empty.
+ * @pre config_manager returns environments list.
+ */
+
+// --- _resolve_dashboard_id_by_ref (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve dashboard id by title or slug reference in selected environment.
+ * @post Returns dashboard id when uniquely matched, otherwise None.
+ * @pre dashboard_ref is a non-empty string-like token.
+ */
+
+// --- _resolve_dashboard_id_entity (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve dashboard id from intent entities using numeric id or dashboard_ref fallback.
+ * @post Returns resolved dashboard id or None when ambiguous/unresolvable.
+ * @pre entities may contain dashboard_id as int/str and optional dashboard_ref.
+ */
+
+// --- _get_environment_name_by_id (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Resolve human-readable environment name by id.
+ * @post Returns matching environment name or fallback id.
+ * @pre environment id may be None.
+ */
+
+// --- _extract_result_deep_links (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Build deep-link actions to verify task result from assistant chat.
+ * @post Returns zero or more assistant actions for dashboard open/diff.
+ * @pre task object is available.
+ */
+
+// --- _build_task_observability_summary (backend/src/api/routes/assistant/_resolvers.py)
+/**!
+ * @brief Build compact textual summary for completed tasks to reduce "black box" effect.
+ * @post Returns non-empty summary line for known task types or empty string fallback.
+ * @pre task may contain plugin-specific result payload.
+ */
+
+// --- AssistantRoutes (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief FastAPI route handlers for the assistant API — message sending, confirmation, conversation management.
+ * @invariant Risky operations are never executed without valid confirmation token.
+ */
+
+// --- send_message (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Parse assistant command, enforce safety gates, and dispatch executable intent.
+ * @invariant non-safe operations are gated with confirmation before execution from this endpoint.
+ * @post Response state is one of clarification/confirmation/started/success/denied/failed.
+ * @pre Authenticated user is available and message text is non-empty.
+ */
+
+// --- confirm_operation (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Execute previously requested risky operation after explicit user confirmation.
+ * @post Confirmation state becomes consumed and operation result is persisted in history.
+ * @pre confirmation_id exists, belongs to current user, is pending, and not expired.
+ */
+
+// --- cancel_operation (backend/src/api/routes/assistant/_routes.py)
+/**!
+ * @brief Cancel pending risky operation and mark confirmation token as cancelled.
+ * @post Confirmation becomes cancelled and cannot be executed anymore.
+ * @pre confirmation_id exists, belongs to current user, and is still pending.
+ */
+
+// --- AssistantSchemas (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Pydantic models, in-memory stores, and permission mappings for the assistant API.
+ * @invariant In-memory stores are module-level singletons shared across the assistant package.
+ */
+
+// --- AssistantMessageRequest (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Input payload for assistant message endpoint.
+ * @invariant message is always non-empty and no longer than 4000 characters.
+ * @post Request object provides message text and optional conversation binding.
+ * @pre message length is within accepted bounds.
+ */
+
+// --- AssistantAction (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief UI action descriptor returned with assistant responses.
+ * @invariant type and label are required for every UI action.
+ * @post Action can be rendered as button on frontend.
+ * @pre type and label are provided by orchestration logic.
+ */
+
+// --- AssistantMessageResponse (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief Output payload contract for assistant interaction endpoints.
+ * @invariant created_at and state are always present in endpoint responses.
+ * @post Payload may include task_id/confirmation_id/actions for UI follow-up.
+ * @pre Response includes deterministic state and text.
+ */
+
+// --- ConfirmationRecord (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory confirmation token model for risky operation dispatch.
+ * @invariant state defaults to "pending" and expires_at bounds confirmation validity.
+ * @post Record tracks lifecycle state and expiry timestamp.
+ * @pre intent/dispatch/user_id are populated at confirmation request time.
+ */
+
+// --- CONVERSATIONS (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory conversation history store: {(user_id, conversation_id) -> [message_records]}
+ */
+
+// --- ASSISTANT_AUDIT (backend/src/api/routes/assistant/_schemas.py)
+/**!
+ * @brief In-memory assistant audit trail: {user_id -> [audit_records]}. Volatile — lost on restart.
+ */
+
+// --- CleanReleaseApi (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Expose clean release endpoints for candidate preparation and subsequent compliance flow.
+ * @invariant API never reports prepared status if preparation errors are present.
+ * @post Candidate preparation, manifest, and compliance routes expose deterministic API payloads without reporting prepared state on failed preparation.
+ * @pre Clean release repository and preparation service dependencies are configured for the current request scope.
+ */
+
+// --- PrepareCandidateRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate preparation endpoint.
+ */
+
+// --- StartCheckRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for clean compliance check run startup.
+ */
+
+// --- RegisterCandidateRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate registration endpoint.
+ */
+
+// --- ImportArtifactsRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for candidate artifact import endpoint.
+ */
+
+// --- BuildManifestRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for manifest build endpoint.
+ */
+
+// --- CreateComplianceRunRequest (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Request schema for compliance run creation with optional manifest pinning.
+ */
+
+// --- register_candidate_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Register a clean-release candidate for headless lifecycle.
+ * @post Candidate is persisted in DRAFT status.
+ * @pre Candidate identifier is unique.
+ */
+
+// --- import_candidate_artifacts_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Import candidate artifacts in headless flow.
+ * @post Artifacts are persisted and candidate advances to PREPARED if it was DRAFT.
+ * @pre Candidate exists and artifacts array is non-empty.
+ */
+
+// --- build_candidate_manifest_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Build immutable manifest snapshot for prepared candidate.
+ * @post Returns created ManifestDTO with incremented version.
+ * @pre Candidate exists and has imported artifacts.
+ */
+
+// --- get_candidate_overview_v2_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return expanded candidate overview DTO for headless lifecycle visibility.
+ * @post Returns CandidateOverviewDTO built from the same repository state used by headless US1 endpoints.
+ * @pre Candidate exists.
+ */
+
+// --- prepare_candidate_endpoint (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Prepare candidate with policy evaluation and deterministic manifest generation.
+ * @post Returns preparation result including manifest reference and violations.
+ * @pre Candidate and active policy exist in repository.
+ */
+
+// --- start_check (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Start and finalize a clean compliance check run and persist report artifacts.
+ * @post Returns accepted payload with check_run_id and started_at.
+ * @pre Active policy and candidate exist.
+ */
+
+// --- get_check_status (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return terminal/intermediate status payload for a check run.
+ * @post Deterministic payload shape includes checks and violations arrays.
+ * @pre check_run_id references an existing run.
+ */
+
+// --- get_report (backend/src/api/routes/clean_release.py)
+/**!
+ * @brief Return persisted compliance report by report_id.
+ * @post Returns serialized report object.
+ * @pre report_id references an existing report.
+ */
+
+// --- CleanReleaseV2Api (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Redesigned clean release API for headless candidate lifecycle.
+ * @post Candidate registration, approval, publication, and revocation routes are registered without behavior changes.
+ * @pre Clean release repository dependency is available for candidate lifecycle endpoints.
+ */
+
+// --- ApprovalRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for approval request payload.
+ */
+
+// --- PublishRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for publication request payload.
+ */
+
+// --- RevokeRequest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Schema for revocation request payload.
+ */
+
+// --- register_candidate (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Register a new release candidate.
+ * @post Candidate is saved in repository.
+ * @pre Payload contains required fields (id, version, source_snapshot_ref, created_by).
+ */
+
+// --- import_artifacts (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Associate artifacts with a release candidate.
+ * @post Artifacts are processed (placeholder).
+ * @pre Candidate exists.
+ */
+
+// --- build_manifest (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Generate distribution manifest for a candidate.
+ * @post Manifest is created and saved.
+ * @pre Candidate exists.
+ */
+
+// --- approve_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to record candidate approval.
+ */
+
+// --- reject_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to record candidate rejection.
+ */
+
+// --- publish_candidate_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to publish an approved candidate.
+ */
+
+// --- revoke_publication_endpoint (backend/src/api/routes/clean_release_v2.py)
+/**!
+ * @brief Endpoint to revoke a previous publication.
+ */
+
+// --- DashboardsApi (backend/src/api/routes/dashboards/__init__.py)
+/**!
+ * @brief API endpoints for the Dashboard Hub - listing dashboards with Git and task status
+ * @invariant All dashboard responses include git_status and last_task metadata
+ * @post Dashboard responses are projected into DashboardsResponse DTO.
+ * @pre Valid environment configurations exist in ConfigManager.
+ */
+
+// --- DashboardActionRoutes (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Dashboard action route handlers — migrate, backup.
+ */
+
+// --- migrate_dashboards (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Trigger bulk migration of dashboards from source to target environment
+ * @post Task is created and queued for execution
+ * @pre dashboard_ids is a non-empty list
+ */
+
+// --- backup_dashboards (backend/src/api/routes/dashboards/_action_routes.py)
+/**!
+ * @brief Trigger bulk backup of dashboards with optional cron schedule
+ * @post If schedule is provided, a scheduled task is created
+ * @pre dashboard_ids is a non-empty list
+ */
+
+// --- DashboardDetailRoutes (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Dashboard detail, db-mappings, task history, thumbnail route handlers.
+ */
+
+// --- get_database_mappings (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Get database mapping suggestions between source and target environments
+ * @post Returns list of suggested database mappings with confidence scores
+ * @pre source_env_id and target_env_id are valid environment IDs
+ */
+
+// --- get_dashboard_detail (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Fetch detailed dashboard info with related charts and datasets
+ * @post Returns dashboard detail payload for overview page
+ * @pre env_id must be valid and dashboard ref (slug or id) must exist
+ */
+
+// --- get_dashboard_tasks_history (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Returns history of backup and LLM validation tasks for a dashboard.
+ * @post Response contains sorted task history (newest first).
+ * @pre dashboard ref (slug or id) is valid.
+ */
+
+// --- get_dashboard_thumbnail (backend/src/api/routes/dashboards/_detail_routes.py)
+/**!
+ * @brief Proxies Superset dashboard thumbnail with cache support.
+ * @post Returns image bytes or 202 when thumbnail is being prepared by Superset.
+ * @pre env_id must exist.
+ */
+
+// --- DashboardHelpers (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Basic helper functions for dashboard route handlers — slug resolution, filter normalization.
+ */
+
+// --- _find_dashboard_id_by_slug (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard numeric ID by slug using Superset list endpoint.
+ * @post Returns dashboard ID when found, otherwise None.
+ * @pre `dashboard_slug` is non-empty.
+ */
+
+// --- _resolve_dashboard_id_from_ref (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard ID from slug-first reference with numeric fallback.
+ * @post Returns a valid dashboard ID or raises HTTPException(404).
+ * @pre `dashboard_ref` is provided in route path.
+ */
+
+// --- _find_dashboard_id_by_slug_async (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard numeric ID by slug using async Superset list endpoint.
+ * @post Returns dashboard ID when found, otherwise None.
+ * @pre dashboard_slug is non-empty.
+ */
+
+// --- _resolve_dashboard_id_from_ref_async (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Resolve dashboard ID from slug-first reference using async Superset client.
+ * @post Returns valid dashboard ID or raises HTTPException(404).
+ * @pre dashboard_ref is provided in route path.
+ */
+
+// --- _normalize_filter_values (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Normalize query filter values to lower-cased non-empty tokens.
+ * @post Returns trimmed normalized list preserving input order.
+ * @pre values may be None or list of strings.
+ */
+
+// --- _dashboard_git_filter_value (backend/src/api/routes/dashboards/_helpers.py)
+/**!
+ * @brief Build comparable git status token for dashboards filtering.
+ * @post Returns one of ok|diff|no_repo|error|pending.
+ * @pre dashboard payload may contain git_status or None.
+ */
+
+// --- DashboardListingRoutes (backend/src/api/routes/dashboards/_listing_routes.py)
+/**!
+ * @brief Dashboard listing route handler for Dashboard Hub.
+ */
+
+// --- get_dashboards (backend/src/api/routes/dashboards/_listing_routes.py)
+/**!
+ * @brief Fetch list of dashboards from a specific environment with Git status and last task status
+ * @post Response includes effective profile filter metadata for main dashboards page context
+ * @pre page_size must be between 1 and 100 if provided
+ */
+
+// --- DashboardProjection (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Dashboard response projection and profile-filter helpers for Dashboard Hub routes.
+ */
+
+// --- _normalize_actor_alias_token (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Normalize actor alias token to comparable trim+lower text.
+ */
+
+// --- _normalize_owner_display_token (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Project owner payload value into stable display string for API response contracts.
+ */
+
+// --- _normalize_dashboard_owner_values (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Normalize dashboard owners payload to optional list of display strings.
+ */
+
+// --- _project_dashboard_response_items (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Project dashboard payloads to response-contract-safe shape.
+ */
+
+// --- _get_profile_filter_binding (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Resolve dashboard profile-filter binding through current or legacy profile service contracts.
+ */
+
+// --- _resolve_profile_actor_aliases (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Resolve stable actor aliases for profile filtering without per-dashboard detail fan-out.
+ */
+
+// --- _matches_dashboard_actor_aliases (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Apply profile actor matching against multiple aliases (username + optional display name).
+ */
+
+// --- _task_matches_dashboard (backend/src/api/routes/dashboards/_projection.py)
+/**!
+ * @brief Checks whether task params are tied to a specific dashboard and environment.
+ */
+
+// --- DashboardsRouter (backend/src/api/routes/dashboards/_router.py)
+/**!
+ * @brief Single APIRouter instance for all dashboard endpoints.
+ */
+
+// --- DashboardSchemas (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO classes for the Dashboard Hub API.
+ */
+
+// --- GitStatus (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard Git synchronization status.
+ */
+
+// --- DashboardItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO representing a single dashboard with projected metadata.
+ */
+
+// --- EffectiveProfileFilter (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Metadata about applied profile filters for UI context.
+ */
+
+// --- DashboardsResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Envelope DTO for paginated dashboards list.
+ */
+
+// --- DashboardChartItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for a chart linked to a dashboard.
+ */
+
+// --- DashboardDatasetItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for a dataset associated with a dashboard.
+ */
+
+// --- DashboardDetailResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Detailed dashboard metadata including children.
+ */
+
+// --- DashboardTaskHistoryItem (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Individual history record entry.
+ */
+
+// --- DashboardTaskHistoryResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Collection DTO for task history.
+ */
+
+// --- DatabaseMapping (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for cross-environment database ID mapping.
+ */
+
+// --- DatabaseMappingsResponse (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief Wrapper for database mappings.
+ */
+
+// --- MigrateRequest (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard migration requests.
+ */
+
+// --- BackupRequest (backend/src/api/routes/dashboards/_schemas.py)
+/**!
+ * @brief DTO for dashboard backup requests.
+ */
+
+// --- DatasetReviewDependencies (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Dependency injection, serialization helpers, and feature-flag guards for dataset review endpoints.
+ */
+
+// --- StartSessionRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for starting one dataset review session.
+ */
+
+// --- UpdateSessionRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for lifecycle state updates on an existing session.
+ */
+
+// --- SessionCollectionResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Paginated session collection response.
+ */
+
+// --- ExportArtifactResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Inline export response for documentation or validation outputs.
+ */
+
+// --- FieldSemanticUpdateRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for field-level semantic candidate acceptance or manual override.
+ */
+
+// --- FeedbackRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for thumbs up/down feedback.
+ */
+
+// --- ClarificationAnswerRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for submitting one clarification answer.
+ */
+
+// --- ClarificationSessionSummaryResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Summary DTO for current clarification session state.
+ */
+
+// --- ClarificationStateResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Response DTO for current clarification state and active question payload.
+ */
+
+// --- ClarificationAnswerResultResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Response DTO for one clarification answer mutation result.
+ */
+
+// --- FeedbackResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Minimal response DTO for persisted AI feedback actions.
+ */
+
+// --- ApproveMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Optional request DTO for explicit mapping approval audit notes.
+ */
+
+// --- BatchApproveSemanticItemRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for one batch semantic-approval item.
+ */
+
+// --- BatchApproveSemanticRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for explicit batch semantic approvals.
+ */
+
+// --- BatchApproveMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for explicit batch mapping approvals.
+ */
+
+// --- PreviewEnqueueResultResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Async preview trigger response exposing only enqueue state.
+ */
+
+// --- MappingCollectionResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Wrapper for execution mapping list responses.
+ */
+
+// --- UpdateExecutionMappingRequest (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Request DTO for one manual execution-mapping override update.
+ */
+
+// --- LaunchDatasetResponse (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Launch result exposing audited run context and SQL Lab redirect target.
+ */
+
+// --- _require_auto_review_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard US1 dataset review endpoints behind the configured feature flag.
+ */
+
+// --- _require_clarification_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard clarification-specific US2 endpoints behind the configured feature flag.
+ */
+
+// --- _require_execution_flag (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Guard US3 execution endpoints behind the configured feature flag.
+ */
+
+// --- _get_repository (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build repository dependency.
+ */
+
+// --- _get_orchestrator (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build orchestrator dependency.
+ */
+
+// --- _get_clarification_engine (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build clarification engine dependency.
+ */
+
+// --- _serialize_session_summary (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map session aggregate into stable API summary DTO.
+ */
+
+// --- _serialize_session_detail (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map session aggregate into stable API detail DTO.
+ */
+
+// --- _require_session_version_header (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Read the optimistic-lock session version header.
+ */
+
+// --- _build_session_version_conflict_http_exception (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Normalize optimistic-lock conflict errors into HTTP 409 responses.
+ */
+
+// --- _enforce_session_version (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert repository optimistic-lock conflicts into deterministic HTTP 409 responses.
+ */
+
+// --- _get_owned_session_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve one session for current user or collaborator scope, returning 404 when inaccessible.
+ */
+
+// --- _require_owner_mutation_scope (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Enforce owner-only mutation scope.
+ */
+
+// --- _prepare_owned_session_mutation (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve owner-scoped mutation session and enforce optimistic-lock version.
+ */
+
+// --- _commit_owned_session_mutation (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Centralize session version bumping and commit semantics.
+ */
+
+// --- _record_session_event (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Persist one explicit audit event for an owned mutation endpoint.
+ */
+
+// --- _serialize_semantic_field (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one semantic field into stable DTO.
+ */
+
+// --- _serialize_execution_mapping (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one execution mapping into stable DTO.
+ */
+
+// --- _serialize_preview (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one preview into stable DTO.
+ */
+
+// --- _serialize_run_context (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Map one run context into stable DTO.
+ */
+
+// --- _serialize_clarification_question_payload (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert clarification engine payload into API DTO.
+ */
+
+// --- _serialize_clarification_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Convert clarification engine state into API response.
+ */
+
+// --- _serialize_empty_clarification_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Return empty clarification payload.
+ */
+
+// --- _get_latest_clarification_session_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve the latest clarification aggregate or raise.
+ */
+
+// --- _get_owned_mapping_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve one execution mapping inside one owned session.
+ */
+
+// --- _get_owned_field_or_404 (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve a semantic field inside one owned session.
+ */
+
+// --- _map_candidate_provenance (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Translate accepted semantic candidate type into stable field provenance.
+ */
+
+// --- _resolve_candidate_source_version (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Resolve the semantic source version for one accepted candidate.
+ */
+
+// --- _update_semantic_field_state (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Apply field-level semantic manual override or candidate acceptance.
+ * @post Manual overrides always set manual provenance plus lock.
+ */
+
+// --- _build_sql_lab_redirect_url (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Build SQL Lab redirect URL.
+ */
+
+// --- _build_documentation_export (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Produce session documentation export content.
+ */
+
+// --- _build_validation_export (backend/src/api/routes/dataset_review_pkg/_dependencies.py)
+/**!
+ * @brief Produce validation-focused export content.
+ */
+
+// --- DatasetReviewRoutes (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for clarification question/answer content.
+ */
+
+// --- list_sessions (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief List resumable dataset review sessions for the current user.
+ */
+
+// --- start_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Start a new dataset review session from a Superset link or dataset selection.
+ */
+
+// --- get_session_detail (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the full accessible dataset review session aggregate.
+ */
+
+// --- update_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Update resumable lifecycle status for an owned session.
+ */
+
+// --- delete_session (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Archive or hard-delete a session owned by the current user.
+ */
+
+// --- export_documentation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Export documentation output for the current session.
+ */
+
+// --- export_validation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Export validation findings for the current session.
+ */
+
+// --- get_clarification_state (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the current clarification session summary and active question payload.
+ */
+
+// --- resume_clarification (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Resume clarification mode on the highest-priority unresolved question.
+ */
+
+// --- record_clarification_answer (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist one clarification answer before advancing the active pointer.
+ */
+
+// --- update_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Apply one field-level semantic candidate decision or manual override.
+ */
+
+// --- lock_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Lock one semantic field against later automatic overwrite.
+ */
+
+// --- unlock_field_semantic (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Unlock one semantic field so later automated candidate application may replace it.
+ */
+
+// --- approve_batch_semantic_fields (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Approve multiple semantic candidate decisions in one batch.
+ */
+
+// --- list_execution_mappings (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Return the current mapping-review set for one accessible session.
+ */
+
+// --- update_execution_mapping (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist one owner-authorized execution-mapping effective value override.
+ */
+
+// --- approve_execution_mapping (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Explicitly approve a warning-sensitive mapping transformation.
+ */
+
+// --- approve_batch_execution_mappings (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Approve multiple warning-sensitive execution mappings in one batch.
+ */
+
+// --- trigger_preview_generation (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Trigger Superset-side preview compilation for the current owned execution context.
+ */
+
+// --- launch_dataset (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Execute the current owned session launch handoff and return audited SQL Lab run context.
+ */
+
+// --- record_field_feedback (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for AI-assisted semantic field content.
+ */
+
+// --- record_clarification_feedback (backend/src/api/routes/dataset_review_pkg/_routes.py)
+/**!
+ * @brief Persist thumbs up/down feedback for clarification question/answer content.
+ */
+
+// --- DatasetsApi (backend/src/api/routes/datasets.py)
+/**!
+ * @brief API endpoints for the Dataset Hub - listing datasets with mapping progress
+ * @invariant All dataset responses include last_task metadata
+ * @post Returns dataset metadata with mapping status.
+ * @pre SupersetClient is available; env_id is valid.
+ */
+
+// --- MappedFields (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for dataset mapping progress statistics
+ */
+
+// --- LastTask (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for the most recent task associated with a dataset
+ */
+
+// --- DatasetItem (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Summary DTO for a dataset in the hub listing
+ */
+
+// --- LinkedDashboard (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for a dashboard linked to a dataset
+ */
+
+// --- DatasetColumn (backend/src/api/routes/datasets.py)
+/**!
+ * @brief DTO for a single dataset column's metadata
+ */
+
+// --- MetricItem (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Pydantic DTO for a dataset metric — carries Superset metric metadata.
+ */
+
+// --- DatasetDetailResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Detailed DTO for a dataset including columns, linked dashboards, and metrics.
+ */
+
+// --- StatsCounts (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Aggregate statistics for the Stats Bar — computed from full dataset list.
+ */
+
+// --- DatasetsResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Paginated response DTO for dataset listings with stats.
+ */
+
+// --- TaskResponse (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Response DTO containing a task ID for tracking
+ */
+
+// --- ColumnDescriptionUpdate (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for inline-edit of a column description.
+ */
+
+// --- MetricDescriptionUpdate (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for inline-edit of a metric description.
+ */
+
+// --- get_dataset_ids (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Fetch list of all dataset IDs from a specific environment (without pagination)
+ * @post Returns a list of all dataset IDs
+ * @pre env_id must be a valid environment ID
+ */
+
+// --- get_datasets (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Fetch list of datasets from a specific environment with mapping progress and stats.
+ * @post Response includes pagination metadata (page, page_size, total, total_pages) and stats object.
+ * @pre page_size must be between 1 and 100 if provided
+ */
+
+// --- MapColumnsRequest (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for initiating column mapping
+ */
+
+// --- map_columns (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Trigger bulk column mapping for datasets
+ * @post Task is created and queued for execution
+ * @pre dataset_ids is a non-empty list
+ */
+
+// --- GenerateDocsRequest (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Request DTO for initiating documentation generation
+ */
+
+// --- generate_docs (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Trigger bulk documentation generation for datasets
+ * @post Task is created and queued for execution
+ * @pre dataset_ids is a non-empty list
+ */
+
+// --- get_dataset_detail (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Get detailed dataset information including columns and linked dashboards
+ * @post Returns detailed dataset info with columns and linked dashboards
+ * @pre dataset_id is a valid dataset ID
+ */
+
+// --- _strip_html_tags (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Detect and strip HTML tags from a text string. Uses simple regex <[^>]*>.
+ */
+
+// --- update_column_description (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Save description for a single dataset column. Internal: GET full dataset from Superset, modify one column's description, PUT back.
+ * @post Column description in Superset is updated. Response confirms success.
+ * @pre dataset_id and column_id must exist in the target environment.
+ */
+
+// --- update_metric_description (backend/src/api/routes/datasets.py)
+/**!
+ * @brief Save description for a single dataset metric. Mirror of update_column_description for metrics.
+ * @post Metric description in Superset is updated.
+ * @pre dataset_id and metric_id must exist in the target environment.
+ */
+
+// --- EnvironmentsApi (backend/src/api/routes/environments.py)
+/**!
+ * @brief API endpoints for listing environments and their databases.
+ * @invariant Environment IDs must exist in the configuration.
+ */
+
+// --- _normalize_superset_env_url (backend/src/api/routes/environments.py)
+/**!
+ * @brief Canonicalize Superset environment URL to base host/path without trailing /api/v1.
+ * @post Returns normalized base URL.
+ * @pre raw_url can be empty.
+ */
+
+// --- ScheduleSchema (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- EnvironmentResponse (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- DatabaseResponse (backend/src/api/routes/environments.py)
+/**!
+ */
+
+// --- update_environment_schedule (backend/src/api/routes/environments.py)
+/**!
+ * @brief Update backup schedule for an environment.
+ * @post Backup schedule updated and scheduler reloaded.
+ * @pre Environment id exists, schedule is valid ScheduleSchema.
+ */
+
+// --- get_environment_databases (backend/src/api/routes/environments.py)
+/**!
+ * @brief Fetch the list of databases from a specific environment.
+ * @post Returns a list of database summaries from the environment.
+ * @pre Environment id exists.
+ */
+
+// --- GitPackage (backend/src/api/routes/git/__init__.py)
+/**!
+ * @brief Package root for decomposed git routes. Re-exports all public symbols from submodules.
+ * @invariant git_service and os are module-level attributes for test monkeypatch compatibility.
+ * @post Git API package exported
+ * @pre Git service initialized
+ */
+
+// --- GitConfigRoutes (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git server configuration CRUD and connection testing.
+ */
+
+// --- get_git_configs (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief List all configured Git servers.
+ */
+
+// --- create_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Register a new Git server configuration.
+ */
+
+// --- update_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Update an existing Git server configuration.
+ */
+
+// --- delete_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Remove a Git server configuration.
+ */
+
+// --- test_git_config (backend/src/api/routes/git/_config_routes.py)
+/**!
+ * @brief Validate connection to a Git server using provided credentials.
+ */
+
+// --- GitDeps (backend/src/api/routes/git/_deps.py)
+/**!
+ * @brief Shared dependency wiring for monkeypatch-safe git_service access and constants.
+ * @invariant get_git_service() resolves from sys.modules at call time so test monkeypatching
+ */
+
+// --- GitEnvironmentRoutes (backend/src/api/routes/git/_environment_routes.py)
+/**!
+ * @brief FastAPI endpoint for listing deployment environments.
+ */
+
+// --- GitGiteaRoutes (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief FastAPI endpoints for Gitea-specific repository operations.
+ */
+
+// --- list_gitea_repositories (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief List repositories in Gitea for a saved Gitea config.
+ */
+
+// --- create_gitea_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Create a repository in Gitea for a saved Gitea config.
+ */
+
+// --- delete_gitea_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Delete repository in Gitea for a saved Gitea config.
+ */
+
+// --- create_remote_repository (backend/src/api/routes/git/_gitea_routes.py)
+/**!
+ * @brief Create repository on remote Git server using selected provider config.
+ */
+
+// --- GitHelpers (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Shared helper functions for Git route modules.
+ */
+
+// --- _build_no_repo_status_payload (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Build a consistent status payload for dashboards without initialized repositories.
+ * @post Returns a stable payload compatible with frontend repository status parsing.
+ */
+
+// --- _handle_unexpected_git_route_error (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Convert unexpected route-level exceptions to stable 500 API responses.
+ * @post Raises HTTPException(500) with route-specific context.
+ * @pre `error` is a non-HTTPException instance.
+ */
+
+// --- _resolve_repository_status (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve repository status for one dashboard with graceful NO_REPO semantics.
+ * @post Returns standard status payload or `NO_REPO` payload when repository path is absent.
+ * @pre `dashboard_id` is a valid integer.
+ */
+
+// --- _get_git_config_or_404 (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve GitServerConfig by id or raise 404.
+ */
+
+// --- _resolve_repo_key_from_ref (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve repository folder key with slug-first strategy and deterministic fallback.
+ */
+
+// --- _sanitize_optional_identity_value (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Normalize optional identity value into trimmed string or None.
+ */
+
+// --- _resolve_current_user_git_identity (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Resolve configured Git username/email from current user's profile preferences.
+ */
+
+// --- _apply_git_identity_from_profile (backend/src/api/routes/git/_helpers.py)
+/**!
+ * @brief Apply user-scoped Git identity to repository-local config before write/pull operations.
+ */
+
+// --- GitMergeRoutes (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief FastAPI endpoints for merge operations (status, conflicts, resolve, abort, continue).
+ */
+
+// --- get_merge_status (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Return unfinished-merge status for repository (web-only recovery support).
+ */
+
+// --- get_merge_conflicts (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Return conflicted files with mine/theirs previews for web conflict resolver.
+ */
+
+// --- resolve_merge_conflicts (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Apply mine/theirs/manual conflict resolutions from WebUI and stage files.
+ */
+
+// --- abort_merge (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Abort unfinished merge from WebUI flow.
+ */
+
+// --- continue_merge (backend/src/api/routes/git/_merge_routes.py)
+/**!
+ * @brief Finalize unfinished merge from WebUI flow.
+ */
+
+// --- GitRepoLifecycleRoutes (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git lifecycle operations (sync, promote, deploy).
+ */
+
+// --- sync_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Sync dashboard state from Superset to Git using the GitPlugin.
+ */
+
+// --- promote_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Promote changes between branches via MR or direct merge.
+ */
+
+// --- deploy_dashboard (backend/src/api/routes/git/_repo_lifecycle_routes.py)
+/**!
+ * @brief Deploy dashboard from Git to a target environment.
+ */
+
+// --- GitRepoOperationsRoutes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief FastAPI endpoints for Git repository operations (commit, push, pull, status, diff, history).
+ */
+
+// --- commit_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Stage and commit changes in the dashboard's repository.
+ */
+
+// --- push_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Push local commits to the remote repository.
+ */
+
+// --- pull_changes (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Pull changes from the remote repository.
+ */
+
+// --- get_repository_status (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get current Git status for a dashboard repository.
+ */
+
+// --- get_repository_status_batch (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get Git statuses for multiple dashboard repositories in one request.
+ */
+
+// --- get_repository_diff (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Get Git diff for a dashboard repository.
+ */
+
+// --- generate_commit_message (backend/src/api/routes/git/_repo_operations_routes.py)
+/**!
+ * @brief Generate a suggested commit message using LLM.
+ */
+
+// --- GitRepoRoutes (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief FastAPI endpoints for core Git repository operations (init, binding, branches, checkout).
+ */
+
+// --- init_repository (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Link a dashboard to a Git repository and perform initial clone/init.
+ */
+
+// --- get_repository_binding (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Return repository binding with provider metadata for selected dashboard.
+ */
+
+// --- delete_repository (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Delete local repository workspace and DB binding for selected dashboard.
+ */
+
+// --- get_branches (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief List all branches for a dashboard's repository.
+ */
+
+// --- create_branch (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Create a new branch in the dashboard's repository.
+ */
+
+// --- checkout_branch (backend/src/api/routes/git/_repo_routes.py)
+/**!
+ * @brief Switch the dashboard's repository to a specific branch.
+ */
+
+// --- GitRouter (backend/src/api/routes/git/_router.py)
+/**!
+ * @brief Shared APIRouter for all Git route modules.
+ */
+
+// --- GitSchemas (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Defines Pydantic models for the Git integration API layer.
+ * @invariant All schemas must be compatible with the FastAPI router.
+ */
+
+// --- GitServerConfigBase (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Base schema for Git server configuration attributes.
+ */
+
+// --- GitServerConfigUpdate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for updating an existing Git server configuration.
+ */
+
+// --- GitServerConfigCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for creating a new Git server configuration.
+ */
+
+// --- GitServerConfigSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a Git server configuration with metadata.
+ */
+
+// --- GitRepositorySchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for tracking a local Git repository linked to a dashboard.
+ */
+
+// --- BranchSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a Git branch metadata.
+ */
+
+// --- CommitSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing Git commit details.
+ */
+
+// --- BranchCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for branch creation requests.
+ */
+
+// --- BranchCheckout (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for branch checkout requests.
+ */
+
+// --- CommitCreate (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for staging and committing changes.
+ */
+
+// --- ConflictResolution (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for resolving merge conflicts.
+ */
+
+// --- MergeStatusSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema representing unfinished merge status for repository.
+ */
+
+// --- MergeConflictFileSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing one conflicted file with optional side snapshots.
+ */
+
+// --- MergeResolveRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for resolving one or multiple merge conflicts.
+ */
+
+// --- MergeContinueRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for finishing merge with optional explicit commit message.
+ */
+
+// --- DeploymentEnvironmentSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for representing a target deployment environment.
+ */
+
+// --- DeployRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for dashboard deployment requests.
+ */
+
+// --- RepoInitRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for repository initialization requests.
+ */
+
+// --- RepositoryBindingSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing repository-to-config binding and provider metadata.
+ */
+
+// --- RepoStatusBatchRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for requesting repository statuses for multiple dashboards in a single call.
+ */
+
+// --- RepoStatusBatchResponse (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema for returning repository statuses keyed by dashboard ID.
+ */
+
+// --- GiteaRepoSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Schema describing a Gitea repository.
+ */
+
+// --- GiteaRepoCreateRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for creating a Gitea repository.
+ */
+
+// --- RemoteRepoSchema (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Provider-agnostic remote repository payload.
+ */
+
+// --- RemoteRepoCreateRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Provider-agnostic repository creation request.
+ */
+
+// --- PromoteRequest (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Request schema for branch promotion workflow.
+ */
+
+// --- PromoteResponse (backend/src/api/routes/git_schemas.py)
+/**!
+ * @brief Response schema for promotion operation result.
+ */
+
+// --- health_router (backend/src/api/routes/health.py)
+/**!
+ * @brief API endpoints for dashboard health monitoring and status aggregation.
+ */
+
+// --- get_health_summary (backend/src/api/routes/health.py)
+/**!
+ * @brief Get aggregated health status for all dashboards.
+ * @post Returns HealthSummaryResponse.
+ * @pre Caller has read permission for dashboard health view.
+ */
+
+// --- delete_health_report (backend/src/api/routes/health.py)
+/**!
+ * @brief Delete one persisted dashboard validation report from health summary.
+ * @post Validation record is removed; linked task/logs are cleaned when available.
+ * @pre Caller has write permission for tasks/report maintenance.
+ */
+
+// --- LlmRoutes (backend/src/api/routes/llm.py)
+/**!
+ * @brief API routes for LLM provider configuration and management.
+ */
+
+// --- FetchModelsRequest (backend/src/api/routes/llm.py)
+/**!
+ * @brief Pydantic request model for the fetch-models endpoint.
+ */
+
+// --- router (backend/src/api/routes/llm.py)
+/**!
+ * @brief APIRouter instance for LLM routes.
+ */
+
+// --- _is_valid_runtime_api_key (backend/src/api/routes/llm.py)
+/**!
+ * @brief Validate decrypted runtime API key presence/shape.
+ * @post Returns True only for non-placeholder key.
+ * @pre value can be None.
+ */
+
+// --- get_providers (backend/src/api/routes/llm.py)
+/**!
+ * @brief Retrieve all LLM provider configurations.
+ * @post Returns list of LLMProviderConfig.
+ * @pre User is authenticated.
+ */
+
+// --- fetch_models (backend/src/api/routes/llm.py)
+/**!
+ * @brief Fetch available models from an LLM provider by base_url+provider_type, or by provider_id.
+ * @post Returns a list of available model IDs.
+ * @pre User is authenticated. Either provider_id or base_url+provider_type must be provided.
+ */
+
+// --- get_llm_status (backend/src/api/routes/llm.py)
+/**!
+ * @brief Returns whether LLM runtime is configured for dashboard validation.
+ * @post configured=true only when an active provider with valid decrypted key exists.
+ * @pre User is authenticated.
+ */
+
+// --- create_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Create a new LLM provider configuration.
+ * @post Returns the created LLMProviderConfig.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- update_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Update an existing LLM provider configuration.
+ * @post Returns the updated LLMProviderConfig.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- delete_provider (backend/src/api/routes/llm.py)
+/**!
+ * @brief Delete an LLM provider configuration.
+ * @post Returns success status.
+ * @pre User is authenticated and has admin permissions.
+ */
+
+// --- test_connection (backend/src/api/routes/llm.py)
+/**!
+ * @brief Test connection to an LLM provider.
+ * @post Returns success status and message.
+ * @pre User is authenticated.
+ */
+
+// --- test_provider_config (backend/src/api/routes/llm.py)
+/**!
+ * @brief Test connection with a provided configuration (not yet saved).
+ * @post Returns success status and message.
+ * @pre User is authenticated.
+ */
+
+// --- MaintenanceRoutesPackage (backend/src/api/routes/maintenance/__init__.py)
+/**!
+ * @brief Maintenance Banner API route package.
+ */
+
+// --- MaintenanceRouter (backend/src/api/routes/maintenance/_router.py)
+/**!
+ * @brief FastAPI APIRouter for the Maintenance Banner endpoints.
+ */
+
+// --- MaintenanceRoutesModule (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Route handler stubs for all 7 Maintenance Banner API endpoints with RBAC guards per FR-015.
+ * @invariant RBAC enforced per FR-015 matrix via has_permission() dependency.
+ */
+
+// --- list_dashboard_banners (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get per-dashboard banner state for the Dashboard Hub indicator.
+ */
+
+// --- list_events (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get active and completed maintenance event lists with affected dashboard counts.
+ */
+
+// --- start_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Start a maintenance event. Validates input, creates event, dispatches TaskManager task.
+ */
+
+// --- end_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief End a specific maintenance event by ID. Removes banners from affected dashboards.
+ */
+
+// --- end_all_maintenance (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief End all active maintenance events. Removes all banners from all dashboards.
+ */
+
+// --- get_maintenance_settings (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Get current maintenance settings configuration.
+ */
+
+// --- update_maintenance_settings (backend/src/api/routes/maintenance/_routes.py)
+/**!
+ * @brief Update maintenance settings. All fields optional for partial update.
+ */
+
+// --- MaintenanceSchemasModule (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Pydantic models for Maintenance Banner API: request/response schemas per data-model.md.
+ * @invariant All response schemas use the standard envelope shape: { status, data, error, meta }
+ */
+
+// --- MaintenanceStartRequest (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief POST /api/maintenance/start request body with environment scoping.
+ */
+
+// --- MaintenanceSettingsUpdate (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief PUT /api/maintenance/settings request body — all fields optional for partial update.
+ */
+
+// --- MaintenanceStartResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for /api/maintenance/start — always 202 with task_id.
+ */
+
+// --- MaintenanceDashboardResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Describes a single dashboard affected by a maintenance operation.
+ */
+
+// --- MaintenanceFailedDashboard (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Describes a dashboard that failed during banner apply/removal.
+ */
+
+// --- MaintenanceTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed maintenance start task.
+ */
+
+// --- MaintenanceEndResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for /api/maintenance/{id}/end and /api/maintenance/end-all — always 202 with task_id.
+ */
+
+// --- MaintenanceEndTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed end maintenance task.
+ */
+
+// --- MaintenanceEndAllTaskResult (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Result payload for a completed end-all maintenance task.
+ */
+
+// --- MaintenanceSettingsResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for GET /api/maintenance/settings.
+ */
+
+// --- MaintenanceEventItem (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Single maintenance event summary for GET /api/maintenance/events.
+ */
+
+// --- MaintenanceEventListResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for GET /api/maintenance/events.
+ */
+
+// --- MaintenanceDashboardBannerState (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Per-dashboard banner state for GET /api/maintenance/dashboard-banners.
+ */
+
+// --- MaintenanceAlreadyActiveResponse (backend/src/api/routes/maintenance/_schemas.py)
+/**!
+ * @brief Response for duplicate /start call — idempotency hit.
+ */
+
+// --- MappingsApi (backend/src/api/routes/mappings.py)
+/**!
+ * @brief API endpoints for managing database mappings and getting suggestions.
+ */
+
+// --- MappingCreate (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- MappingResponse (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- SuggestRequest (backend/src/api/routes/mappings.py)
+/**!
+ */
+
+// --- get_mappings (backend/src/api/routes/mappings.py)
+/**!
+ * @brief List all saved database mappings.
+ * @post Returns filtered list of DatabaseMapping records.
+ * @pre db session is injected.
+ */
+
+// --- create_mapping (backend/src/api/routes/mappings.py)
+/**!
+ * @brief Create or update a database mapping.
+ * @post DatabaseMapping created or updated in database.
+ * @pre mapping is valid MappingCreate, db session is injected.
+ */
+
+// --- suggest_mappings_api (backend/src/api/routes/mappings.py)
+/**!
+ * @brief Get suggested mappings based on fuzzy matching.
+ * @post Returns mapping suggestions.
+ * @pre request is valid SuggestRequest, config_manager is injected.
+ */
+
+// --- MigrationApi (backend/src/api/routes/migration.py)
+/**!
+ * @brief HTTP contract layer for migration orchestration, settings, dry-run, and mapping sync endpoints.
+ * @invariant Migration endpoints never execute with invalid environment references and always return explicit HTTP errors on guard failures.
+ * @post Migration tasks are enqueued or dry-run results are computed and returned.
+ * @pre Backend core services initialized and Database session available.
+ */
+
+// --- execute_migration (backend/src/api/routes/migration.py)
+/**!
+ * @brief Validate migration selection and enqueue asynchronous migration task execution.
+ * @invariant Migration task dispatch never occurs before source and target environment ids pass guard validation.
+ * @post Returns {"task_id": str, "message": str} when task creation succeeds; emits HTTP_400/HTTP_500 on failure.
+ * @pre DashboardSelection payload is valid and both source/target environments exist.
+ */
+
+// --- dry_run_migration (backend/src/api/routes/migration.py)
+/**!
+ * @brief Build pre-flight migration diff and risk summary without mutating target systems.
+ * @invariant Dry-run flow remains read-only and rejects identical source/target environments before service execution.
+ * @post Returns deterministic dry-run payload; emits HTTP_400 for guard violations and HTTP_500 for orchestrator value errors.
+ * @pre DashboardSelection is valid, source and target environments exist, differ, and selected_ids is non-empty.
+ */
+
+// --- get_migration_settings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Read and return configured migration synchronization cron expression.
+ * @post Returns {"cron": str} reflecting current persisted settings value.
+ * @pre Configuration store is available and requester has READ permission.
+ */
+
+// --- update_migration_settings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Validate and persist migration synchronization cron expression update.
+ * @post Returns {"cron": str, "status": "updated"} and persists updated cron value.
+ * @pre Payload includes "cron" key and requester has WRITE permission.
+ */
+
+// --- get_resource_mappings (backend/src/api/routes/migration.py)
+/**!
+ * @brief Fetch synchronized resource mappings with optional filters and pagination for migration mappings view.
+ * @post Returns {"items": [...], "total": int} where items reflect applied filters and pagination.
+ * @pre skip>=0, 1<=limit<=500, DB session is active, requester has READ permission.
+ */
+
+// --- trigger_sync_now (backend/src/api/routes/migration.py)
+/**!
+ * @brief Trigger immediate ID synchronization for every configured environment.
+ * @post Returns sync summary with synced/failed counts after attempting all environments.
+ * @pre At least one environment is configured and requester has EXECUTE permission.
+ */
+
+// --- PluginsRouter (backend/src/api/routes/plugins.py)
+/**!
+ * @brief Defines the FastAPI router for plugin-related endpoints, allowing clients to list available plugins.
+ */
+
+// --- list_plugins (backend/src/api/routes/plugins.py)
+/**!
+ * @brief Retrieve a list of all available plugins.
+ * @post Returns a list of PluginConfig objects.
+ * @pre plugin_loader is injected via Depends.
+ */
+
+// --- ProfileApiModule (backend/src/api/routes/profile.py)
+/**!
+ * @brief Exposes self-scoped profile preference endpoints and environment-based Superset account lookup.
+ * @invariant Endpoints are self-scoped and never mutate another user preference.
+ * @post Profile endpoints registered
+ * @pre Auth middleware configured, database session available
+ */
+
+// --- _get_profile_service (backend/src/api/routes/profile.py)
+/**!
+ * @brief Build profile service for current request scope.
+ * @post Returns a ready ProfileService instance.
+ * @pre db session and config manager are available.
+ */
+
+// --- get_preferences (backend/src/api/routes/profile.py)
+/**!
+ * @brief Get authenticated user's dashboard filter preference.
+ * @post Returns preference payload for current user only.
+ * @pre Valid JWT and authenticated user context.
+ */
+
+// --- update_preferences (backend/src/api/routes/profile.py)
+/**!
+ * @brief Update authenticated user's dashboard filter preference.
+ * @post Persists normalized preference for current user or raises validation/authorization errors.
+ * @pre Valid JWT and valid request payload.
+ */
+
+// --- lookup_superset_accounts (backend/src/api/routes/profile.py)
+/**!
+ * @brief Lookup Superset account candidates in selected environment.
+ * @post Returns success or degraded lookup payload with stable shape.
+ * @pre Valid JWT, authenticated context, and environment_id query parameter.
+ */
+
+// --- ReportsRouter (backend/src/api/routes/reports.py)
+/**!
+ * @brief FastAPI router for unified task report list and detail retrieval endpoints.
+ * @invariant Endpoints are read-only and do not trigger long-running tasks.
+ * @post Router is configured and endpoints are ready for registration.
+ * @pre Reports service and dependencies are initialized.
+ */
+
+// --- _parse_csv_enum_list (backend/src/api/routes/reports.py)
+/**!
+ * @brief Parse comma-separated query value into enum list.
+ * @post Returns enum list or raises HTTP 400 with deterministic machine-readable payload.
+ * @pre raw may be None/empty or comma-separated values.
+ */
+
+// --- list_reports (backend/src/api/routes/reports.py)
+/**!
+ * @brief Return paginated unified reports list.
+ * @post deterministic error payload for invalid filters.
+ * @pre authenticated/authorized request and validated query params.
+ */
+
+// --- get_report_detail (backend/src/api/routes/reports.py)
+/**!
+ * @brief Return one normalized report detail with diagnostics and next actions.
+ * @post returns normalized detail envelope or 404 when report is not found.
+ * @pre authenticated/authorized request and existing report_id.
+ */
+
+// --- SettingsRouter (backend/src/api/routes/settings.py)
+/**!
+ * @brief Provides API endpoints for managing application settings and Superset environments.
+ * @invariant All settings changes must be persisted via ConfigManager.
+ * @post Settings are read or written via ConfigManager.
+ * @pre ConfigManager is initialized and accessible.
+ */
+
+// --- LoggingConfigResponse (backend/src/api/routes/settings.py)
+/**!
+ * @brief Response model for logging configuration with current task log level.
+ */
+
+// --- _validate_superset_connection_fast (backend/src/api/routes/settings.py)
+/**!
+ * @brief Run lightweight Superset connectivity validation without full pagination scan.
+ * @post Raises on auth/API failures; returns None on success.
+ * @pre env contains valid URL and credentials.
+ */
+
+// --- get_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves all application settings.
+ * @post Returns masked AppConfig.
+ * @pre Config manager is available.
+ */
+
+// --- get_features (backend/src/api/routes/settings.py)
+/**!
+ * @brief Public endpoint returning feature flags for frontend sidebar filtering.
+ * @post Returns dict with dataset_review and health_monitor booleans.
+ * @pre Config manager is available.
+ */
+
+// --- get_storage_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves storage-specific settings.
+ */
+
+// --- update_storage_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates storage-specific settings.
+ * @post Storage settings are updated and saved.
+ */
+
+// --- test_environment_connection (backend/src/api/routes/settings.py)
+/**!
+ * @brief Tests the connection to a Superset environment.
+ * @post Returns success or error status.
+ * @pre ID is provided.
+ */
+
+// --- get_logging_config (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves current logging configuration.
+ * @post Returns logging configuration.
+ * @pre Config manager is available.
+ */
+
+// --- update_logging_config (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates logging configuration.
+ * @post Logging configuration is updated and saved.
+ * @pre New logging config is provided.
+ */
+
+// --- ConsolidatedSettingsResponse (backend/src/api/routes/settings.py)
+/**!
+ * @brief Response model for consolidated application settings.
+ */
+
+// --- get_consolidated_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Retrieves all settings categories in a single call.
+ * @post Returns consolidated settings, provider metadata, and persisted notification payload in one stable response.
+ * @pre Config manager is available and the caller holds admin settings read permission.
+ */
+
+// --- update_consolidated_settings (backend/src/api/routes/settings.py)
+/**!
+ * @brief Bulk update application settings from the consolidated view.
+ * @post Settings are updated and saved via ConfigManager.
+ * @pre User has admin permissions, config is valid.
+ */
+
+// --- get_validation_policies (backend/src/api/routes/settings.py)
+/**!
+ * @brief Lists all validation policies.
+ */
+
+// --- create_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Creates a new validation policy.
+ */
+
+// --- update_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Updates an existing validation policy.
+ */
+
+// --- delete_validation_policy (backend/src/api/routes/settings.py)
+/**!
+ * @brief Deletes a validation policy.
+ */
+
+// --- get_translation_schedules (backend/src/api/routes/settings.py)
+/**!
+ * @brief Lists all translation schedules joined with translation job names.
+ */
+
+// --- storage_routes (backend/src/api/routes/storage.py)
+/**!
+ * @brief API endpoints for file storage management (backups and repositories).
+ * @invariant All paths must be validated against path traversal.
+ */
+
+// --- list_files (backend/src/api/routes/storage.py)
+/**!
+ * @brief List all files and directories in the storage system.
+ * @post Returns a list of StoredFile objects.
+ * @pre None.
+ */
+
+// --- delete_file (backend/src/api/routes/storage.py)
+/**!
+ * @brief Delete a specific file or directory.
+ * @post Item is removed from storage.
+ * @pre category must be a valid FileCategory.
+ */
+
+// --- download_file (backend/src/api/routes/storage.py)
+/**!
+ * @brief Retrieve a file for download.
+ * @post Returns a FileResponse.
+ * @pre category must be a valid FileCategory.
+ */
+
+// --- get_file_by_path (backend/src/api/routes/storage.py)
+/**!
+ * @brief Retrieve a file by validated absolute/relative path under storage root.
+ * @post Returns a FileResponse for existing files.
+ * @pre path must resolve under configured storage root.
+ */
+
+// --- TasksRouter (backend/src/api/routes/tasks.py)
+/**!
+ * @brief Defines the FastAPI router for task-related endpoints, allowing clients to create, list, and get the status of tasks.
+ */
+
+// --- resume_task (backend/src/api/routes/tasks.py)
+/**!
+ * @brief Resume a task that is awaiting input (e.g., passwords).
+ * @post Task resumes execution with provided input.
+ * @pre task must be in AWAITING_INPUT status.
+ */
+
+// --- TranslateRoutes (backend/src/api/routes/translate/__init__.py)
+/**!
+ * @brief API routes for LLM-based SQL/dashboard translation management including terminology dictionary CRUD and import.
+ * @post Translation job, run, dictionary, correction, preview, and schedule CRUD operations are executed.
+ * @pre API server is running, user is authenticated, database is accessible.
+ */
+
+// --- TranslateCorrectionRoutesModule (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Term correction submission endpoints.
+ */
+
+// --- submit_correction (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Submit a term correction from a run result review.
+ * @post Correction applied with conflict detection.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- submit_bulk_corrections (backend/src/api/routes/translate/_correction_routes.py)
+/**!
+ * @brief Submit multiple term corrections atomically.
+ * @post All corrections applied or none with conflict list.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- TranslateDictionaryRoutesModule (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Terminology Dictionary CRUD, entries management, and import routes.
+ */
+
+// --- list_dictionaries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief List all terminology dictionaries.
+ * @post Returns list of dictionaries with total count.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- get_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Get a single terminology dictionary by ID.
+ * @post Returns the dictionary with entry_count.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- create_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Create a new terminology dictionary.
+ * @post Returns the created dictionary.
+ * @pre User has translate.dictionary.create permission.
+ */
+
+// --- update_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Update an existing terminology dictionary.
+ * @post Returns the updated dictionary.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- delete_dictionary (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Delete a terminology dictionary, blocked if attached to active/scheduled jobs.
+ * @post Dictionary is deleted.
+ * @pre User has translate.dictionary.delete permission.
+ */
+
+// --- list_dictionary_entries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief List entries for a dictionary, optionally filtered by language pair.
+ * @post Returns paginated list of entries with language pair fields.
+ * @pre User has translate.dictionary.view permission.
+ */
+
+// --- add_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Add a new entry to a dictionary.
+ * @post Entry is created.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- edit_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Update an existing dictionary entry.
+ * @post Entry is updated.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- delete_dictionary_entry (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Delete a dictionary entry.
+ * @post Entry is deleted.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- import_dictionary_entries (backend/src/api/routes/translate/_dictionary_routes.py)
+/**!
+ * @brief Import entries into a terminology dictionary from CSV/TSV content.
+ * @post Entries are imported per conflict mode.
+ * @pre User has translate.dictionary.edit permission.
+ */
+
+// --- TranslateHelpersModule (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Shared helper functions for translate route handlers.
+ */
+
+// --- _run_to_response (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Convert TranslationRun ORM to response dict.
+ */
+
+// --- _dict_to_response (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Convert a TerminologyDictionary ORM model to a response dict with computed entry_count.
+ */
+
+// --- _get_dictionary_entry_counts (backend/src/api/routes/translate/_helpers.py)
+/**!
+ * @brief Get entry counts for a list of dictionary IDs.
+ */
+
+// --- TranslateJobRoutesModule (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Translation Job CRUD and datasource column routes.
+ */
+
+// --- list_jobs (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief List all translation jobs.
+ * @post Returns list of translation jobs.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- get_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Get a single translation job by ID.
+ * @post Returns the translation job.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- create_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Create a new translation job.
+ * @post Returns the created translation job.
+ * @pre User has translate.job.create permission.
+ */
+
+// --- update_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Update an existing translation job.
+ * @post Returns the updated translation job.
+ * @pre User has translate.job.edit permission.
+ */
+
+// --- delete_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Delete a translation job.
+ * @post Job is deleted.
+ * @pre User has translate.job.delete permission.
+ */
+
+// --- duplicate_job (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Duplicate a translation job.
+ * @post Returns the duplicated job with status DRAFT.
+ * @pre User has translate.job.create permission.
+ */
+
+// --- get_datasource_columns (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Get column metadata and database dialect for a Superset datasource.
+ * @post Returns column list with metadata and database_dialect.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- check_target_schema (backend/src/api/routes/translate/_job_routes.py)
+/**!
+ * @brief Проверяет схему целевой таблицы: какие колонки ожидаются, какие есть, каких не хватает.
+ */
+
+// --- TranslateMetricsRoutesModule (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Translation Metrics endpoints.
+ */
+
+// --- get_metrics (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Get translation metrics, optionally filtered by job.
+ * @post Returns metrics data.
+ * @pre User has translate.metrics.view permission.
+ */
+
+// --- get_job_metrics (backend/src/api/routes/translate/_metrics_routes.py)
+/**!
+ * @brief Get aggregated metrics for a specific job.
+ * @post Returns metrics dict.
+ * @pre User has translate.metrics.view permission.
+ */
+
+// --- TranslatePreviewRoutesModule (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Translation Preview session management routes.
+ */
+
+// --- preview_translation (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Preview a translation before applying it.
+ * @post Returns a preview session with records and cost estimation.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- update_preview_row (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Approve, edit, or reject a preview row (optionally per language).
+ * @post Preview row status is updated.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- accept_preview_session (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Accept a preview session, marking it as the quality gate for full execution.
+ * @post Preview session is marked as APPLIED; full execution can proceed.
+ * @pre User has translate.job.execute permission. Job has an ACTIVE preview session.
+ */
+
+// --- apply_preview (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Apply a preview session (alias for accept when accepting at session level).
+ * @post Preview is applied.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- get_preview_records (backend/src/api/routes/translate/_preview_routes.py)
+/**!
+ * @brief Get records for a preview session.
+ * @post Returns list of preview records.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- TranslateRouterModule (backend/src/api/routes/translate/_router.py)
+/**!
+ * @brief APIRouter instance for translate routes.
+ */
+
+// --- translate_router (backend/src/api/routes/translate/_router.py)
+/**!
+ * @brief APIRouter instance for all translate sub-routes.
+ */
+
+// --- TranslateRunListRoutesModule (backend/src/api/routes/translate/_run_list_routes.py)
+/**!
+ * @brief Translation Run listing, detail, and CSV download routes (cross-job).
+ */
+
+// --- download_skipped_csv (backend/src/api/routes/translate/_run_list_routes.py)
+/**!
+ * @brief Download a CSV of skipped translation records from a run.
+ * @post Returns CSV file of skipped records.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- TranslateRunRoutesModule (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Translation Run execution, history, status, records and batches routes.
+ */
+
+// --- run_translation (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Execute a translation job (trigger a run).
+ * @post Returns the created translation run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- retry_run (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Retry failed batches in a translation run.
+ * @post Returns the updated translation run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- retry_insert (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Retry the SQL insert phase for a completed run.
+ * @post Returns the updated run.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- cancel_run (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Cancel a running translation.
+ * @post Run is cancelled.
+ * @pre User has translate.job.execute permission.
+ */
+
+// --- get_run_history (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get run history for a translation job.
+ * @post Returns list of runs.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_run_status (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get status and statistics for a translation run.
+ * @post Returns run details with statistics.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_run_records (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get paginated records for a translation run.
+ * @post Returns paginated records.
+ * @pre User has translate.history.view permission.
+ */
+
+// --- get_batches (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Get batches for a translation run.
+ * @post Returns list of batches.
+ * @pre User has translate.job.view permission.
+ */
+
+// --- override_detected_language (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Manually override the detected source language for a specific translation language entry.
+ * @post TranslationLanguage.source_language_detected is updated; language_overridden is set to True.
+ * @pre User has translate.job.execute permission. Run, record, and language entry exist.
+ */
+
+// --- inline_edit_translation (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Apply an inline correction to a translated value on a completed run result.
+ * @post TranslationLanguage.final_value and user_edit are updated. Optional dictionary submission.
+ * @pre User has translate.job.execute permission. Run, record, and language entry exist.
+ */
+
+// --- bulk_find_replace (backend/src/api/routes/translate/_run_routes.py)
+/**!
+ * @brief Perform bulk find-and-replace on translated values within a run.
+ * @post If preview=false, matching translations are updated. Optional dictionary submission.
+ * @pre User has translate.job.execute permission. Run exists.
+ */
+
+// --- TranslateScheduleRoutesModule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Translation Schedule management routes.
+ */
+
+// --- get_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Get the schedule for a translation job.
+ * @post Returns the schedule configuration.
+ * @pre User has translate.schedule.view permission.
+ */
+
+// --- set_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Set or update the schedule for a translation job.
+ * @post Schedule is created or updated.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- enable_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Enable a schedule for a translation job.
+ * @post Schedule is enabled.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- disable_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Disable a schedule for a translation job.
+ * @post Schedule is disabled.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- delete_schedule (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Delete the schedule for a translation job.
+ * @post Schedule is removed.
+ * @pre User has translate.schedule.manage permission.
+ */
+
+// --- get_next_executions (backend/src/api/routes/translate/_schedule_routes.py)
+/**!
+ * @brief Preview next N executions for a job's schedule.
+ * @post Returns next execution times.
+ * @pre User has translate.schedule.view permission.
+ */
+
+// --- ValidationRoutes (backend/src/api/routes/validation.py)
+/**!
+ * @brief API routes for validation task management and run history.
+ */
+
+// --- _get_task_service (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- _get_run_service (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- list_tasks (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- update_task (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- delete_task (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- trigger_run (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- list_runs (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- get_run_detail (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- delete_run (backend/src/api/routes/validation.py)
+/**!
+ */
+
+// --- ValidationApiTests (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Unit tests for validation task CRUD and run history API endpoints.
+ * @invariant provider_id must reference a multimodal LLM provider for creation
+ */
+
+// --- test_list_tasks_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/tasks returns paginated task list with filters.
+ */
+
+// --- test_list_tasks_pagination (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Pagination query params are validated: page >= 1, page_size 1-100.
+ */
+
+// --- test_list_tasks_service_error (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Service ValueError becomes 400 on list_tasks.
+ */
+
+// --- test_create_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST /validation/tasks with valid payload returns 201.
+ */
+
+// --- test_create_task_missing_fields (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST with missing required fields returns 422.
+ */
+
+// --- test_create_task_invalid_provider (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST with non-multimodal provider returns 422.
+ */
+
+// --- test_get_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/tasks/{id} returns task with recent_runs.
+ */
+
+// --- test_get_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET for nonexistent task returns 404.
+ */
+
+// --- test_update_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief PUT /validation/tasks/{id} updates task and returns updated object.
+ */
+
+// --- test_update_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief PUT for nonexistent task returns 404.
+ */
+
+// --- test_delete_task_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE /validation/tasks/{id} returns 204.
+ */
+
+// --- test_delete_task_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE for nonexistent task returns 404.
+ */
+
+// --- test_delete_task_with_runs_flag (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE with delete_runs=true passes query param to service.
+ */
+
+// --- test_trigger_run_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST /validation/tasks/{id}/run spawns a validation task.
+ */
+
+// --- test_trigger_run_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief POST for nonexistent task returns 422.
+ */
+
+// --- test_trigger_run_no_dashboards (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Trigger fails with 422 when task has no dashboard IDs.
+ */
+
+// --- test_list_runs_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/runs returns paginated run list.
+ */
+
+// --- test_list_runs_filters (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief All 6 filter query params are accepted and forwarded to service.
+ */
+
+// --- test_list_runs_pagination (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Pagination boundary checks on runs list.
+ */
+
+// --- test_list_runs_invalid_status (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Status is a free string; any value passes through to service.
+ */
+
+// --- test_get_run_detail_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET /validation/runs/{id} returns full detail with issues and raw_response.
+ */
+
+// --- test_get_run_detail_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief GET for nonexistent run returns 404.
+ */
+
+// --- test_delete_run_success (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE /validation/runs/{id} returns 204.
+ */
+
+// --- test_delete_run_not_found (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief DELETE for nonexistent run returns 404.
+ */
+
+// --- test_endpoints_require_authentication (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Without current_user dependency, all 9 endpoints return 401.
+ */
+
+// --- test_permission_denied_non_admin (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief A non-admin user without validation.* permissions receives 403.
+ */
+
+// --- test_permission_denied_all_actions (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief Each action (VIEW, CREATE, EDIT, DELETE, EXECUTE) denied for non-admin.
+ */
+
+// --- test_delete_task_runs_default_false (backend/src/api/routes/validation/__tests__/test_validation_api.py)
+/**!
+ * @brief delete_runs query param defaults to False.
+ */
+
+// --- AppModule (backend/src/app.py)
+/**!
+ * @brief The main entry point for the FastAPI application.
+ * @invariant All WebSocket connections must be properly cleaned up on disconnect.
+ * @post FastAPI app instance is created, middleware configured, and routes registered.
+ * @pre Python environment and dependencies installed; configuration database available.
+ */
+
+// --- FastAPI_App (backend/src/app.py)
+/**!
+ * @brief Canonical FastAPI application instance for route, middleware, and websocket registration.
+ */
+
+// --- ensure_initial_admin_user (backend/src/app.py)
+/**!
+ * @brief Ensures initial admin user exists when bootstrap env flags are enabled.
+ */
+
+// --- startup_event (backend/src/app.py)
+/**!
+ * @brief Handles application startup tasks, such as starting the scheduler.
+ * @post Scheduler is started.
+ * @pre None.
+ */
+
+// --- shutdown_event (backend/src/app.py)
+/**!
+ * @brief Handles application shutdown tasks, such as stopping the scheduler.
+ * @post Scheduler is stopped.
+ * @pre None.
+ */
+
+// --- app_middleware (backend/src/app.py)
+/**!
+ * @brief Configure application-wide middleware (Session, CORS).
+ */
+
+// --- network_error_handler (backend/src/app.py)
+/**!
+ * @brief Global exception handler for NetworkError.
+ * @post Returns 503 HTTP Exception.
+ * @pre request is a FastAPI Request object.
+ */
+
+// --- log_requests (backend/src/app.py)
+/**!
+ * @brief Middleware to log incoming HTTP requests and their response status.
+ * @post Logs request and response details.
+ * @pre request is a FastAPI Request object.
+ */
+
+// --- API_Routes (backend/src/app.py)
+/**!
+ * @brief Register all FastAPI route groups exposed by the application entrypoint.
+ */
+
+// --- api.include_routers (backend/src/app.py)
+/**!
+ * @brief Registers all API routers with the FastAPI application.
+ */
+
+// --- websocket_endpoint (backend/src/app.py)
+/**!
+ * @brief Provides a WebSocket endpoint for real-time log streaming of a task with server-side filtering.
+ * @invariant Every accepted WebSocket subscription is unsubscribed exactly once even when streaming fails or the client disconnects.
+ * @post WebSocket connection is managed and logs are streamed until disconnect.
+ * @pre task_id must be a valid task ID.
+ */
+
+// --- dataset_websocket_endpoint (backend/src/app.py)
+/**!
+ * @brief WebSocket endpoint for dataset.updated events — auto-refresh on task completion.
+ * @post WebSocket streams dataset.updated events until disconnect.
+ * @pre env_id must reference a known environment.
+ */
+
+// --- StaticFiles (backend/src/app.py)
+/**!
+ * @brief Mounts the frontend build directory to serve static assets.
+ */
+
+// --- serve_spa (backend/src/app.py)
+/**!
+ * @brief Serves the SPA frontend for any path not matched by API routes.
+ * @post Returns the requested file or index.html.
+ * @pre frontend_path exists.
+ */
+
+// --- read_root (backend/src/app.py)
+/**!
+ * @brief A simple root endpoint to confirm that the API is running when frontend is missing.
+ * @post Returns a JSON message indicating API status.
+ * @pre None.
+ */
+
+// --- src.core (backend/src/core/__init__.py)
+/**!
+ * @brief Backend core services and infrastructure package root.
+ */
+
+// --- TestConfigManagerCompat (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Verifies ConfigManager compatibility wrappers preserve legacy payload sections.
+ */
+
+// --- test_get_payload_preserves_legacy_sections (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure get_payload merges typed config into raw payload without dropping legacy sections.
+ */
+
+// --- test_save_config_accepts_raw_payload_and_keeps_extras (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure save_config accepts raw dict payload, refreshes typed config, and preserves extra sections.
+ */
+
+// --- test_save_config_syncs_environment_records_for_fk_backed_flows (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure saving config mirrors typed environments into relational records required by FK-backed session persistence.
+ */
+
+// --- _FakeQuery (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal query stub returning hardcoded existing environment record list for sync tests.
+ * @invariant all() always returns [existing_record]; no parameterization or filtering.
+ */
+
+// --- _FakeSession (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal SQLAlchemy session stub that captures add/delete calls for environment sync assertions.
+ * @invariant query() always returns _FakeQuery; no real DB interaction.
+ */
+
+// --- test_save_config_syncs_deletions_to_persistence (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure stale environment records are deleted during save (in _delete_stale_environment_records)
+ */
+
+// --- _FakeQueryDel (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal query stub for deletion test.
+ */
+
+// --- _FakeSessionDel (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Minimal session stub that captures add/delete for deletion assertions.
+ */
+
+// --- test_load_config_syncs_environment_records_from_existing_db_payload (backend/src/core/__tests__/test_config_manager_compat.py)
+/**!
+ * @brief Ensure loading an existing DB-backed config also mirrors environment rows required by FK-backed runtime flows.
+ */
+
+// --- NativeFilterExtractionTests (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Verify native filter extraction from permalinks and native_filters_key URLs.
+ */
+
+// --- test_extract_native_filters_from_permalink (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Extract native filters from a permalink key.
+ */
+
+// --- test_extract_native_filters_from_permalink_direct_response (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle permalink response without result wrapper.
+ */
+
+// --- test_extract_native_filters_from_key (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Extract native filters from a native_filters_key.
+ */
+
+// --- test_extract_native_filters_from_key_single_filter (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle single filter format in native filter state.
+ */
+
+// --- test_extract_native_filters_from_key_dict_value (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Handle filter state value as dict instead of JSON string.
+ */
+
+// --- test_parse_dashboard_url_for_filters_permalink (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse permalink URL format.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters_key URL format with numeric dashboard ID.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key_slug (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters_key URL format when dashboard reference is a slug, not a numeric ID.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_key_slug_resolution_fails (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Gracefully handle slug resolution failure for native_filters_key URL.
+ */
+
+// --- test_parse_dashboard_url_for_filters_native_filters_direct (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Parse native_filters direct query param.
+ */
+
+// --- test_parse_dashboard_url_for_filters_no_filters (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Return empty result when no filters present.
+ */
+
+// --- test_extra_form_data_merge (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ExtraFormDataMerge correctly merges dictionaries.
+ */
+
+// --- test_filter_state_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test FilterState Pydantic model.
+ */
+
+// --- test_parsed_native_filters_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ParsedNativeFilters Pydantic model.
+ */
+
+// --- test_parsed_native_filters_empty (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test ParsedNativeFilters with no filters.
+ */
+
+// --- test_native_filter_data_mask_model (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Test NativeFilterDataMask model.
+ */
+
+// --- test_recover_imported_filters_reconciles_raw_native_filter_ids_to_metadata_names (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Reconcile raw native filter ids from state to canonical metadata filter names.
+ */
+
+// --- test_recover_imported_filters_collapses_state_and_metadata_duplicates_into_one_canonical_filter (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Collapse raw-id state entries and metadata entries into one canonical filter.
+ */
+
+// --- test_recover_imported_filters_preserves_unmatched_raw_native_filter_ids (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Preserve unmatched raw native filter ids as fallback diagnostics when metadata mapping is unavailable.
+ */
+
+// --- test_extract_imported_filters_preserves_clause_level_native_filter_payload_for_preview (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Recovered native filter state should preserve exact Superset clause payload and time extras for preview compilation.
+ */
+
+// --- test_sanitize_imported_filter_for_assistant_masks_sensitive_raw_values (backend/src/core/__tests__/test_native_filters.py)
+/**!
+ * @brief Assistant-facing imported-filter payload should redact likely PII while preserving structure metadata.
+ */
+
+// --- SupersetPreviewPipelineTests (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Verify explicit chart-data preview compilation and ensure non-dashboard 404 errors remain generic across sync and async clients.
+ */
+
+// --- _make_environment (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- _make_requests_http_error (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- _make_httpx_status_error (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ */
+
+// --- test_compile_dataset_preview_prefers_legacy_explore_form_data_strategy (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Superset preview compilation should prefer the legacy form_data transport inferred from browser traffic before falling back to chart-data.
+ */
+
+// --- test_compile_dataset_preview_falls_back_to_chart_data_after_legacy_failures (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Superset preview compilation should fall back to chart-data when legacy form_data strategies are rejected.
+ */
+
+// --- test_build_dataset_preview_query_context_places_recovered_filters_in_chart_style_form_data (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should mirror chart-style filter transport so recovered native filters reach Superset compilation.
+ */
+
+// --- test_build_dataset_preview_query_context_merges_dataset_template_params_and_preserves_user_values (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should merge dataset template params for parity with real dataset definitions while preserving explicit session overrides.
+ */
+
+// --- test_build_dataset_preview_query_context_preserves_time_range_from_native_filter_payload (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Preview query context should preserve time-range native filter extras even when dataset defaults differ.
+ */
+
+// --- test_build_dataset_preview_legacy_form_data_preserves_native_filter_clauses (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Legacy preview form_data should preserve recovered native filter clauses in browser-style fields without duplicating datasource for QueryObjectFactory.
+ */
+
+// --- test_sync_network_404_mapping_keeps_non_dashboard_endpoints_generic (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Sync network client should reserve dashboard-not-found translation for dashboard endpoints only.
+ */
+
+// --- test_sync_network_404_mapping_translates_dashboard_endpoints (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Sync network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+ */
+
+// --- test_async_network_404_mapping_keeps_non_dashboard_endpoints_generic (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Async network client should reserve dashboard-not-found translation for dashboard endpoints only.
+ */
+
+// --- test_async_network_404_mapping_translates_dashboard_endpoints (backend/src/core/__tests__/test_superset_preview_pipeline.py)
+/**!
+ * @brief Async network client should still translate dashboard endpoint 404 responses into dashboard-not-found errors.
+ */
+
+// --- TestSupersetProfileLookup (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Verifies Superset profile lookup adapter payload normalization and fallback error precedence.
+ */
+
+// --- _RecordingNetworkClient (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Records request payloads and returns scripted responses for deterministic adapter tests.
+ * @invariant Each request consumes one scripted response in call order and persists call metadata.
+ */
+
+// --- test_get_users_page_sends_lowercase_order_direction (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Ensures adapter sends lowercase order_direction compatible with Superset rison schema.
+ * @post First request query payload contains order_direction='asc' for asc sort.
+ * @pre Adapter is initialized with recording network client.
+ */
+
+// --- test_get_users_page_preserves_primary_schema_error_over_fallback_auth_error (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Ensures fallback auth error does not mask primary schema/query failure.
+ * @post Raised exception remains primary SupersetAPIError (non-auth) to preserve root cause.
+ * @pre Primary endpoint fails with SupersetAPIError and fallback fails with AuthenticationError.
+ */
+
+// --- test_get_users_page_uses_fallback_endpoint_when_primary_fails (backend/src/core/__tests__/test_superset_profile_lookup.py)
+/**!
+ * @brief Verifies adapter retries second users endpoint and succeeds when fallback is healthy.
+ * @post Result status is success and both endpoints were attempted in order.
+ * @pre Primary endpoint fails; fallback returns valid users payload.
+ */
+
+// --- test_throttled_scheduler (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Unit tests for ThrottledSchedulerConfigurator distribution logic.
+ */
+
+// --- test_calculate_schedule_even_distribution (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate even spacing across a two-hour scheduling window for three tasks.
+ */
+
+// --- test_calculate_schedule_midnight_crossing (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate scheduler correctly rolls timestamps into the next day across midnight.
+ */
+
+// --- test_calculate_schedule_single_task (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate single-task schedule returns only the window start timestamp.
+ */
+
+// --- test_calculate_schedule_empty_list (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate empty dashboard list produces an empty schedule.
+ */
+
+// --- test_calculate_schedule_zero_window (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate zero-length window schedules all tasks at identical start timestamp.
+ */
+
+// --- test_calculate_schedule_very_small_window (backend/src/core/__tests__/test_throttled_scheduler.py)
+/**!
+ * @brief Validate sub-second interpolation when task count exceeds near-zero window granularity.
+ */
+
+// --- AsyncSupersetClientModule (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+ */
+
+// --- AsyncSupersetClient (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Async sibling of SupersetClient for dashboard read paths.
+ */
+
+// --- AsyncSupersetClientInit (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Initialize async Superset client with AsyncAPIClient transport.
+ * @post Client uses async network transport and inherited projection helpers.
+ * @pre env is valid Environment instance.
+ */
+
+// --- AsyncSupersetClientClose (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Close async transport resources.
+ * @post Underlying AsyncAPIClient is closed.
+ */
+
+// --- get_dashboards_page_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one dashboards page asynchronously.
+ * @post Returns total count and page result list.
+ */
+
+// --- get_dashboard_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one dashboard payload asynchronously.
+ * @post Returns raw dashboard payload from Superset API.
+ */
+
+// --- get_chart_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch one chart payload asynchronously.
+ * @post Returns raw chart payload from Superset API.
+ */
+
+// --- get_dashboard_detail_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch dashboard detail asynchronously with concurrent charts/datasets requests.
+ * @post Returns dashboard detail payload for overview page.
+ */
+
+// --- get_dashboard_permalink_state_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch stored dashboard permalink state asynchronously.
+ * @post Returns dashboard permalink state payload from Superset API.
+ */
+
+// --- get_native_filter_state_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Fetch stored native filter state asynchronously.
+ * @post Returns native filter state payload from Superset API.
+ */
+
+// --- extract_native_filters_from_permalink_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Extract native filters dataMask from a permalink key asynchronously.
+ * @post Returns extracted dataMask with filter states.
+ */
+
+// --- extract_native_filters_from_key_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Extract native filters from a native_filters_key URL parameter asynchronously.
+ * @post Returns extracted filter state with extraFormData.
+ */
+
+// --- parse_dashboard_url_for_filters_async (backend/src/core/async_superset_client.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state asynchronously.
+ * @post Returns extracted filter state or empty dict if no filters found.
+ */
+
+// --- AuthPackage (backend/src/core/auth/__init__.py)
+/**!
+ * @brief Authentication and authorization package root.
+ */
+
+// --- test_auth (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Unit tests for authentication module
+ */
+
+// --- test_create_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies that a persisted user can be retrieved with intact credential hash.
+ */
+
+// --- test_authenticate_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Validates authentication outcomes for valid, wrong-password, and unknown-user cases.
+ */
+
+// --- test_create_session (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Ensures session creation returns bearer token payload fields.
+ */
+
+// --- test_role_permission_association (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Confirms role-permission many-to-many assignments persist and reload correctly.
+ */
+
+// --- test_user_role_association (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Confirms user-role assignment persists and is queryable from repository reads.
+ */
+
+// --- test_ad_group_mapping (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies AD group mapping rows persist and reference the expected role.
+ */
+
+// --- test_authenticate_user_updates_last_login (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies successful authentication updates last_login audit field.
+ */
+
+// --- test_authenticate_inactive_user (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies inactive accounts are rejected during password authentication.
+ */
+
+// --- test_verify_password_empty_hash (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies password verification safely rejects empty or null password hashes.
+ */
+
+// --- test_provision_adfs_user_new (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies JIT provisioning creates a new ADFS user and maps group-derived roles.
+ */
+
+// --- test_provision_adfs_user_existing (backend/src/core/auth/__tests__/test_auth.py)
+/**!
+ * @brief Verifies JIT provisioning reuses existing ADFS user and refreshes role assignments.
+ */
+
+// --- APIKeyUtilities (backend/src/core/auth/api_key.py)
+/**!
+ * @brief API key generation and hashing utilities for service-to-service authentication.
+ * @invariant hash_api_key() produces SHA-256 hex digest for lookup and storage.
+ */
+
+// --- generate_api_key (backend/src/core/auth/api_key.py)
+/**!
+ * @brief Generate a new API key in ssk_ format with SHA-256 hash.
+ * @post Returns (raw_key, prefix, key_hash) — raw_key shown ONCE to caller, never stored.
+ */
+
+// --- hash_api_key (backend/src/core/auth/api_key.py)
+/**!
+ * @brief Hash an API key string to SHA-256 hex digest for lookup.
+ * @post Returns 64-character hex digest.
+ * @pre raw_key is a non-empty string.
+ */
+
+// --- AuthConfigModule (backend/src/core/auth/config.py)
+/**!
+ * @brief Centralized configuration for authentication and authorization.
+ * @invariant All sensitive configuration must be loaded from environment; no hardcoded secrets.
+ */
+
+// --- AuthConfig (backend/src/core/auth/config.py)
+/**!
+ * @brief Holds authentication-related settings.
+ * @post Returns a configuration object with validated settings.
+ * @pre Environment variables may be provided via .env file.
+ */
+
+// --- auth_config (backend/src/core/auth/config.py)
+/**!
+ * @brief Singleton instance of AuthConfig.
+ */
+
+// --- AuthJwtModule (backend/src/core/auth/jwt.py)
+/**!
+ * @brief JWT token generation and validation logic.
+ * @invariant Tokens must include expiration time and user identifier.
+ * @post Token encode/decode functions exported
+ * @pre JWT secret configured in environment
+ */
+
+// --- create_access_token (backend/src/core/auth/jwt.py)
+/**!
+ * @brief Generates a new JWT access token.
+ * @post Returns a signed JWT string.
+ * @pre data dict contains 'sub' (user_id) and optional 'scopes' (roles).
+ */
+
+// --- decode_token (backend/src/core/auth/jwt.py)
+/**!
+ * @brief Decodes and validates a JWT token.
+ * @post Returns the decoded payload if valid.
+ * @pre token is a signed JWT string.
+ */
+
+// --- AuthLoggerModule (backend/src/core/auth/logger.py)
+/**!
+ * @brief Structured auth logging module for audit trail generation.
+ * @invariant Must not log sensitive data like passwords or full tokens.
+ * @post Audit logging functions exported
+ * @pre Auth module initialized
+ */
+
+// --- log_security_event (backend/src/core/auth/logger.py)
+/**!
+ * @brief Logs a security-related event for audit trails.
+ * @post Security event is written to the application log.
+ * @pre event_type and username are strings.
+ */
+
+// --- AuthOauthModule (backend/src/core/auth/oauth.py)
+/**!
+ * @brief ADFS OIDC configuration and client using Authlib.
+ * @invariant Must use secure OIDC flows.
+ */
+
+// --- oauth (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Global Authlib OAuth registry.
+ */
+
+// --- register_adfs (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Registers the ADFS OIDC client.
+ * @post ADFS client is registered in oauth registry.
+ * @pre ADFS configuration is provided in auth_config.
+ */
+
+// --- is_adfs_configured (backend/src/core/auth/oauth.py)
+/**!
+ * @brief Checks if ADFS is properly configured.
+ * @post Returns True if ADFS client is registered, False otherwise.
+ * @pre None.
+ */
+
+// --- AuthRepositoryModule (backend/src/core/auth/repository.py)
+/**!
+ * @brief Data access layer for authentication and user preference entities.
+ * @invariant All database read/write operations must execute via the injected SQLAlchemy session boundary.
+ * @post Provides valid access to identity data.
+ * @pre Database connection is active.
+ */
+
+// --- AuthRepository (backend/src/core/auth/repository.py)
+/**!
+ * @brief Provides low-level CRUD operations for identity and authorization records.
+ * @post Entity instances returned safely.
+ * @pre Database session is bound.
+ */
+
+// --- get_user_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve user by UUID.
+ * @post Returns User object if found, else None.
+ * @pre user_id is a valid UUID string.
+ */
+
+// --- get_user_by_username (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve user by username.
+ * @post Returns User object if found, else None.
+ * @pre username is a non-empty string.
+ */
+
+// --- get_role_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve role by UUID with permissions preloaded.
+ */
+
+// --- get_role_by_name (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve role by unique name.
+ */
+
+// --- get_permission_by_id (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve permission by UUID.
+ */
+
+// --- get_permission_by_resource_action (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve permission by resource and action tuple.
+ */
+
+// --- list_permissions (backend/src/core/auth/repository.py)
+/**!
+ * @brief List all system permissions.
+ */
+
+// --- get_user_dashboard_preference (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve dashboard filters/preferences for a user.
+ */
+
+// --- get_roles_by_ad_groups (backend/src/core/auth/repository.py)
+/**!
+ * @brief Retrieve roles that match a list of AD group names.
+ * @post Returns a list of Role objects mapped to the provided AD groups.
+ * @pre groups is a list of strings representing AD group identifiers.
+ */
+
+// --- AuthSecurityModule (backend/src/core/auth/security.py)
+/**!
+ * @brief Utility for password hashing and verification using Passlib.
+ * @invariant Uses bcrypt for hashing with standard work factor.
+ */
+
+// --- verify_password (backend/src/core/auth/security.py)
+/**!
+ * @brief Verifies a plain password against a hashed password.
+ * @post Returns True if password matches, False otherwise.
+ * @pre plain_password is a string, hashed_password is a bcrypt hash.
+ */
+
+// --- get_password_hash (backend/src/core/auth/security.py)
+/**!
+ * @brief Generates a bcrypt hash for a plain password.
+ * @post Returns a secure bcrypt hash string.
+ * @pre password is a string.
+ */
+
+// --- ConfigManager (backend/src/core/config_manager.py)
+/**!
+ * @brief Manages application configuration persistence in DB with one-time migration from legacy JSON.
+ * @invariant Configuration must always be representable by AppConfig and persisted under global record id.
+ * @post Configuration is loaded into memory and logger is configured.
+ * @pre Database schema for AppConfigRecord must be initialized.
+ */
+
+// --- _apply_features_from_env (backend/src/core/config_manager.py)
+/**!
+ * @brief Read FEATURES__* env vars and apply them to a GlobalSettings features config.
+ */
+
+// --- _default_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Build default application configuration fallback.
+ */
+
+// --- _sync_raw_payload_from_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Merge typed AppConfig state into raw payload while preserving unsupported legacy sections.
+ */
+
+// --- _load_from_legacy_file (backend/src/core/config_manager.py)
+/**!
+ * @brief Load legacy JSON configuration for migration fallback path.
+ */
+
+// --- _get_record (backend/src/core/config_manager.py)
+/**!
+ * @brief Resolve global configuration record from DB.
+ */
+
+// --- _load_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Load configuration from DB or perform one-time migration from legacy JSON.
+ */
+
+// --- _sync_environment_records (backend/src/core/config_manager.py)
+/**!
+ * @brief Mirror configured environments into the relational environments table used by FK-backed domain models.
+ */
+
+// --- _delete_stale_environment_records (backend/src/core/config_manager.py)
+/**!
+ * @brief Remove persisted environment records that are no longer in the configured environments.
+ * @post Stale Environment rows are deleted via the session (caller must commit).
+ * @pre _sync_environment_records must already have run so the query returns a current view.
+ */
+
+// --- _save_config_to_db (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist provided AppConfig into the global DB configuration record.
+ */
+
+// --- save (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist current in-memory configuration state.
+ */
+
+// --- get_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Return current in-memory configuration snapshot.
+ */
+
+// --- get_payload (backend/src/core/config_manager.py)
+/**!
+ * @brief Return full persisted payload including sections outside typed AppConfig schema.
+ */
+
+// --- save_config (backend/src/core/config_manager.py)
+/**!
+ * @brief Persist configuration provided either as typed AppConfig or raw payload dict.
+ */
+
+// --- update_global_settings (backend/src/core/config_manager.py)
+/**!
+ * @brief Replace global settings and persist the resulting configuration.
+ */
+
+// --- validate_path (backend/src/core/config_manager.py)
+/**!
+ * @brief Validate that path exists and is writable, creating it when absent.
+ */
+
+// --- get_environments (backend/src/core/config_manager.py)
+/**!
+ * @brief Return all configured environments.
+ */
+
+// --- has_environments (backend/src/core/config_manager.py)
+/**!
+ * @brief Check whether at least one environment exists in configuration.
+ */
+
+// --- get_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Resolve a configured environment by identifier.
+ */
+
+// --- add_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Upsert environment by id into configuration and persist.
+ */
+
+// --- update_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Update existing environment by id and preserve masked password placeholder behavior.
+ */
+
+// --- delete_environment (backend/src/core/config_manager.py)
+/**!
+ * @brief Delete environment by id and persist when deletion occurs.
+ */
+
+// --- ConfigModels (backend/src/core/config_models.py)
+/**!
+ * @brief Defines the data models for application configuration using Pydantic.
+ */
+
+// --- CoreContracts (backend/src/core/config_models.py)
+/**!
+ * @brief Contract for core configuration models — Pydantic BaseModel subclasses with scheduler config.
+ */
+
+// --- ConnectionContracts (backend/src/core/config_models.py)
+/**!
+ * @brief Contract for database/environment connection configuration models.
+ */
+
+// --- Schedule (backend/src/core/config_models.py)
+/**!
+ * @brief Represents a backup schedule configuration.
+ */
+
+// --- Environment (backend/src/core/config_models.py)
+/**!
+ * @brief Represents a Superset environment configuration.
+ */
+
+// --- LoggingConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Defines the configuration for the application's logging system.
+ */
+
+// --- CleanReleaseConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Configuration for clean release compliance subsystem.
+ */
+
+// --- FeaturesConfig (backend/src/core/config_models.py)
+/**!
+ * @brief Top-level feature flags that toggle entire project features on/off.
+ */
+
+// --- GlobalSettings (backend/src/core/config_models.py)
+/**!
+ * @brief Represents global application settings.
+ */
+
+// --- AppConfig (backend/src/core/config_models.py)
+/**!
+ * @brief The root configuration model containing all application settings.
+ */
+
+// --- CotLoggerModule (backend/src/core/cot_logger.py)
+/**!
+ * @brief Structured JSON logger implementing the molecular CoT (Chain-of-Thought) logging protocol.
+ */
+
+// --- cot_trace_context (backend/src/core/cot_logger.py)
+/**!
+ * @brief ContextVars for trace ID and span ID propagation across async boundaries.
+ */
+
+// --- cot_logger_instance (backend/src/core/cot_logger.py)
+/**!
+ * @brief Dedicated Python logger for all CoT (molecular) log output.
+ */
+
+// --- seed_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Generate a new UUID4 trace_id, set it in ContextVar, and return it.
+ */
+
+// --- set_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Set an explicit trace_id into the ContextVar (e.g. from an incoming header).
+ */
+
+// --- get_trace_id (backend/src/core/cot_logger.py)
+/**!
+ * @brief Get the current trace_id from ContextVar.
+ */
+
+// --- push_span (backend/src/core/cot_logger.py)
+/**!
+ * @brief Set a new span_id in ContextVar and return the previous span_id for later restoration.
+ */
+
+// --- pop_span (backend/src/core/cot_logger.py)
+/**!
+ * @brief Restore a previous span_id into the ContextVar.
+ */
+
+// --- cot_log_function (backend/src/core/cot_logger.py)
+/**!
+ * @brief Core structured logging function that emits a single-line JSON record.
+ */
+
+// --- MarkerLogger (backend/src/core/cot_logger.py)
+/**!
+ * @brief Thin proxy class providing .reason(), .reflect(), .explore() convenience methods.
+ */
+
+// --- MarkerLogger.__init__ (backend/src/core/cot_logger.py)
+/**!
+ * @brief Store the module/component name used as the 'src' field in all log calls.
+ */
+
+// --- MarkerLogger.reason (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log a REASON marker — strict deduction, core logic.
+ */
+
+// --- MarkerLogger.reflect (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log a REFLECT marker — self-check, structural validation.
+ */
+
+// --- MarkerLogger.explore (backend/src/core/cot_logger.py)
+/**!
+ * @brief Log an EXPLORE marker — searching, alternatives, violated assumptions.
+ */
+
+// --- DatabaseModule (backend/src/core/database.py)
+/**!
+ * @brief Configures database connection and session management (PostgreSQL-first).
+ * @invariant A single engine instance is used for the entire application.
+ */
+
+// --- BASE_DIR (backend/src/core/database.py)
+/**!
+ * @brief Base directory for the backend.
+ */
+
+// --- DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the main application database. Read from env; dev fallback only.
+ */
+
+// --- TASKS_DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the tasks execution database.
+ */
+
+// --- AUTH_DATABASE_URL (backend/src/core/database.py)
+/**!
+ * @brief URL for the authentication database.
+ */
+
+// --- engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for mappings database.
+ */
+
+// --- tasks_engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for tasks database.
+ */
+
+// --- auth_engine (backend/src/core/database.py)
+/**!
+ * @brief SQLAlchemy engine for authentication database.
+ */
+
+// --- SessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the main mappings database.
+ * @pre engine is initialized.
+ */
+
+// --- TasksSessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the tasks execution database.
+ * @pre tasks_engine is initialized.
+ */
+
+// --- AuthSessionLocal (backend/src/core/database.py)
+/**!
+ * @brief A session factory for the authentication database.
+ * @pre auth_engine is initialized.
+ */
+
+// --- _ensure_user_dashboard_preferences_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for user_dashboard_preferences table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database where profile table is stored.
+ */
+
+// --- _ensure_user_dashboard_preferences_health_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for user_dashboard_preferences table (health fields).
+ */
+
+// --- _ensure_llm_validation_results_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for llm_validation_results table.
+ */
+
+// --- _ensure_git_server_configs_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for git_server_configs table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database.
+ */
+
+// --- _ensure_auth_users_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for auth users table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to authentication database.
+ */
+
+// --- _ensure_filter_source_enum_values (backend/src/core/database.py)
+/**!
+ * @brief Adds missing FilterSource enum values to the PostgreSQL native filtersource type.
+ * @post New enum values are available without data loss.
+ * @pre bind_engine points to application database with imported_filters table.
+ */
+
+// --- _ensure_dataset_review_session_columns (backend/src/core/database.py)
+/**!
+ * @brief Apply additive schema upgrades for dataset review persistence required by optimistic-lock and recovery metadata semantics.
+ * @post Missing additive columns across legacy dataset review tables are created without removing existing data.
+ * @pre bind_engine points to the application database where dataset review tables are stored.
+ */
+
+// --- _ensure_translation_schedules_columns (backend/src/core/database.py)
+/**!
+ * @brief Applies additive schema upgrades for translation_schedules table.
+ * @post Missing columns are added without data loss.
+ * @pre bind_engine points to application database.
+ */
+
+// --- _ensure_dictionary_entries_columns (backend/src/core/database.py)
+/**!
+ * @brief Additive migration for dictionary_entries origin tracking columns.
+ */
+
+// --- init_db (backend/src/core/database.py)
+/**!
+ * @brief Initializes the database by creating all tables.
+ * @post Database tables created in all databases.
+ * @pre engine, tasks_engine and auth_engine are initialized.
+ */
+
+// --- get_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting a database session.
+ * @post Session is closed after use.
+ * @pre SessionLocal is initialized.
+ */
+
+// --- get_tasks_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting a tasks database session.
+ * @post Session is closed after use.
+ * @pre TasksSessionLocal is initialized.
+ */
+
+// --- get_auth_db (backend/src/core/database.py)
+/**!
+ * @brief Dependency for getting an authentication database session.
+ * @post Session is closed after use.
+ * @pre AuthSessionLocal is initialized.
+ */
+
+// --- EncryptionKeyModule (backend/src/core/encryption_key.py)
+/**!
+ * @brief Resolve and persist the Fernet encryption key required by runtime services.
+ * @invariant Runtime key resolution never falls back to an ephemeral secret.
+ * @post A valid Fernet key is available to runtime services via ENCRYPTION_KEY.
+ * @pre Runtime environment can read process variables and target .env path is writable when key generation is required.
+ */
+
+// --- ensure_encryption_key (backend/src/core/encryption_key.py)
+/**!
+ * @brief Ensure backend runtime has a persistent valid Fernet key.
+ * @post Returns a valid Fernet key and guarantees it is present in process environment.
+ * @pre env_file_path points to a writable backend .env file or ENCRYPTION_KEY exists in process environment.
+ */
+
+// --- LoggerModule (backend/src/core/logger.py)
+/**!
+ * @brief Application logging system with CotJsonFormatter producing molecular CoT JSON output.
+ * @invariant CotJsonFormatter.format() always returns valid single-line JSON string.
+ * @post All log output is single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+ * @pre Python 3.7+ with cot_logger ContextVars available.
+ */
+
+// --- CotJsonFormatter (backend/src/core/logger.py)
+/**!
+ * @brief JSON formatter implementing the molecular CoT logging protocol. Outputs single-line JSON with ts, level, trace_id, src, marker, intent, payload, error, span_id.
+ */
+
+// --- CotJsonFormatter.format (backend/src/core/logger.py)
+/**!
+ * @brief Format a LogRecord into a single-line CoT JSON string with molecular CoT protocol fields.
+ * @invariant Output is always valid single-line JSON.
+ */
+
+// --- BeliefFormatter (backend/src/core/logger.py)
+/**!
+ * @brief Legacy formatter that adds belief state prefixes to log messages. Deprecated in favor of CotJsonFormatter.
+ */
+
+// --- LogEntry (backend/src/core/logger.py)
+/**!
+ * @brief A Pydantic model representing a single, structured log entry.
+ */
+
+// --- belief_scope (backend/src/core/logger.py)
+/**!
+ * @brief Context manager for Molecular CoT structured logging. Uses cot_logger.log() for JSON output.
+ * @post Thread-local belief state is updated; REASON/REFLECT/EXPLORE markers emitted via structured JSON logger.
+ * @pre anchor_id must be provided.
+ */
+
+// --- configure_logger (backend/src/core/logger.py)
+/**!
+ * @brief Configures the main logger and the CoT logger with CotJsonFormatter, file handlers, and global flags.
+ * @post Logger levels, handlers, formatters, belief state flag, and task log level are updated.
+ * @pre config is a valid LoggingConfig instance.
+ */
+
+// --- get_task_log_level (backend/src/core/logger.py)
+/**!
+ * @brief Returns the current task log level filter.
+ */
+
+// --- should_log_task_level (backend/src/core/logger.py)
+/**!
+ * @brief Checks if a log level should be recorded based on task_log_level setting.
+ */
+
+// --- Logger (backend/src/core/logger.py)
+/**!
+ * @brief The global application logger instance configured with CotJsonFormatter, console handler, and WebSocketLogHandler.
+ */
+
+// --- believed (backend/src/core/logger.py)
+/**!
+ * @brief A decorator that wraps a function in a belief scope.
+ */
+
+// --- explore (backend/src/core/logger.py)
+/**!
+ * @brief Logs an EXPLORE marker (WARNING level) with structured extra data for CotJsonFormatter.
+ */
+
+// --- reason (backend/src/core/logger.py)
+/**!
+ * @brief Logs a REASON marker (DEBUG level) with structured extra data for CotJsonFormatter.
+ */
+
+// --- reflect (backend/src/core/logger.py)
+/**!
+ * @brief Logs a REFLECT marker (DEBUG level) with structured extra data for CotJsonFormatter.
+ */
+
+// --- test_logger (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Unit tests for logger module
+ */
+
+// --- test_belief_scope_logs_reason_reflect_at_debug (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope generates [REASON] and [REFLECT] logs at DEBUG level.
+ * @post Logs are verified to contain REASON and REFLECT markers at DEBUG level.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_error_handling (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs EXPLORE on exception.
+ * @post Logs are verified to contain EXPLORE marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_success_reflect (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs REFLECT on success.
+ * @post Logs are verified to contain REFLECT marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_not_visible_at_info (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that belief_scope REFLECT logs are NOT visible at INFO level.
+ * @post REASON is visible at INFO (uses info()); REFLECT is not (uses debug()).
+ * @pre belief_scope is available. caplog fixture is used.
+ */
+
+// --- test_task_log_level_default (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that default task log level is INFO.
+ * @post Default level is INFO.
+ * @pre None.
+ */
+
+// --- test_should_log_task_level (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that should_log_task_level correctly filters log levels.
+ * @post Filtering works correctly for all level combinations.
+ * @pre None.
+ */
+
+// --- test_configure_logger_task_log_level (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that configure_logger updates task_log_level.
+ * @post task_log_level is updated correctly.
+ * @pre LoggingConfig is available.
+ */
+
+// --- test_enable_belief_state_flag (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test that enable_belief_state flag controls belief_scope logging.
+ * @post belief_scope explicit REASON logs are controlled by the flag; REFLECT always logged.
+ * @pre LoggingConfig is available. caplog fixture is used.
+ */
+
+// --- test_belief_scope_missing_anchor (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test @PRE condition: anchor_id must be provided
+ */
+
+// --- test_configure_logger_post_conditions (backend/src/core/logger/__tests__/test_logger.py)
+/**!
+ * @brief Test @POST condition: Logger level, handlers, belief state flag, and task log level are updated.
+ */
+
+// --- IdMappingServiceModule (backend/src/core/mapping_service.py)
+/**!
+ * @brief Service for tracking and synchronizing Superset Resource IDs (UUID <-> Integer ID)
+ * @invariant sync_environment must handle remote API failures gracefully.
+ * @post Mapping synchronization and lookup APIs are available for environment-scoped UUID-to-integer resolution.
+ * @pre Database session is valid and Superset client factory returns authenticated clients for requested environments.
+ */
+
+// --- IdMappingService (backend/src/core/mapping_service.py)
+/**!
+ * @brief Service handling the cataloging and retrieval of remote Superset Integer IDs.
+ * @invariant self.db remains the authoritative session for all mapping operations.
+ * @post Service instance provides scheduler control and environment-scoped mapping synchronization APIs.
+ * @pre db_session is an active SQLAlchemy Session bound to mapping tables.
+ */
+
+// --- start_scheduler (backend/src/core/mapping_service.py)
+/**!
+ * @brief Starts the background scheduler with a given cron string.
+ * @param superset_client_factory - Function to get a client for an environment.
+ */
+
+// --- sync_environment (backend/src/core/mapping_service.py)
+/**!
+ * @brief Fully synchronizes mapping for a specific environment.
+ * @param superset_client - Instance capable of hitting the Superset API.
+ * @post ResourceMapping records for the environment are created or updated.
+ * @pre environment_id exists in the database.
+ */
+
+// --- get_remote_id (backend/src/core/mapping_service.py)
+/**!
+ * @brief Retrieves the remote integer ID for a given universal UUID.
+ * @param uuid (str)
+ * @return Optional[int]
+ */
+
+// --- get_remote_ids_batch (backend/src/core/mapping_service.py)
+/**!
+ * @brief Retrieves remote integer IDs for a list of universal UUIDs efficiently.
+ * @param uuids (List[str])
+ * @return Dict[str, int] - Mapping of UUID -> Integer ID
+ */
+
+// --- middleware_package (backend/src/core/middleware/__init__.py)
+/**!
+ * @brief FastAPI/Starlette middleware package for request-level context and tracing.
+ */
+
+// --- TraceContextMiddlewareModule (backend/src/core/middleware/trace.py)
+/**!
+ * @brief FastAPI/Starlette middleware that seeds a trace_id for every incoming HTTP request.
+ */
+
+// --- TraceContextMiddleware (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Starlette BaseHTTPMiddleware that seeds a trace_id per request.
+ */
+
+// --- TraceContextMiddleware.__init__ (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Standard BaseHTTPMiddleware initialiser.
+ */
+
+// --- TraceContextMiddleware.dispatch (backend/src/core/middleware/trace.py)
+/**!
+ * @brief Dispatch handler that seeds trace_id before passing to the next middleware.
+ */
+
+// --- MigrationPackage (backend/src/core/migration/__init__.py)
+/**!
+ */
+
+// --- MigrationArchiveParserModule (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Parse Superset export ZIP archives into normalized object catalogs for diffing.
+ * @invariant Parsing is read-only and never mutates archive files.
+ * @post Parsed migration archive returned
+ * @pre Archive file path is valid and readable
+ */
+
+// --- MigrationArchiveParser (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Extract normalized dashboards/charts/datasets metadata from ZIP archives.
+ */
+
+// --- extract_objects_from_zip (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Extract object catalogs from Superset archive.
+ * @post Returns object lists grouped by resource type.
+ * @pre zip_path points to a valid readable ZIP.
+ * @return Dict[str, List[Dict[str, Any]]]
+ */
+
+// --- _collect_yaml_objects (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Read and normalize YAML manifests for one object type.
+ * @post Returns only valid normalized objects.
+ * @pre object_type is one of dashboards/charts/datasets.
+ */
+
+// --- _normalize_object_payload (backend/src/core/migration/archive_parser.py)
+/**!
+ * @brief Convert raw YAML payload to stable diff signature shape.
+ * @post Returns normalized descriptor with `uuid`, `title`, and `signature`.
+ * @pre payload is parsed YAML mapping.
+ */
+
+// --- MigrationDryRunOrchestratorModule (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Compute pre-flight migration diff and risk scoring without apply.
+ * @invariant Dry run is informative only and must not mutate target environment.
+ * @post Dry-run diff returned without mutation
+ * @pre Source and target environments configured
+ */
+
+// --- MigrationDryRunService (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build deterministic diff/risk payload for migration pre-flight.
+ */
+
+// --- run (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Execute full dry-run computation for selected dashboards.
+ * @post Returns JSON-serializable pre-flight payload with summary, diff and risk.
+ * @pre source/target clients are authenticated and selection validated by caller.
+ */
+
+// --- _load_db_mapping (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Resolve UUID mapping for optional DB config replacement.
+ */
+
+// --- _accumulate_objects (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Merge extracted resources by UUID to avoid duplicates.
+ */
+
+// --- _index_by_uuid (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build UUID-index map for normalized resources.
+ */
+
+// --- _build_object_diff (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Compute create/update/delete buckets by UUID+signature.
+ */
+
+// --- _build_target_signatures (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Pull target metadata and normalize it into comparable signatures.
+ */
+
+// --- _build_risks (backend/src/core/migration/dry_run_orchestrator.py)
+/**!
+ * @brief Build risk items for missing datasource, broken refs, overwrite, owner mismatch.
+ */
+
+// --- RiskAssessorModule (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Compute deterministic migration risk items and aggregate score for dry-run reporting.
+ * @invariant Risk scoring must remain bounded to [0,100] and preserve severity-to-weight mapping.
+ * @post Risk scoring output preserves item list and provides bounded score with derived level.
+ * @pre Risk assessor functions receive normalized migration object collections from dry-run orchestration.
+ */
+
+// --- index_by_uuid (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Build UUID-index from normalized objects.
+ * @post Returns mapping keyed by string uuid; only truthy uuid values are included.
+ * @pre Input list items are dict-like payloads potentially containing "uuid".
+ */
+
+// --- extract_owner_identifiers (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Normalize owner payloads for stable comparison.
+ * @post Returns sorted unique owner identifiers as strings.
+ * @pre Owners may be list payload, scalar values, or None.
+ */
+
+// --- build_risks (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Build risk list from computed diffs and target catalog state.
+ * @post Returns list of deterministic risk items derived from overwrite, missing datasource, reference, and owner mismatch checks.
+ * @pre target_client is authenticated/usable for database list retrieval.
+ */
+
+// --- score_risks (backend/src/core/migration/risk_assessor.py)
+/**!
+ * @brief Aggregate risk list into score and level.
+ * @post Returns dict with score in [0,100], derived level, and original items.
+ * @pre risk_items contains optional severity fields expected in {high,medium,low} or defaults to low weight.
+ */
+
+// --- MigrationEngineModule (backend/src/core/migration_engine.py)
+/**!
+ * @brief Transforms Superset export ZIP archives while preserving archive integrity and patching mapped identifiers.
+ * @invariant ZIP structure and non-targeted metadata must remain valid after transformation.
+ * @post Migration engine contracts preserve ZIP integrity while exposing transformation entrypoints for import pipelines.
+ * @pre Input archives are readable Superset exports and optional mapping collaborators expose remote id lookup APIs.
+ */
+
+// --- MigrationEngine (backend/src/core/migration_engine.py)
+/**!
+ * @brief Engine for transforming Superset export ZIPs.
+ */
+
+// --- transform_zip (backend/src/core/migration_engine.py)
+/**!
+ * @brief Extracts ZIP, replaces database UUIDs in YAMLs, patches cross-filters, and re-packages.
+ * @param fix_cross_filters (bool) - Whether to patch dashboard json_metadata.
+ * @post Returns True only when extraction, transformation, and packaging complete without exception.
+ * @pre zip_path points to a readable ZIP; output_path parent is writable; db_mapping keys/values are UUID strings.
+ * @return bool - True if successful.
+ */
+
+// --- _transform_yaml (backend/src/core/migration_engine.py)
+/**!
+ * @brief Replaces database_uuid in a single YAML file.
+ * @param db_mapping (Dict[str, str]) - UUID mapping dictionary.
+ * @post database_uuid is replaced in-place only when source UUID is present in db_mapping.
+ * @pre file_path exists, is readable YAML, and db_mapping contains source->target UUID pairs.
+ */
+
+// --- _extract_chart_uuids_from_archive (backend/src/core/migration_engine.py)
+/**!
+ * @brief Scans extracted chart YAML files and builds a source chart ID to UUID lookup map.
+ * @param temp_dir (Path) - Root dir of unpacked archive.
+ * @post Returns a best-effort Dict[int, str] containing only parseable chart id/uuid pairs.
+ * @pre temp_dir exists and points to extracted archive root with optional chart YAML resources.
+ * @return Dict[int, str] - Mapping of source Integer ID to UUID.
+ */
+
+// --- _patch_dashboard_metadata (backend/src/core/migration_engine.py)
+/**!
+ * @brief Rewrites dashboard json_metadata chart/dataset integer identifiers using target environment mappings.
+ * @param source_map (Dict[int, str])
+ * @post json_metadata is re-serialized with mapped integer IDs when remote mappings are available; otherwise file remains unchanged.
+ * @pre file_path points to dashboard YAML with json_metadata; target_env_id is non-empty; source_map contains source id->uuid.
+ */
+
+// --- PluginBase (backend/src/core/plugin_base.py)
+/**!
+ * @brief PluginLoader scans for subclasses of PluginBase.
+ * @invariant All plugins MUST inherit from this class.
+ */
+
+// --- id (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the unique identifier for the plugin.
+ * @post Returns string ID.
+ * @pre Plugin instance exists.
+ * @return str - Plugin ID.
+ */
+
+// --- name (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the human-readable name of the plugin.
+ * @post Returns string name.
+ * @pre Plugin instance exists.
+ * @return str - Plugin name.
+ */
+
+// --- description (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns a brief description of the plugin.
+ * @post Returns string description.
+ * @pre Plugin instance exists.
+ * @return str - Plugin description.
+ */
+
+// --- version (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the version of the plugin.
+ * @post Returns string version.
+ * @pre Plugin instance exists.
+ * @return str - Plugin version.
+ */
+
+// --- required_permission (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the required permission string to execute this plugin.
+ * @post Returns string permission.
+ * @pre Plugin instance exists.
+ * @return str - Required permission (e.g., "plugin:backup:execute").
+ */
+
+// --- ui_route (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the frontend route for the plugin's UI, if applicable.
+ * @post Returns string route or None.
+ * @pre Plugin instance exists.
+ * @return Optional[str] - Frontend route.
+ */
+
+// --- get_schema (backend/src/core/plugin_base.py)
+/**!
+ * @brief Returns the JSON schema for the plugin's input parameters.
+ * @post Returns dict schema.
+ * @pre Plugin instance exists.
+ * @return Dict[str, Any] - JSON schema.
+ */
+
+// --- execute (backend/src/core/plugin_base.py)
+/**!
+ * @brief Executes the plugin's core logic.
+ * @param params (Dict[str, Any]) - Validated input parameters.
+ * @post Plugin execution is completed.
+ * @pre params must be a dictionary.
+ */
+
+// --- PluginConfig (backend/src/core/plugin_base.py)
+/**!
+ * @brief Validated PluginConfig exposed to API layer.
+ */
+
+// --- PluginLoader (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Discovers and manages available PluginBase implementations.
+ */
+
+// --- _load_plugins (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Scans the plugin directory and loads all valid plugins.
+ * @post _load_module is called for each .py file.
+ * @pre plugin_dir exists or can be created.
+ */
+
+// --- _load_module (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Loads a single Python module and discovers PluginBase implementations.
+ * @param file_path (str) - The path to the module file.
+ * @post Plugin classes are instantiated and registered.
+ * @pre module_name and file_path are valid.
+ */
+
+// --- _register_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Registers a PluginBase instance and its configuration.
+ * @param plugin_instance (PluginBase) - The plugin instance to register.
+ * @post Plugin is added to _plugins and _plugin_configs.
+ * @pre plugin_instance is a valid implementation of PluginBase.
+ */
+
+// --- get_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Retrieves a loaded plugin instance by its ID.
+ * @param plugin_id (str) - The unique identifier of the plugin.
+ * @post Returns plugin instance or None.
+ * @pre plugin_id is a string.
+ * @return Optional[PluginBase] - The plugin instance if found, otherwise None.
+ */
+
+// --- get_all_plugin_configs (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Returns a list of all registered plugin configurations.
+ * @post Returns list of all PluginConfig objects.
+ * @pre None.
+ * @return List[PluginConfig] - A list of plugin configurations.
+ */
+
+// --- has_plugin (backend/src/core/plugin_loader.py)
+/**!
+ * @brief Checks if a plugin with the given ID is registered.
+ * @param plugin_id (str) - The unique identifier of the plugin.
+ * @post Returns True if plugin exists.
+ * @pre plugin_id is a string.
+ * @return bool - True if the plugin is registered, False otherwise.
+ */
+
+// --- SchedulerModule (backend/src/core/scheduler.py)
+/**!
+ * @brief Manages scheduled tasks using APScheduler.
+ */
+
+// --- SchedulerService (backend/src/core/scheduler.py)
+/**!
+ * @brief Provides a service to manage scheduled backup tasks.
+ */
+
+// --- start (backend/src/core/scheduler.py)
+/**!
+ * @brief Starts the background scheduler and loads initial schedules.
+ * @post Scheduler is running and schedules are loaded.
+ * @pre Scheduler should be initialized.
+ */
+
+// --- stop (backend/src/core/scheduler.py)
+/**!
+ * @brief Stops the background scheduler.
+ * @post Scheduler is shut down.
+ * @pre Scheduler should be running.
+ */
+
+// --- load_schedules (backend/src/core/scheduler.py)
+/**!
+ * @brief Load backup and active translation schedules from config and DB, re-registering all jobs.
+ * @post All enabled backup jobs and active translation schedules are re-registered in APScheduler.
+ * @pre config_manager must have valid configuration; database is accessible.
+ */
+
+// --- add_backup_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Adds a scheduled backup job for an environment.
+ * @param cron_expression (str) - The cron expression for the schedule.
+ * @post A new job is added to the scheduler or replaced if it already exists.
+ * @pre env_id and cron_expression must be valid strings.
+ */
+
+// --- add_translation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Register a translation schedule with APScheduler.
+ * @post A new APScheduler job is registered or replaced if it already exists.
+ * @pre schedule_id, job_id, and cron_expression are valid strings.
+ */
+
+// --- remove_translation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Remove a translation schedule from APScheduler.
+ * @post The APScheduler job is removed if it exists; silently ignored otherwise.
+ * @pre schedule_id is a valid string.
+ */
+
+// --- _trigger_backup (backend/src/core/scheduler.py)
+/**!
+ * @brief Triggered by the scheduler to start a backup task.
+ * @param env_id (str) - The ID of the environment.
+ * @post A new backup task is created in the task manager if not already running.
+ * @pre env_id must be a valid environment ID.
+ */
+
+// --- add_validation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Register a validation policy schedule with APScheduler.
+ * @post A new APScheduler job is registered or replaced if it already exists.
+ * @pre policy_id and cron_expression are valid strings.
+ */
+
+// --- remove_validation_job (backend/src/core/scheduler.py)
+/**!
+ * @brief Remove a validation policy schedule from APScheduler.
+ * @post The APScheduler job is removed if it exists; silently ignored otherwise.
+ * @pre policy_id is a valid string.
+ */
+
+// --- reload_validation_policy (backend/src/core/scheduler.py)
+/**!
+ * @brief Reload a single validation policy schedule — calls remove then add.
+ * @post Old job is removed; new job is registered if policy is active and has schedule_days.
+ * @pre policy_id is a valid ValidationPolicy id with schedule data in DB.
+ */
+
+// --- _trigger_validation (backend/src/core/scheduler.py)
+/**!
+ * @brief APScheduler job handler — triggers validation runs for a policy.
+ * @post A validation task is spawned via TaskManager for each dashboard in the policy.
+ * @pre policy_id is a valid ValidationPolicy id with dashboard_ids.
+ */
+
+// --- ThrottledSchedulerConfigurator (backend/src/core/scheduler.py)
+/**!
+ * @brief Distributes validation tasks evenly within an execution window.
+ * @invariant Returned schedule size always matches number of dashboard IDs.
+ * @post Produces deterministic per-dashboard run timestamps within the configured window.
+ * @pre Validation policies provide a finite dashboard list and a valid execution window.
+ */
+
+// --- calculate_schedule (backend/src/core/scheduler.py)
+/**!
+ * @brief Calculates execution times for N tasks within a window.
+ * @invariant Tasks are distributed with near-even spacing.
+ * @post Returns List[EXT:Python:datetime] of scheduled times.
+ * @pre window_start, window_end (time), dashboard_ids (List), current_date (date).
+ */
+
+// --- SupersetClientModule (backend/src/core/superset_client/__init__.py)
+/**!
+ * @brief Предоставляет высокоуровневый клиент для взаимодействия с Superset REST API, инкапсулируя логику запросов, обработку ошибок и пагинацию.
+ * @invariant All network operations must use the internal APIClient instance.
+ */
+
+// --- SupersetClient (backend/src/core/superset_client/__init__.py)
+/**!
+ * @brief Класс-обёртка над Superset REST API, предоставляющий методы для работы с дашбордами и датасетами.
+ */
+
+// --- SupersetClientBase (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Base class for SupersetClient providing initialization, authentication, pagination, and import/export helpers.
+ */
+
+// --- SupersetClientInit (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Инициализирует клиент, проверяет конфигурацию и создает сетевой клиент.
+ */
+
+// --- SupersetClientAuthenticate (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Authenticates the client using the configured credentials.
+ */
+
+// --- SupersetClientHeaders (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Возвращает базовые HTTP-заголовки, используемые сетевым клиентом.
+ */
+
+// --- SupersetClientValidateQueryParams (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Ensures query parameters have default page and page_size.
+ */
+
+// --- SupersetClientFetchTotalObjectCount (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Fetches the total number of items for a given endpoint.
+ */
+
+// --- SupersetClientFetchAllPages (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Iterates through all pages to collect all data items.
+ */
+
+// --- SupersetClientDoImport (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Performs the actual multipart upload for import.
+ */
+
+// --- SupersetClientValidateExportResponse (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Validates that the export response is a non-empty ZIP archive.
+ */
+
+// --- SupersetClientResolveExportFilename (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Determines the filename for an exported dashboard.
+ */
+
+// --- SupersetClientValidateImportFile (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Validates that the file to be imported is a valid ZIP with metadata.yaml.
+ */
+
+// --- SupersetClientResolveTargetIdForDelete (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Resolves a dashboard ID from either an ID or a slug.
+ */
+
+// --- SupersetClientGetAllResources (backend/src/core/superset_client/_base.py)
+/**!
+ * @brief Fetches all resources of a given type with id, uuid, and name columns.
+ */
+
+// --- SupersetChartsMixin (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Chart domain mixin for SupersetClient — list, get, extract IDs from layout.
+ */
+
+// --- SupersetClientGetChart (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Fetches a single chart by ID.
+ */
+
+// --- SupersetClientGetCharts (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Fetches all charts with pagination support.
+ */
+
+// --- SupersetClientExtractChartIdsFromLayout (backend/src/core/superset_client/_charts.py)
+/**!
+ * @brief Traverses dashboard layout metadata and extracts chart IDs from common keys.
+ */
+
+// --- SupersetDashboardsCrudMixin (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Dashboard CRUD mixin for SupersetClient — detail, export, import, delete.
+ */
+
+// --- SupersetClientGetDashboardDetail (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Fetches detailed dashboard information including related charts and datasets.
+ */
+
+// --- extract_dataset_id_from_form_data (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ */
+
+// --- SupersetClientExportDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Экспортирует дашборд в виде ZIP-архива.
+ */
+
+// --- SupersetClientImportDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Импортирует дашборд из ZIP-файла.
+ */
+
+// --- SupersetClientDeleteDashboard (backend/src/core/superset_client/_dashboards_crud.py)
+/**!
+ * @brief Удаляет дашборд по его ID или slug.
+ */
+
+// --- SupersetDashboardsFiltersMixin (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Dashboard native filter extraction mixin for SupersetClient.
+ */
+
+// --- SupersetClientGetDashboard (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches a single dashboard by ID or slug.
+ */
+
+// --- SupersetClientGetDashboardPermalinkState (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches stored dashboard permalink state by permalink key.
+ */
+
+// --- SupersetClientGetNativeFilterState (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Fetches stored native filter state by filter state key.
+ */
+
+// --- SupersetClientExtractNativeFiltersFromPermalink (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Extract native filters dataMask from a permalink key.
+ */
+
+// --- SupersetClientExtractNativeFiltersFromKey (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Extract native filters from a native_filters_key URL parameter.
+ */
+
+// --- SupersetClientParseDashboardUrlForFilters (backend/src/core/superset_client/_dashboards_filters.py)
+/**!
+ * @brief Parse a Superset dashboard URL and extract native filter state if present.
+ */
+
+// --- SupersetDashboardsListMixin (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Dashboard listing mixin for SupersetClient — paginated list, summary projection.
+ */
+
+// --- SupersetClientGetDashboards (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Получает полный список дашбордов, автоматически обрабатывая пагинацию.
+ */
+
+// --- SupersetClientGetDashboardsPage (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches a single dashboards page from Superset without iterating all pages.
+ */
+
+// --- SupersetClientGetDashboardsSummary (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches dashboard metadata optimized for the grid.
+ */
+
+// --- SupersetClientGetDashboardsSummaryPage (backend/src/core/superset_client/_dashboards_list.py)
+/**!
+ * @brief Fetches one page of dashboard metadata optimized for the grid.
+ */
+
+// --- SupersetDashboardsWriteMixin (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Dashboard write mixin for SupersetClient — markdown chart CRUD and layout manipulation for maintenance banners.
+ * @invariant All network operations use self.network.request()
+ */
+
+// --- create_markdown_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Create a markdown chart and return the new chart ID.
+ * @post Returns chart_id (int). Chart is NOT yet placed in dashboard layout.
+ * @pre dashboard_id exists in Superset. markdown_text not empty.
+ */
+
+// --- update_markdown_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Update the markdown text of an existing markdown chart.
+ * @post Chart markdown content updated.
+ * @pre chart_id exists and is a markdown chart.
+ */
+
+// --- update_dashboard_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Insert a native MARKDOWN element at (0,0) with full width (12 cols),
+ */
+
+// --- remove_chart_from_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Remove banner markdown element from dashboard layout without deleting the chart.
+ * @post MARKDOWN element removed from position_json; items shifted up.
+ * @pre dashboard_id exists. chart_id exists in layout as MARKDOWN-banner-{chart_id}.
+ */
+
+// --- delete_chart (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Delete a chart from Superset by ID.
+ * @post Chart permanently deleted from Superset.
+ * @pre chart_id exists.
+ */
+
+// --- update_banner_on_dashboard (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Update the content of a native MARKDOWN banner element on a dashboard.
+ * @post MARKDOWN element content updated on dashboard.
+ * @pre dashboard_id exists. chart_id used for key lookup.
+ */
+
+// --- get_dashboard_layout (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Fetch the position_json layout of a dashboard.
+ * @post Returns the dashboard layout dict.
+ * @pre dashboard_id exists.
+ */
+
+// --- _resolve_markdown_datasource (backend/src/core/superset_client/_dashboards_write.py)
+/**!
+ * @brief Find a valid datasource_id for markdown chart creation.
+ * @post Returns an integer datasource_id.
+ * @pre dashboard_id exists.
+ */
+
+// --- SupersetDatabasesMixin (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Database domain mixin for SupersetClient — list, get, summary, by_uuid.
+ */
+
+// --- SupersetClientGetDatabases (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Получает полный список баз данных.
+ */
+
+// --- SupersetClientGetDatabase (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Получает информацию о конкретной базе данных по её ID.
+ */
+
+// --- SupersetClientGetDatabasesSummary (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Fetch a summary of databases including uuid, name, and engine.
+ */
+
+// --- SupersetClientGetDatabaseByUuid (backend/src/core/superset_client/_databases.py)
+/**!
+ * @brief Find a database by its UUID.
+ */
+
+// --- SupersetDatasetsMixin (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Dataset domain mixin for SupersetClient — list, get, detail, update.
+ */
+
+// --- SupersetClientGetDatasets (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Получает полный список датасетов, автоматически обрабатывая пагинацию.
+ */
+
+// --- SupersetClientGetDatasetsSummary (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetches dataset metadata optimized for the Dataset Hub grid.
+ */
+
+// --- SupersetClientGetDatasetLinkedDashboardCount (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetch the number of dashboards linked to a dataset via related_objects endpoint.
+ */
+
+// --- SupersetClientGetDatasetDetail (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Fetches detailed dataset information including columns and linked dashboards.
+ */
+
+// --- SupersetClientGetDataset (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Получает информацию о конкретном датасете по его ID.
+ */
+
+// --- SupersetClientUpdateDataset (backend/src/core/superset_client/_datasets.py)
+/**!
+ * @brief Обновляет данные датасета по его ID.
+ */
+
+// --- SupersetDatasetsPreviewMixin (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Dataset preview compilation mixin for SupersetClient — build query context, compile SQL.
+ */
+
+// --- SupersetClientCompileDatasetPreview (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Compile dataset preview SQL through the strongest supported Superset preview endpoint family and return normalized SQL output.
+ */
+
+// --- SupersetClientBuildDatasetPreviewLegacyFormData (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Build browser-style legacy form_data payload for Superset preview endpoints inferred from observed deployment traffic.
+ */
+
+// --- SupersetClientBuildDatasetPreviewQueryContext (backend/src/core/superset_client/_datasets_preview.py)
+/**!
+ * @brief Build a reduced-scope chart-data query context for deterministic dataset preview compilation.
+ */
+
+// --- SupersetDatasetsPreviewFiltersMixin (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Filter normalization and SQL extraction helpers for dataset preview compilation.
+ */
+
+// --- SupersetClientNormalizeEffectiveFiltersForQueryContext (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Convert execution mappings into Superset chart-data filter objects.
+ */
+
+// --- SupersetClientExtractCompiledSqlFromPreviewResponse (backend/src/core/superset_client/_datasets_preview_filters.py)
+/**!
+ * @brief Normalize compiled SQL from either chart-data or legacy form_data preview responses.
+ */
+
+// --- LayoutUtils (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Utility functions for manipulating Superset dashboard position_json layout.
+ */
+
+// --- parse_position_json (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Parse position_json from a dashboard API response (may be string or dict).
+ * @post Returns a dict.
+ * @pre raw_position is a string, dict, or None.
+ */
+
+// --- _estimate_markdown_height (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Estimate grid height for a MARKDOWN element based on HTML content.
+ */
+
+// --- _generate_banner_id (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Generate a deterministic row and markdown key for a banner chart.
+ */
+
+// --- insert_banner_markdown_at_top (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Insert a ROW + native MARKDOWN pair at the top of the dashboard grid.
+ */
+
+// --- update_banner_markdown_content (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Update the code content and adaptive height of an existing banner markdown element.
+ * @post position_json is mutated; markdown content and height updated.
+ * @pre position_json has markdown_key. content is the new HTML/markdown string.
+ */
+
+// --- remove_banner_from_position (backend/src/core/superset_client/_layout_utils.py)
+/**!
+ * @brief Remove the banner ROW + MARKDOWN pair from the position dict and GRID children.
+ */
+
+// --- SupersetUserProjection (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief User/owner payload normalization helpers for Superset client responses.
+ */
+
+// --- SupersetUserProjectionMixin (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Mixin providing user/owner payload normalization for Superset API responses.
+ */
+
+// --- SupersetClientExtractOwnerLabels (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Normalize dashboard owners payload to stable display labels.
+ */
+
+// --- SupersetClientExtractUserDisplay (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Normalize user payload to a stable display name.
+ */
+
+// --- SupersetClientSanitizeUserText (backend/src/core/superset_client/_user_projection.py)
+/**!
+ * @brief Convert scalar value to non-empty user-facing text.
+ */
+
+// --- SupersetProfileLookup (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Provides environment-scoped Superset account lookup adapter with stable normalized output.
+ * @invariant Adapter never leaks raw upstream payload shape to API consumers.
+ */
+
+// --- SupersetAccountLookupAdapter (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Lookup Superset users and normalize candidates for profile binding.
+ */
+
+// --- __init__ (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Initializes lookup adapter with authenticated API client and environment context.
+ * @post Adapter is ready to perform users lookup requests.
+ * @pre network_client supports request(method, endpoint, params=...).
+ */
+
+// --- get_users_page (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Fetch one users page from Superset with passthrough search/sort parameters.
+ * @post Returns deterministic payload with normalized items and total count.
+ * @pre page_index >= 0 and page_size >= 1.
+ * @return Dict[str, Any]
+ */
+
+// --- _normalize_lookup_payload (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Convert Superset users response variants into stable candidates payload.
+ * @post Output contains canonical keys: status, environment_id, page_index, page_size, total, items.
+ * @pre response can be dict/list in any supported upstream shape.
+ * @return Dict[str, Any]
+ */
+
+// --- normalize_user_payload (backend/src/core/superset_profile_lookup.py)
+/**!
+ * @brief Project raw Superset user object to canonical candidate shape.
+ * @post Returns normalized candidate keys (environment_id, username, display_name, email, is_active).
+ * @pre raw_user may have heterogenous key names between Superset versions.
+ * @return Dict[str, Any]
+ */
+
+// --- TaskManagerPackage (backend/src/core/task_manager/__init__.py)
+/**!
+ */
+
+// --- TestContext (backend/src/core/task_manager/__tests__/test_context.py)
+/**!
+ * @brief Verify TaskContext preserves optional background task scheduler across sub-context creation.
+ */
+
+// --- test_task_context_preserves_background_tasks_across_sub_context (backend/src/core/task_manager/__tests__/test_context.py)
+/**!
+ * @brief Plugins must be able to access background_tasks from both root and sub-context loggers.
+ * @post background_tasks remains available on root and derived sub-contexts.
+ * @pre TaskContext is initialized with a BackgroundTasks-like object.
+ */
+
+// --- __tests__/test_task_logger (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Contract testing for TaskLogger
+ */
+
+// --- test_task_logger_initialization (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger initializes with correct task_id and state.
+ */
+
+// --- test_log_methods_delegation (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger delegates log method calls to the underlying persistence service.
+ */
+
+// --- test_with_source (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger.with_source returns a new logger with the correct source attribution.
+ */
+
+// --- test_missing_task_id (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger raises or handles missing task_id gracefully.
+ */
+
+// --- test_invalid_add_log_fn (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger raises ValueError for invalid add_log_fn parameter.
+ */
+
+// --- test_progress_log (backend/src/core/task_manager/__tests__/test_task_logger.py)
+/**!
+ * @brief Verify TaskLogger correctly logs progress updates with percentage and message.
+ */
+
+// --- TaskCleanupModule (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Implements task cleanup and retention policies, including associated logs.
+ */
+
+// --- TaskCleanupService (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Provides methods to clean up old task records and their associated logs.
+ */
+
+// --- run_cleanup (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Deletes tasks older than the configured retention period and their logs.
+ * @post Old tasks and their logs are deleted from persistence.
+ * @pre Config manager has valid settings.
+ */
+
+// --- delete_task_with_logs (backend/src/core/task_manager/cleanup.py)
+/**!
+ * @brief Delete a single task and all its associated logs.
+ * @param task_id (str) - The task ID to delete.
+ * @post Task and all its logs are deleted.
+ * @pre task_id is a valid task ID.
+ */
+
+// --- TaskContextModule (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Provides execution context passed to plugins during task execution.
+ * @invariant Each TaskContext is bound to a single task execution.
+ * @post Plugins receive context instances with stable logger and parameter accessors.
+ * @pre Task execution pipeline provides valid task identifiers, logging callbacks, and parameter dictionaries.
+ */
+
+// --- TaskContext (backend/src/core/task_manager/context.py)
+/**!
+ * @brief A container passed to plugin.execute() providing the logger and other task-specific utilities.
+ * @invariant logger is always a valid TaskLogger instance.
+ * @post Instance exposes immutable task identity with logger, params, and optional background task access.
+ * @pre Constructor receives non-empty task_id, callable add_log_fn, and params mapping.
+ */
+
+// --- task_id (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the task ID.
+ * @post Returns the task ID string.
+ * @pre TaskContext must be initialized.
+ * @return str - The task ID.
+ */
+
+// --- logger (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the TaskLogger instance for this context.
+ * @post Returns the TaskLogger instance.
+ * @pre TaskContext must be initialized.
+ * @return TaskLogger - The logger instance.
+ */
+
+// --- params (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get the task parameters.
+ * @post Returns the parameters dictionary.
+ * @pre TaskContext must be initialized.
+ * @return Dict[str, Any] - The task parameters.
+ */
+
+// --- background_tasks (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Expose optional background task scheduler for plugins that dispatch deferred side effects.
+ * @post Returns BackgroundTasks-like object or None.
+ * @pre TaskContext must be initialized.
+ */
+
+// --- get_param (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Get a specific parameter value with optional default.
+ * @param default (Any) - Default value if key not found.
+ * @post Returns parameter value or default.
+ * @pre TaskContext must be initialized.
+ * @return Any - Parameter value or default.
+ */
+
+// --- create_sub_context (backend/src/core/task_manager/context.py)
+/**!
+ * @brief Create a sub-context with a different default source.
+ * @param source (str) - New default source for logging.
+ * @post Returns new TaskContext with different logger source.
+ * @pre source is a non-empty string.
+ * @return TaskContext - New context with different source.
+ */
+
+// --- EventBusModule (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Task-scoped log buffering, persistence flushes, and subscriber fan-out for real-time
+ */
+
+// --- EventBus (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Coordinates task-scoped log buffering, persistence flushes, and subscriber fan-out
+ */
+
+// --- flush_task_logs (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Flush logs for a specific task immediately.
+ * @post Task's buffered logs are written to database.
+ * @pre task_id exists.
+ */
+
+// --- add_log (backend/src/core/task_manager/event_bus.py)
+/**!
+ * @brief Adds a log entry to a task buffer and notifies subscribers.
+ * @post Log added to buffer and pushed to queues (if level meets task_log_level filter).
+ * @pre Task exists.
+ */
+
+// --- TaskGraphModule (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief In-memory task registry with persistence-backed hydration, pagination, and
+ */
+
+// --- TaskGraph (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief In-memory task dependency graph spanning task registry nodes, pause futures,
+ */
+
+// --- add_task (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Register a task in the in-memory registry.
+ */
+
+// --- remove_tasks (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Remove tasks from registry and persistence, cancel futures for waiting tasks.
+ */
+
+// --- create_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Create and store a future for a paused task.
+ */
+
+// --- resolve_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Resolve a paused task's future and remove it from the map.
+ */
+
+// --- remove_future (backend/src/core/task_manager/graph.py)
+/**!
+ * @brief Remove a future without resolving it.
+ */
+
+// --- JobLifecycleModule (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Task creation, execution, pause/resume, and completion transitions for plugin-backed
+ */
+
+// --- JobLifecycle (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Encodes task creation, execution, pause/resume, and completion transitions for
+ */
+
+// --- _broadcast_dataset_updated (backend/src/core/task_manager/lifecycle.py)
+/**!
+ * @brief Broadcast dataset.updated event to all subscribers for a given environment.
+ */
+
+// --- TaskManagerModule (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Thin facade composing TaskGraph (registry), EventBus (log/pub-sub), and JobLifecycle
+ */
+
+// --- TaskManager (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Facade composing TaskGraph, EventBus, and JobLifecycle into a single interface.
+ * @post In-memory task graph, lifecycle scheduler, and log event bus stay consistent with
+ * @pre Plugin loader resolves plugin ids and persistence services are available.
+ */
+
+// --- _make_add_log_callback (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Create a closure for adding logs that looks up the task and delegates to EventBus.
+ */
+
+// --- _flusher_loop (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus._flusher_loop.
+ */
+
+// --- _flush_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus._flush_logs.
+ */
+
+// --- _flush_task_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Legacy alias delegating to EventBus.flush_task_logs.
+ */
+
+// --- get_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves a task by its ID.
+ */
+
+// --- get_all_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves all registered tasks.
+ */
+
+// --- get_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves tasks with pagination and optional status filter.
+ */
+
+// --- load_persisted_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Load persisted tasks using persistence service.
+ */
+
+// --- clear_tasks (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Clears tasks based on status filter (also deletes associated logs).
+ */
+
+// --- get_task_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Retrieves logs for a specific task (from memory or persistence).
+ */
+
+// --- get_task_log_stats (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Get statistics about logs for a task.
+ */
+
+// --- get_task_log_sources (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Get unique sources for a task's logs.
+ */
+
+// --- subscribe_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Subscribes to real-time logs for a task.
+ */
+
+// --- unsubscribe_logs (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Unsubscribes from real-time logs for a task.
+ */
+
+// --- create_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Creates and queues a new task for execution.
+ */
+
+// --- _run_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Internal method to execute a task with TaskContext support (delegates to lifecycle).
+ */
+
+// --- resolve_task (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Resumes a task that is awaiting mapping.
+ */
+
+// --- wait_for_resolution (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Pauses execution and waits for a resolution signal.
+ */
+
+// --- wait_for_input (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Pauses execution and waits for user input.
+ */
+
+// --- await_input (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Transition a task to AWAITING_INPUT state with input request.
+ */
+
+// --- resume_task_with_password (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Resume a task that is awaiting input with provided passwords.
+ */
+
+// --- subscribe_dataset_events (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Subscribe to dataset.updated events for an environment.
+ */
+
+// --- unsubscribe_dataset_events (backend/src/core/task_manager/manager.py)
+/**!
+ * @brief Unsubscribe from dataset.updated events.
+ */
+
+// --- TaskManagerModels (backend/src/core/task_manager/models.py)
+/**!
+ * @brief Defines the data models and enumerations used by the Task Manager.
+ * @invariant Must use Pydantic for data validation.
+ * @post Task models exported with immutable IDs
+ * @pre Task manager initialized
+ */
+
+// --- TaskStatus (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- LogLevel (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- TaskLog (backend/src/core/task_manager/models.py)
+/**!
+ * @brief A Pydantic model representing a persisted log entry from the database.
+ */
+
+// --- LogFilter (backend/src/core/task_manager/models.py)
+/**!
+ */
+
+// --- LogStats (backend/src/core/task_manager/models.py)
+/**!
+ * @brief Statistics about log entries for a task.
+ */
+
+// --- Task (backend/src/core/task_manager/models.py)
+/**!
+ * @brief A Pydantic model representing a single execution instance of a plugin, including its status, parameters, and logs.
+ */
+
+// --- TaskPersistenceModule (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Handles the persistence of tasks using SQLAlchemy and the tasks.db database.
+ * @invariant Database schema must match the TaskRecord model structure.
+ * @post Provides reliable storage and retrieval for task metadata and logs.
+ * @pre Tasks database must be initialized with TaskRecord and TaskLogRecord schemas.
+ */
+
+// --- TaskPersistenceService (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Provides methods to save, load, and delete task records in tasks.db using SQLAlchemy models.
+ * @invariant Persistence must handle potentially missing task fields natively.
+ * @post Persist operations leave matching TaskRecord rows committed or rolled back without leaking sessions, load operations return reconstructed Task objects from stored TaskRecord rows, and delete operations remove only the addressed task rows.
+ * @pre TasksSessionLocal must provide an active SQLAlchemy session, Task inputs must expose id/plugin_id/status/params/result/logs fields, and TaskRecord plus Environment schemas must be available.
+ */
+
+// --- _json_load_if_needed (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Safely load JSON strings from DB if necessary
+ * @post Returns parsed JSON object, list, string, or primitive
+ * @pre value is an arbitrary database value
+ */
+
+// --- _parse_datetime (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Safely parse a datetime string from the database
+ * @post Returns datetime object or None
+ * @pre value is an ISO string or datetime object
+ */
+
+// --- _resolve_environment_id (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Resolve environment id into existing environments.id value to satisfy FK constraints.
+ * @post Returns existing environments.id or None when unresolved.
+ * @pre Session is active
+ */
+
+// --- persist_task (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Persists or updates a single task in the database.
+ * @param task (Task) - The task object to persist.
+ * @post Task record created or updated in database.
+ * @pre isinstance(task, Task)
+ */
+
+// --- persist_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Persists multiple tasks.
+ * @param tasks (List[Task]) - The list of tasks to persist.
+ * @post All tasks in list are persisted.
+ * @pre isinstance(tasks, list)
+ */
+
+// --- load_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Loads tasks from the database.
+ * @param status (Optional[TaskStatus]) - Filter by status.
+ * @post Returns list of Task objects.
+ * @pre limit is an integer.
+ * @return List[Task] - The loaded tasks.
+ */
+
+// --- delete_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Deletes specific tasks from the database.
+ * @param task_ids (List[str]) - List of task IDs to delete.
+ * @post Specified task records deleted from database.
+ * @pre task_ids is a list of strings.
+ */
+
+// --- TaskLogPersistenceService (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Provides methods to store, query, summarize, and delete task log rows in the task_logs table.
+ * @invariant Log entries are batch-inserted for performance.
+ * @post add_logs commits all provided log entries or rolls back on failure, query methods return TaskLog or LogStats views reconstructed from TaskLogRecord rows, and delete methods remove only log rows matching the supplied task identifiers.
+ * @pre TasksSessionLocal must provide an active SQLAlchemy session, task_id inputs must identify task log rows, LogEntry batches must expose timestamp/level/source/message/metadata fields, and LogFilter inputs must provide pagination and filter attributes used by queries.
+ */
+
+// --- add_logs (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Batch insert log entries for a task.
+ * @param logs (List[LogEntry]) - Log entries to insert.
+ * @post All logs inserted into task_logs table.
+ * @pre logs is a list of LogEntry objects.
+ */
+
+// --- get_logs (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Query logs for a task with filtering and pagination.
+ * @param log_filter (LogFilter) - Filter parameters.
+ * @post Returns list of TaskLog objects matching filters.
+ * @pre task_id is a valid task ID.
+ * @return List[TaskLog] - Filtered log entries.
+ */
+
+// --- get_log_stats (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Get statistics about logs for a task.
+ * @param task_id (str) - The task ID.
+ * @post Returns LogStats with counts by level and source.
+ * @pre task_id is a valid task ID.
+ * @return LogStats - Statistics about task logs.
+ */
+
+// --- get_sources (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Get unique sources for a task's logs.
+ * @param task_id (str) - The task ID.
+ * @post Returns list of unique source strings.
+ * @pre task_id is a valid task ID.
+ * @return List[str] - Unique source names.
+ */
+
+// --- delete_logs_for_task (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Delete all logs for a specific task.
+ * @param task_id (str) - The task ID.
+ * @post All logs for the task are deleted.
+ * @pre task_id is a valid task ID.
+ */
+
+// --- delete_logs_for_tasks (backend/src/core/task_manager/persistence.py)
+/**!
+ * @brief Delete all logs for multiple tasks.
+ * @param task_ids (List[str]) - List of task IDs.
+ * @post All logs for the tasks are deleted.
+ * @pre task_ids is a list of task IDs.
+ */
+
+// --- TaskLoggerModule (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Provides a dedicated logger for tasks with automatic source attribution.
+ * @invariant Each TaskLogger instance is bound to a specific task_id and default source.
+ */
+
+// --- TaskLogger (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief A wrapper around TaskManager._add_log that carries task_id and source context.
+ * @invariant All log calls include the task_id and source.
+ */
+
+// --- with_source (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Create a sub-logger with a different default source.
+ * @param source (str) - New default source.
+ * @post Returns new TaskLogger with the same task_id but different source.
+ * @pre source is a non-empty string.
+ * @return TaskLogger - New logger instance.
+ */
+
+// --- _log (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Internal method to log a message at a given level.
+ * @param metadata (Optional[Dict]) - Additional structured data.
+ * @post Log entry added via add_log_fn.
+ * @pre level is a valid log level string.
+ */
+
+// --- debug (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a DEBUG level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added via internally with DEBUG level.
+ * @pre message is a string.
+ */
+
+// --- info (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log an INFO level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with INFO level.
+ * @pre message is a string.
+ */
+
+// --- warning (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a WARNING level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with WARNING level.
+ * @pre message is a string.
+ */
+
+// --- error (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log an ERROR level message.
+ * @param metadata (Optional[Dict]) - Additional data.
+ * @post Log entry added internally with ERROR level.
+ * @pre message is a string.
+ */
+
+// --- progress (backend/src/core/task_manager/task_logger.py)
+/**!
+ * @brief Log a progress update with percentage.
+ * @param source (Optional[str]) - Override source.
+ * @post Log entry with progress metadata added.
+ * @pre percent is between 0 and 100.
+ */
+
+// --- AppTimezone (backend/src/core/timezone.py)
+/**!
+ * @brief Application-level timezone utilities. Reads APP_TIMEZONE from env (default Europe/Moscow)
+ */
+
+// --- _get_default_tz_name (backend/src/core/timezone.py)
+/**!
+ * @brief Read APP_TIMEZONE from env, fall back to Europe/Moscow.
+ * @post Returns a valid IANA timezone string.
+ * @pre Environment is loaded (dotenv or os.environ).
+ */
+
+// --- get_app_timezone (backend/src/core/timezone.py)
+/**!
+ * @brief Return cached ZoneInfo for the configured application timezone.
+ * @post Returns a ZoneInfo instance matching APP_TIMEZONE env var.
+ */
+
+// --- invalidate_timezone_cache (backend/src/core/timezone.py)
+/**!
+ * @brief Reset the cached ZoneInfo so the next get_app_timezone() call re-reads from env/DB.
+ * @post _APP_TZ_CACHE is set to None; subsequent get_app_timezone() will re-resolve.
+ */
+
+// --- validate_timezone (backend/src/core/timezone.py)
+/**!
+ * @brief Validate that a timezone string is a known IANA timezone.
+ * @post Returns True if ZoneInfo accepts the name, False otherwise.
+ * @pre tz_name is a string.
+ */
+
+// --- localize (backend/src/core/timezone.py)
+/**!
+ * @brief Convert a timezone-aware or naive UTC datetime to the configured app timezone.
+ * @post Returns a datetime with the app timezone attached (astimezone).
+ * @pre If dt is timezone-naive, it is assumed to be UTC.
+ */
+
+// --- now (backend/src/core/timezone.py)
+/**!
+ * @brief Get current time in the configured application timezone.
+ * @post Returns timezone-aware datetime in the app timezone.
+ */
+
+// --- format_timezone_offset (backend/src/core/timezone.py)
+/**!
+ * @brief Return the UTC offset string for the configured timezone (e.g. "+03:00").
+ * @post Returns string like "+03:00" or "+00:00".
+ */
+
+// --- CoreUtils (backend/src/core/utils/__init__.py)
+/**!
+ * @brief Shared utility package root.
+ */
+
+// --- AsyncAPIClient.__init__ (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Initialize async API client for one environment.
+ * @post Client is ready for async request/authentication flow.
+ * @pre config contains base_url and auth payload.
+ */
+
+// --- AsyncAPIClient._normalize_base_url (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Normalize base URL for Superset API root construction.
+ * @post Returns canonical base URL without trailing slash and duplicate /api/v1 suffix.
+ */
+
+// --- AsyncAPIClient._build_api_url (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Build full API URL from relative Superset endpoint.
+ * @post Returns absolute URL for upstream request.
+ */
+
+// --- AsyncAPIClient._get_auth_lock (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Return per-cache-key async lock to serialize fresh login attempts.
+ * @post Returns stable asyncio.Lock instance.
+ */
+
+// --- AsyncAPIClient.authenticate (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Authenticate against Superset and cache access/csrf tokens.
+ * @post Client tokens are populated and reusable across requests.
+ */
+
+// --- AsyncAPIClient.get_headers (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Return authenticated Superset headers for async requests.
+ * @post Headers include Authorization and CSRF tokens.
+ */
+
+// --- AsyncAPIClient._is_dashboard_endpoint (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+ * @post Returns true only for dashboard-specific endpoints.
+ */
+
+// --- AsyncAPIClient._handle_network_error (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Translate generic httpx errors into NetworkError.
+ * @post Raises NetworkError with URL context.
+ */
+
+// --- AsyncAPIClient.aclose (backend/src/core/utils/async_network.py)
+/**!
+ * @brief Close underlying httpx client.
+ * @post Client resources are released.
+ */
+
+// --- DatasetMapperModule (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Этот модуль отвечает за обновление метаданных (verbose_name) в датасетах Superset,
+ */
+
+// --- DatasetMapper (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Класс для маппинга и обновления verbose_name в датасетах Superset.
+ */
+
+// --- get_sqllab_mappings (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Извлекает маппинги column_name -> verbose_name через SQL Lab Superset.
+ * @post Возвращается словарь column_name -> verbose_name из результатов SQL-запроса.
+ * @pre dataset_id должен существовать в Superset.
+ */
+
+// --- load_excel_mappings (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Загружает маппинги column_name -> verbose_name из XLSX файла.
+ * @param file_path (str) - Путь к XLSX файлу.
+ * @post Возвращается словарь с маппингами из файла.
+ * @pre file_path должен указывать на существующий XLSX файл.
+ * @return Dict[str, str] - Словарь с маппингами.
+ */
+
+// --- run_mapping (backend/src/core/utils/dataset_mapper.py)
+/**!
+ * @brief Основная функция для выполнения маппинга и обновления verbose_name датасета в Superset.
+ * @param excel_path (Optional[str]) - Путь к XLSX файлу.
+ * @post Если найдены изменения, датасет в Superset обновлен через API.
+ * @pre dataset_id должен быть существующим ID в Superset.
+ */
+
+// --- FileIO (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Предоставляет набор утилит для управления файловыми операциями, включая работу с временными файлами, архивами ZIP, файлами YAML и очистку директорий.
+ */
+
+// --- InvalidZipFormatError (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Exception raised when a file is not a valid ZIP archive.
+ */
+
+// --- create_temp_file (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Контекстный менеджер для создания временного файла или директории с гарантированным удалением.
+ * @post Временный ресурс создан и путь к нему возвращен; ресурс удален после выхода из контекста.
+ * @pre suffix должен быть строкой, определяющей тип ресурса.
+ */
+
+// --- remove_empty_directories (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Рекурсивно удаляет все пустые поддиректории, начиная с указанного пути.
+ * @post Все пустые поддиректории удалены, возвращено их количество.
+ * @pre root_dir должен быть путем к существующей директории.
+ */
+
+// --- read_dashboard_from_disk (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Читает бинарное содержимое файла с диска.
+ * @post Возвращает байты содержимого и имя файла.
+ * @pre file_path должен указывать на существующий файл.
+ */
+
+// --- calculate_crc32 (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Вычисляет контрольную сумму CRC32 для файла.
+ * @post Возвращает 8-значную hex-строку CRC32.
+ * @pre file_path должен быть объектом Path к существующему файлу.
+ */
+
+// --- RetentionPolicy (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Определяет политику хранения для архивов (ежедневные, еженедельные, ежемесячные).
+ */
+
+// --- archive_exports (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Управляет архивом экспортированных файлов, применяя политику хранения и дедупликацию.
+ * @post Старые или дублирующиеся архивы удалены согласно политике.
+ * @pre output_dir должен быть путем к существующей директории.
+ */
+
+// --- apply_retention_policy (backend/src/core/utils/fileio.py)
+/**!
+ * @brief (Helper) Применяет политику хранения к списку файлов, возвращая те, что нужно сохранить.
+ * @post Returns a set of files to keep.
+ * @pre files_with_dates is a list of (Path, date) tuples.
+ */
+
+// --- save_and_unpack_dashboard (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Сохраняет бинарное содержимое ZIP-архива на диск и опционально распаковывает его.
+ * @post ZIP-файл сохранен, и если unpack=True, он распакован в output_dir.
+ * @pre zip_content должен быть байтами валидного ZIP-архива.
+ */
+
+// --- update_yamls (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Обновляет конфигурации в YAML-файлах, заменяя значения или применяя regex.
+ * @post Все YAML файлы в директории обновлены согласно переданным параметрам.
+ * @pre path должен быть существующей директорией.
+ */
+
+// --- _update_yaml_file (backend/src/core/utils/fileio.py)
+/**!
+ * @brief (Helper) Обновляет один YAML файл.
+ * @post Файл обновлен согласно переданным конфигурациям или регулярному выражению.
+ * @pre file_path должен быть объектом Path к существующему YAML файлу.
+ */
+
+// --- replacer (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Функция замены, сохраняющая кавычки если они были.
+ * @post Возвращает строку с новым значением, сохраняя префикс и кавычки.
+ * @pre match должен быть объектом совпадения регулярного выражения.
+ */
+
+// --- create_dashboard_export (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Создает ZIP-архив из указанных исходных путей.
+ * @post ZIP-архив создан по пути zip_path.
+ * @pre source_paths должен содержать существующие пути.
+ */
+
+// --- sanitize_filename (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Очищает строку от символов, недопустимых в именах файлов.
+ * @post Возвращает строку без спецсимволов.
+ * @pre filename должен быть строкой.
+ */
+
+// --- get_filename_from_headers (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Извлекает имя файла из HTTP заголовка 'Content-Disposition'.
+ * @post Возвращает имя файла или None, если заголовок отсутствует.
+ * @pre headers должен быть словарем заголовков.
+ */
+
+// --- consolidate_archive_folders (backend/src/core/utils/fileio.py)
+/**!
+ * @brief Консолидирует директории архивов на основе общего слага в имени.
+ * @post Директории с одинаковым префиксом объединены в одну.
+ * @pre root_directory должен быть объектом Path к существующей директории.
+ */
+
+// --- FuzzyMatching (backend/src/core/utils/matching.py)
+/**!
+ * @brief Provides utility functions for fuzzy matching database names.
+ * @invariant Confidence scores are returned as floats between 0.0 and 1.0.
+ */
+
+// --- suggest_mappings (backend/src/core/utils/matching.py)
+/**!
+ * @brief Suggests mappings between source and target databases using fuzzy matching.
+ * @post Returns a list of suggested mappings with confidence scores.
+ * @pre source_databases and target_databases are lists of dictionaries with 'uuid' and 'database_name'.
+ */
+
+// --- NetworkModule (backend/src/core/utils/network.py)
+/**!
+ * @brief Инкапсулирует низкоуровневую HTTP-логику для взаимодействия с Superset API, включая аутентификацию, управление сессией, retry-логику и обработку ошибок.
+ */
+
+// --- SupersetAPIError (backend/src/core/utils/network.py)
+/**!
+ * @brief Base exception for all Superset API related errors.
+ */
+
+// --- AuthenticationError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when authentication fails.
+ */
+
+// --- PermissionDeniedError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when access is denied.
+ */
+
+// --- DashboardNotFoundError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when a dashboard cannot be found.
+ */
+
+// --- NetworkError (backend/src/core/utils/network.py)
+/**!
+ * @brief Exception raised when a network level error occurs.
+ */
+
+// --- NetworkError.__init__ (backend/src/core/utils/network.py)
+/**!
+ * @brief Initializes the network error.
+ * @post NetworkError is initialized.
+ * @pre message is a string.
+ */
+
+// --- SupersetAuthCache (backend/src/core/utils/network.py)
+/**!
+ * @brief Process-local cache for Superset access/csrf tokens keyed by environment credentials.
+ * @post Cached entries expire automatically by TTL and can be reused across requests.
+ * @pre base_url and username are stable strings.
+ */
+
+// --- SupersetAuthCache.get (backend/src/core/utils/network.py)
+/**!
+ */
+
+// --- SupersetAuthCache.set (backend/src/core/utils/network.py)
+/**!
+ */
+
+// --- APIClient (backend/src/core/utils/network.py)
+/**!
+ * @brief Synchronous Superset API client with process-local auth token caching.
+ */
+
+// --- APIClient.__init__ (backend/src/core/utils/network.py)
+/**!
+ * @brief Инициализирует API клиент с конфигурацией, сессией и логгером.
+ * @param timeout (int) - Таймаут запросов.
+ * @post APIClient instance is initialized with a session.
+ * @pre config must contain 'base_url' and 'auth'.
+ */
+
+// --- _init_session (backend/src/core/utils/network.py)
+/**!
+ * @brief Создает и настраивает `requests.Session` с retry-логикой.
+ * @post Returns a configured requests.Session instance.
+ * @pre self.request_settings must be initialized.
+ * @return requests.Session - Настроенная сессия.
+ */
+
+// --- _normalize_base_url (backend/src/core/utils/network.py)
+/**!
+ * @brief Normalize Superset environment URL to base host/path without trailing slash and /api/v1 suffix.
+ */
+
+// --- _build_api_url (backend/src/core/utils/network.py)
+/**!
+ * @brief Build absolute Superset API URL for endpoint using canonical /api/v1 base.
+ * @post Returns full URL without accidental duplicate slashes.
+ * @pre endpoint is relative path or absolute URL.
+ * @return str
+ */
+
+// --- APIClient.authenticate (backend/src/core/utils/network.py)
+/**!
+ * @brief Выполняет аутентификацию в Superset API и получает access и CSRF токены.
+ * @post `self._tokens` заполнен, `self._authenticated` установлен в `True`.
+ * @pre self.auth and self.base_url must be valid.
+ * @return Dict[str, str] - Словарь с токенами.
+ */
+
+// --- headers (backend/src/core/utils/network.py)
+/**!
+ * @brief Возвращает HTTP-заголовки для аутентифицированных запросов.
+ * @post Returns headers including auth tokens.
+ * @pre APIClient is initialized and authenticated or can be authenticated.
+ */
+
+// --- request (backend/src/core/utils/network.py)
+/**!
+ * @brief Выполняет универсальный HTTP-запрос к API.
+ * @param raw_response (bool) - Возвращать ли сырой ответ.
+ * @post Returns response content or raw Response object.
+ * @pre method and endpoint must be strings.
+ * @return `requests.Response` если `raw_response=True`, иначе `dict`.
+ */
+
+// --- _handle_http_error (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Преобразует HTTP ошибки в кастомные исключения.
+ * @param endpoint (str) - Эндпоинт.
+ * @post Raises a specific SupersetAPIError or subclass.
+ * @pre e must be a valid HTTPError with a response.
+ */
+
+// --- _is_dashboard_endpoint (backend/src/core/utils/network.py)
+/**!
+ * @brief Determine whether an API endpoint represents a dashboard resource for 404 translation.
+ * @post Returns true only for dashboard-specific endpoints.
+ * @pre endpoint may be relative or absolute.
+ */
+
+// --- _handle_network_error (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Преобразует сетевые ошибки в `NetworkError`.
+ * @param url (str) - URL.
+ * @post Raises a NetworkError.
+ * @pre e must be a RequestException.
+ */
+
+// --- upload_file (backend/src/core/utils/network.py)
+/**!
+ * @brief Загружает файл на сервер через multipart/form-data.
+ * @param timeout (Optional[int]) - Таймаут.
+ * @post File is uploaded and response returned.
+ * @pre file_info must contain 'file_obj' and 'file_name'.
+ * @return Ответ API в виде словаря.
+ */
+
+// --- _perform_upload (backend/src/core/utils/network.py)
+/**!
+ * @brief (Helper) Выполняет POST запрос с файлом.
+ * @param timeout (Optional[int]) - Таймаут.
+ * @post POST request is performed and JSON response returned.
+ * @pre url, files, and headers must be provided.
+ * @return Dict - Ответ.
+ */
+
+// --- fetch_paginated_count (backend/src/core/utils/network.py)
+/**!
+ * @brief Получает общее количество элементов для пагинации.
+ * @param count_field (str) - Поле с количеством.
+ * @post Returns total count of items.
+ * @pre query_params must be a dictionary.
+ * @return int - Количество.
+ */
+
+// --- fetch_paginated_data (backend/src/core/utils/network.py)
+/**!
+ * @brief Автоматически собирает данные со всех страниц пагинированного эндпоинта.
+ * @param pagination_options (Dict[str, Any]) - Опции пагинации.
+ * @post Returns all items across all pages.
+ * @pre pagination_options must contain 'base_query', 'results_field'. 'total_count' is optional.
+ * @return List[Any] - Список данных.
+ */
+
+// --- SupersetCompilationAdapter (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Interact with Superset preview compilation and SQL Lab execution endpoints using the current approved execution context.
+ * @invariant The adapter never fabricates compiled SQL locally; preview truth is delegated to Superset only.
+ * @post preview and launch calls return Superset-originated artifacts or explicit errors.
+ * @pre effective template params and dataset execution reference are available.
+ */
+
+// --- SupersetCompilationAdapter.imports (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ */
+
+// --- PreviewCompilationPayload (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Typed preview payload for Superset-side compilation.
+ */
+
+// --- SqlLabLaunchPayload (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Typed SQL Lab payload for audited launch handoff.
+ */
+
+// --- SupersetCompilationAdapter.__init__ (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Bind adapter to one Superset environment and client instance.
+ */
+
+// --- SupersetCompilationAdapter._supports_client_method (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Detect explicitly implemented client capabilities without treating loose mocks as real methods.
+ */
+
+// --- SupersetCompilationAdapter.compile_preview (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Request Superset-side compiled SQL preview for the current effective inputs.
+ * @post returns a ready or failed preview artifact backed only by Superset-originated SQL or diagnostics.
+ * @pre dataset_id and effective inputs are available for the current session.
+ */
+
+// --- SupersetCompilationAdapter.mark_preview_stale (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Invalidate previous preview after mapping or value changes.
+ * @post preview status becomes stale without fabricating a replacement artifact.
+ * @pre preview is a persisted preview artifact or current in-memory snapshot.
+ */
+
+// --- SupersetCompilationAdapter.create_sql_lab_session (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Create the canonical audited execution session after all launch gates pass.
+ * @post returns one canonical SQL Lab session reference from Superset.
+ * @pre compiled_sql is Superset-originated and launch gates are already satisfied.
+ */
+
+// --- SupersetCompilationAdapter._request_superset_preview (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Request preview compilation through explicit client support backed by real Superset endpoints only.
+ * @post returns one normalized upstream compilation response including the chosen strategy metadata.
+ * @pre payload contains a valid dataset identifier and deterministic execution inputs for one preview attempt.
+ */
+
+// --- SupersetCompilationAdapter._request_sql_lab_session (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Probe supported SQL Lab execution surfaces and return the first successful response.
+ * @post returns the first successful SQL Lab execution response from Superset.
+ * @pre payload carries non-empty Superset-originated SQL and a preview identifier for the current launch.
+ */
+
+// --- SupersetCompilationAdapter._normalize_preview_response (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Normalize candidate Superset preview responses into one compiled-sql structure.
+ */
+
+// --- SupersetCompilationAdapter._dump_json (backend/src/core/utils/superset_compilation_adapter.py)
+/**!
+ * @brief Serialize Superset request payload deterministically for network transport.
+ */
+
+// --- SupersetContextExtractorPackage (backend/src/core/utils/superset_context_extractor/__init__.py)
+/**!
+ * @brief Recover dataset and dashboard context from Superset links while preserving explicit partial-recovery markers.
+ * @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+ * @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+ * @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+ */
+
+// --- SupersetContextExtractor (backend/src/core/utils/superset_context_extractor/__init__.py)
+/**!
+ * @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+ * @post extractor instance is ready to parse links against one Superset environment.
+ * @pre constructor receives a configured environment with a usable Superset base URL.
+ */
+
+// --- SupersetContextExtractorBase (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Base class and helpers for recovering dataset/dashboard context from Superset links with explicit partial-recovery markers.
+ * @invariant Partial recovery is surfaced explicitly and never misrepresented as fully confirmed context.
+ * @post Returns the best available recovered context with explicit provenance and partial-recovery markers when necessary.
+ * @pre Superset link or dataset reference must be parseable enough to resolve an environment-scoped target resource.
+ */
+
+// --- _base_imports (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ */
+
+// --- SupersetParsedContext (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Normalized output of Superset link parsing for session intake and recovery.
+ */
+
+// --- SupersetContextExtractorBase.__init__ (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Bind extractor to one Superset environment and client instance.
+ */
+
+// --- SupersetContextExtractorBase.build_recovery_summary (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Summarize recovered, partial, and unresolved context for session state and UX.
+ */
+
+// --- SupersetContextExtractorBase._extract_numeric_identifier (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a numeric identifier from a REST-like Superset URL path.
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_reference (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard id-or-slug reference from a Superset URL path.
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_permalink_key (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard permalink key from a Superset URL path.
+ */
+
+// --- SupersetContextExtractorBase._extract_dashboard_id_from_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a dashboard identifier from returned permalink state when present.
+ */
+
+// --- SupersetContextExtractorBase._extract_chart_id_from_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Extract a chart identifier from returned permalink state when dashboard id is absent.
+ */
+
+// --- SupersetContextExtractorBase._search_nested_numeric_key (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Recursively search nested dict/list payloads for the first numeric value under a candidate key set.
+ */
+
+// --- SupersetContextExtractorBase._decode_query_state (backend/src/core/utils/superset_context_extractor/_base.py)
+/**!
+ * @brief Decode query-string structures used by Superset URL state transport.
+ */
+
+// --- SupersetContextFiltersExtractMixin (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ * @brief Extract normalized imported filters from decoded Superset query state (native_filters, dataMask, native_filter_state, form_data).
+ */
+
+// --- _filters_imports (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ */
+
+// --- SupersetContextFiltersExtractMixin._extract_imported_filters (backend/src/core/utils/superset_context_extractor/_filters.py)
+/**!
+ * @brief Normalize imported filters from decoded query state without fabricating missing values.
+ */
+
+// --- SupersetContextParsingMixin (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Parse supported Superset URLs and recover canonical dataset/dashboard references for review-session intake.
+ */
+
+// --- _parsing_imports (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ */
+
+// --- SupersetContextParsingMixin.parse_superset_link (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Extract candidate identifiers and query state from supported Superset URLs.
+ * @post returns resolved dataset/dashboard context, preserving explicit partial-recovery state if some identifiers cannot be confirmed.
+ * @pre link is a non-empty Superset URL compatible with the configured environment.
+ */
+
+// --- SupersetContextParsingMixin._recover_dataset_binding_from_dashboard (backend/src/core/utils/superset_context_extractor/_parsing.py)
+/**!
+ * @brief Recover a dataset binding from resolved dashboard context while preserving explicit unresolved markers.
+ */
+
+// --- SupersetContextExtractorPII (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief PII redaction helpers for assistant-facing dataset-review context — mask emails, UUIDs, long digit strings, and mixed identifiers.
+ */
+
+// --- _pii_imports (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ */
+
+// --- mask_pii_value (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Redact likely sensitive identifiers while preserving structural hints for assistant-facing dataset-review context.
+ */
+
+// --- sanitize_imported_filter_for_assistant (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Build assistant-safe imported-filter payload with raw-value redaction metadata when sensitive tokens are detected.
+ */
+
+// --- _mask_sensitive_text (backend/src/core/utils/superset_context_extractor/_pii.py)
+/**!
+ * @brief Redact likely PII substrings from one string while preserving non-sensitive delimiters and token shape.
+ */
+
+// --- SupersetContextRecoveryMixin (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Recover imported filters from Superset parsed context and dashboard metadata.
+ */
+
+// --- _recovery_imports (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ */
+
+// --- SupersetContextRecoveryMixin.recover_imported_filters (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Build imported filter entries from URL state and Superset-side saved context.
+ * @post returns explicit recovered and partial filter entries with preserved provenance and confirmation requirements.
+ * @pre parsed_context comes from a successful Superset link parse for one environment.
+ */
+
+// --- SupersetContextRecoveryMixin._normalize_imported_filter_payload (backend/src/core/utils/superset_context_extractor/_recovery.py)
+/**!
+ * @brief Normalize one imported-filter payload with explicit provenance and confirmation state.
+ */
+
+// --- SupersetContextTemplatesMixin (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Deterministically detect runtime variables and Jinja references from dataset query-bearing fields without execution.
+ */
+
+// --- _templates_imports (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ */
+
+// --- SupersetContextTemplatesMixin.discover_template_variables (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Detect runtime variables and Jinja references from dataset query-bearing fields.
+ * @post returns deduplicated explicit variable records without executing Jinja or fabricating runtime values.
+ * @pre dataset_payload is a Superset dataset-detail style payload with query-bearing fields when available.
+ */
+
+// --- SupersetContextTemplatesMixin._collect_query_bearing_expressions (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Collect SQL and expression-bearing dataset fields for deterministic template-variable discovery.
+ */
+
+// --- SupersetContextTemplatesMixin._append_template_variable (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Append one deduplicated template-variable descriptor.
+ */
+
+// --- SupersetContextTemplatesMixin._extract_primary_jinja_identifier (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Extract a deterministic primary identifier from a Jinja expression without executing it.
+ */
+
+// --- SupersetContextTemplatesMixin._normalize_default_literal (backend/src/core/utils/superset_context_extractor/_templates.py)
+/**!
+ * @brief Normalize literal default fragments from template helper calls into JSON-safe values.
+ */
+
+// --- WsLogHandlerModule (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief WebSocket log handler module providing LogEntry DTO and WebSocketLogHandler for buffered log streaming.
+ */
+
+// --- WebSocketLogHandler (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Custom logging handler that captures log records into a fixed-capacity buffer for WebSocket streaming.
+ */
+
+// --- WebSocketLogHandler.__init__ (backend/src/core/ws_log_handler.py)
+/**!
+ */
+
+// --- WebSocketLogHandler.emit (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Captures a log record, formats it, and stores it in the buffer as a LogEntry.
+ */
+
+// --- WebSocketLogHandler.get_recent_logs (backend/src/core/ws_log_handler.py)
+/**!
+ * @brief Returns a list of recent log entries from the buffer.
+ */
+
+// --- AppDependencies (backend/src/dependencies.py)
+/**!
+ * @brief Provides shared instances to app and routers.
+ */
+
+// --- get_config_manager (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for ConfigManager.
+ * @post Returns shared ConfigManager instance.
+ * @pre Global config_manager must be initialized.
+ */
+
+// --- get_plugin_loader (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for PluginLoader.
+ * @post Returns shared PluginLoader instance.
+ * @pre Global plugin_loader must be initialized.
+ */
+
+// --- get_task_manager (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for TaskManager.
+ * @post Returns shared TaskManager instance.
+ * @pre Global task_manager must be initialized.
+ */
+
+// --- get_scheduler_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for SchedulerService.
+ * @post Returns shared SchedulerService instance.
+ * @pre Global scheduler_service must be initialized.
+ */
+
+// --- get_resource_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for ResourceService.
+ * @post Returns shared ResourceService instance.
+ * @pre Global resource_service must be initialized.
+ */
+
+// --- get_mapping_service (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for MappingService.
+ * @post Returns new MappingService instance.
+ * @pre Global config_manager must be initialized.
+ */
+
+// --- get_clean_release_repository (backend/src/dependencies.py)
+/**!
+ * @brief Legacy compatibility shim for CleanReleaseRepository.
+ * @post Returns a shared CleanReleaseRepository instance.
+ */
+
+// --- get_clean_release_facade (backend/src/dependencies.py)
+/**!
+ * @brief Dependency injector for CleanReleaseFacade.
+ * @post Returns a facade instance with a fresh DB session.
+ */
+
+// --- APIKeyPrincipal (backend/src/dependencies.py)
+/**!
+ * @brief Dataclass representing an authenticated API key principal for service-to-service auth.
+ */
+
+// --- require_api_key_or_jwt (backend/src/dependencies.py)
+/**!
+ * @brief Factory: creates a dependency that accepts either a valid API key (with permission check)
+ */
+
+// --- check_api_key_environment_scope (backend/src/dependencies.py)
+/**!
+ * @brief Check the request's API key environment scope against a target env_id. Raises 400 if mismatch.
+ */
+
+// --- get_api_key_principal (backend/src/dependencies.py)
+/**!
+ * @brief FastAPI dependency that reads X-API-Key header and returns APIKeyPrincipal or None.
+ * @post If valid key: returns APIKeyPrincipal; if no header: returns None; if invalid: raises 401.
+ * @pre X-API-Key header may be present in the request.
+ */
+
+// --- oauth2_scheme (backend/src/dependencies.py)
+/**!
+ * @brief OAuth2 password bearer scheme for token extraction (raises 401 on missing token).
+ */
+
+// --- oauth2_scheme_optional (backend/src/dependencies.py)
+/**!
+ * @brief Optional OAuth2 scheme — returns None instead of raising 401 when no token.
+ */
+
+// --- get_current_user (backend/src/dependencies.py)
+/**!
+ * @brief Dependency for retrieving currently authenticated user from a JWT.
+ * @post Returns User object if token is valid.
+ * @pre JWT token provided in Authorization header.
+ */
+
+// --- has_permission (backend/src/dependencies.py)
+/**!
+ * @brief Dependency for checking if the current user has a specific permission.
+ * @post Returns True if user has permission.
+ * @pre User is authenticated.
+ */
+
+// --- ModelsPackage (backend/src/models/__init__.py)
+/**!
+ * @brief Domain model package root.
+ */
+
+// --- TestCleanReleaseModels (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Contract testing for Clean Release models
+ */
+
+// --- test_release_candidate_valid (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a valid release candidate can be instantiated.
+ */
+
+// --- test_release_candidate_empty_id (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a release candidate with an empty ID is rejected.
+ */
+
+// --- test_enterprise_policy_valid (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a valid enterprise policy is accepted.
+ */
+
+// --- test_enterprise_policy_missing_prohibited (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that an enterprise policy without prohibited categories is rejected.
+ */
+
+// --- test_enterprise_policy_external_allowed (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that an enterprise policy allowing external sources is rejected.
+ */
+
+// --- test_manifest_count_mismatch (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify that a manifest with count mismatches is rejected.
+ */
+
+// --- test_compliant_run_validation (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify compliant run validation logic and mandatory stage checks.
+ */
+
+// --- test_report_validation (backend/src/models/__tests__/test_clean_release.py)
+/**!
+ * @brief Verify compliance report validation based on status and violation counts.
+ */
+
+// --- test_models (backend/src/models/__tests__/test_models.py)
+/**!
+ * @brief Unit tests for data models
+ */
+
+// --- test_environment_model (backend/src/models/__tests__/test_models.py)
+/**!
+ * @brief Tests that Environment model correctly stores values.
+ * @post Values are verified.
+ * @pre Environment class is available.
+ */
+
+// --- test_report_models (backend/src/models/__tests__/test_report_models.py)
+/**!
+ * @brief Unit tests for report Pydantic models and their validators
+ */
+
+// --- APIKeyModel (backend/src/models/api_key.py)
+/**!
+ * @brief SQLAlchemy model for API Key authentication — stores SHA-256 hash only, raw key shown once at creation.
+ * @invariant Raw key is NEVER stored — shown once at creation and discarded.
+ */
+
+// --- APIKey (backend/src/models/api_key.py)
+/**!
+ * @brief Stores API key metadata and SHA-256 hash for service-to-service authentication.
+ */
+
+// --- AssistantModels (backend/src/models/assistant.py)
+/**!
+ * @brief SQLAlchemy models for assistant audit trail and confirmation tokens.
+ * @invariant Assistant records preserve immutable ids and creation timestamps.
+ */
+
+// --- AssistantAuditRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Store audit decisions and outcomes produced by assistant command handling.
+ * @post Audit payload remains available for compliance and debugging.
+ * @pre user_id must identify the actor for every record.
+ */
+
+// --- AssistantMessageRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Persist chat history entries for assistant conversations.
+ * @post Message row can be queried in chronological order.
+ * @pre user_id, conversation_id, role and text must be present.
+ */
+
+// --- AssistantConfirmationRecord (backend/src/models/assistant.py)
+/**!
+ * @brief Persist risky operation confirmation tokens with lifecycle state.
+ * @post State transitions can be tracked and audited.
+ * @pre intent/dispatch and expiry timestamp must be provided.
+ */
+
+// --- AuthModels (backend/src/models/auth.py)
+/**!
+ * @brief SQLAlchemy models for multi-user authentication and authorization.
+ * @invariant Usernames and emails must be unique.
+ * @post Auth ORM models registered with unique constraints
+ * @pre Database engine initialized
+ */
+
+// --- generate_uuid (backend/src/models/auth.py)
+/**!
+ * @brief Generates a unique UUID string.
+ * @post Returns a string representation of a new UUID.
+ */
+
+// --- user_roles (backend/src/models/auth.py)
+/**!
+ * @brief Association table for many-to-many relationship between Users and Roles.
+ */
+
+// --- role_permissions (backend/src/models/auth.py)
+/**!
+ * @brief Association table for many-to-many relationship between Roles and Permissions.
+ */
+
+// --- Role (backend/src/models/auth.py)
+/**!
+ * @brief Represents a collection of permissions.
+ */
+
+// --- Permission (backend/src/models/auth.py)
+/**!
+ * @brief Represents a specific capability within the system.
+ */
+
+// --- ADGroupMapping (backend/src/models/auth.py)
+/**!
+ * @brief Maps an Active Directory group to a local System Role.
+ */
+
+// --- CleanReleaseModels (backend/src/models/clean_release.py)
+/**!
+ * @brief Define canonical clean release domain entities and lifecycle guards.
+ * @invariant Immutable snapshots are never mutated; forbidden lifecycle transitions are rejected.
+ * @post Provides SQLAlchemy and dataclass definitions for governance domain.
+ * @pre Base mapping model and release enums are available.
+ */
+
+// --- ExecutionMode (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible execution mode enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckFinalStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible final status enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageName (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage name enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage status enum for legacy TUI/orchestrator tests.
+ */
+
+// --- CheckStageResult (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible stage result container for legacy TUI/orchestrator tests.
+ */
+
+// --- ProfileType (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible profile enum for legacy TUI bootstrap logic.
+ */
+
+// --- RegistryStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible registry status enum for legacy TUI bootstrap logic.
+ */
+
+// --- ReleaseCandidateStatus (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible release candidate status enum for legacy TUI.
+ */
+
+// --- ResourceSourceEntry (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible source entry model for legacy TUI bootstrap logic.
+ */
+
+// --- ResourceSourceRegistry (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible source registry model for legacy TUI bootstrap logic.
+ */
+
+// --- CleanProfilePolicy (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible policy model for legacy TUI bootstrap logic.
+ */
+
+// --- ComplianceCheckRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible run model for legacy TUI typing/import compatibility.
+ */
+
+// --- ReleaseCandidate (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents the release unit being prepared and governed.
+ * @post status advances only through legal transitions.
+ * @pre id, version, source_snapshot_ref are non-empty.
+ */
+
+// --- CandidateArtifact (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents one artifact associated with a release candidate.
+ */
+
+// --- ManifestItem (backend/src/models/clean_release.py)
+/**!
+ */
+
+// --- ManifestSummary (backend/src/models/clean_release.py)
+/**!
+ */
+
+// --- DistributionManifest (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable snapshot of the candidate payload.
+ * @invariant Immutable after creation.
+ */
+
+// --- SourceRegistrySnapshot (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable registry snapshot for allowed sources.
+ */
+
+// --- CleanPolicySnapshot (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable policy snapshot used to evaluate a run.
+ */
+
+// --- ComplianceRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Operational record for one compliance execution.
+ */
+
+// --- ComplianceStageRun (backend/src/models/clean_release.py)
+/**!
+ * @brief Stage-level execution record inside a run.
+ */
+
+// --- ViolationSeverity (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible violation severity enum for legacy clean-release tests.
+ */
+
+// --- ViolationCategory (backend/src/models/clean_release.py)
+/**!
+ * @brief Backward-compatible violation category enum for legacy clean-release tests.
+ */
+
+// --- ComplianceViolation (backend/src/models/clean_release.py)
+/**!
+ * @brief Violation produced by a stage.
+ */
+
+// --- ComplianceReport (backend/src/models/clean_release.py)
+/**!
+ * @brief Immutable result derived from a completed run.
+ * @invariant Immutable after creation.
+ */
+
+// --- ApprovalDecision (backend/src/models/clean_release.py)
+/**!
+ * @brief Approval or rejection bound to a candidate and report.
+ */
+
+// --- PublicationRecord (backend/src/models/clean_release.py)
+/**!
+ * @brief Publication or revocation record.
+ */
+
+// --- CleanReleaseAuditLog (backend/src/models/clean_release.py)
+/**!
+ * @brief Represents a persistent audit log entry for clean release actions.
+ */
+
+// --- AppConfigRecord (backend/src/models/config.py)
+/**!
+ * @brief Stores persisted application configuration as a single authoritative record model.
+ * @post ORM table 'app_configurations' exposes id, payload, and updated_at fields with declared nullability/default semantics.
+ * @pre SQLAlchemy declarative Base is initialized and table metadata registration is active.
+ */
+
+// --- NotificationConfig (backend/src/models/config.py)
+/**!
+ * @brief Stores persisted provider-level notification configuration and encrypted credentials metadata.
+ * @post ORM table 'notification_configs' exposes id, type, name, credentials, is_active, created_at, updated_at fields with declared constraints/defaults.
+ * @pre SQLAlchemy declarative Base is initialized and uuid generation is available at instance creation time.
+ */
+
+// --- DashboardModels (backend/src/models/dashboard.py)
+/**!
+ * @brief Defines data models for dashboard metadata and selection.
+ */
+
+// --- DashboardMetadata (backend/src/models/dashboard.py)
+/**!
+ * @brief Represents a dashboard available for migration.
+ */
+
+// --- DashboardSelection (backend/src/models/dashboard.py)
+/**!
+ * @brief Represents the user's selection of dashboards to migrate.
+ */
+
+// --- DatasetReviewModels (backend/src/models/dataset_review.py)
+/**!
+ * @brief Thin facade re-exporting all dataset review domain models from the decomposed sub-package.
+ * @invariant All public model classes and enums remain importable from `src.models.dataset_review` without changes.
+ */
+
+// --- DatasetReviewClarificationModels (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief Clarification session, question, option, and answer models for guided review flow.
+ * @invariant Only one active clarification question may exist at a time per session.
+ * @post Clarification ORM models registered
+ * @pre Database engine initialized
+ */
+
+// --- ClarificationSession (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One clarification session aggregate owning questions and tracking resolution progress.
+ */
+
+// --- ClarificationQuestion (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One clarification question with priority ordering, options, and state machine.
+ */
+
+// --- ClarificationOption (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One selectable option for a clarification question with recommendation flag.
+ */
+
+// --- ClarificationAnswer (backend/src/models/dataset_review_pkg/_clarification_models.py)
+/**!
+ * @brief One persisted clarification answer with impact summary and feedback tracking.
+ */
+
+// --- DatasetReviewEnums (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief All enumeration types for the dataset review domain, grouped for stable cross-module reuse.
+ * @invariant Enum values are string-based for JSON serialization compatibility.
+ */
+
+// --- SessionStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status of a dataset review session.
+ */
+
+// --- SessionPhase (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Ordered phase progression for dataset review orchestration.
+ */
+
+// --- ReadinessState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Granular readiness indicator driving the recommended-action UX flow.
+ */
+
+// --- RecommendedAction (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Next-action guidance derived from the current readiness state.
+ */
+
+// --- SessionCollaboratorRole (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief RBAC role for session collaborators.
+ */
+
+// --- BusinessSummarySource (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Provenance of the dataset business summary text.
+ */
+
+// --- ConfidenceState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Confidence level for dataset profile completeness.
+ */
+
+// --- FindingArea (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Domain area classification for validation findings.
+ */
+
+// --- FindingSeverity (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Severity classification for validation findings.
+ */
+
+// --- ResolutionState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Resolution status for validation findings and clarification items.
+ */
+
+// --- SemanticSourceType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Classification of semantic enrichment source origins.
+ */
+
+// --- TrustLevel (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Trust classification for semantic source reliability.
+ */
+
+// --- SemanticSourceStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for semantic source application.
+ */
+
+// --- FieldKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Kind classification for semantic field entries.
+ */
+
+// --- FieldProvenance (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Provenance tracking for semantic field value origin.
+ */
+
+// --- CandidateMatchType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Match type classification for semantic candidates.
+ */
+
+// --- CandidateStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for semantic candidate proposals.
+ */
+
+// --- FilterSource (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Origin classification for imported filters.
+ */
+
+// --- FilterConfidenceState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Confidence classification for imported filter values.
+ */
+
+// --- FilterRecoveryStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Recovery quality status for imported filters.
+ */
+
+// --- VariableKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Kind classification for template variables.
+ */
+
+// --- MappingStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for template variable mapping.
+ */
+
+// --- MappingMethod (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Method classification for execution mapping creation.
+ */
+
+// --- MappingWarningLevel (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Warning severity for execution mapping quality indicators.
+ */
+
+// --- ApprovalState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Approval lifecycle for execution mapping gate checks.
+ */
+
+// --- ClarificationStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for clarification sessions.
+ */
+
+// --- QuestionState (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief State machine for individual clarification questions.
+ */
+
+// --- AnswerKind (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Classification of clarification answer types.
+ */
+
+// --- PreviewStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Lifecycle status for compiled SQL previews.
+ */
+
+// --- LaunchStatus (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Outcome status for dataset launch handoff.
+ */
+
+// --- ArtifactType (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Type classification for export artifacts.
+ */
+
+// --- ArtifactFormat (backend/src/models/dataset_review_pkg/_enums.py)
+/**!
+ * @brief Format classification for export artifact output.
+ */
+
+// --- DatasetReviewExecutionModels (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief Compiled preview, run context, session event, and export artifact models for execution and audit.
+ */
+
+// --- CompiledPreview (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One compiled SQL preview snapshot with fingerprint for staleness detection.
+ */
+
+// --- DatasetRunContext (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief Immutable launch audit snapshot capturing effective filters, template params, and approval state at launch time.
+ */
+
+// --- SessionEvent (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One persisted audit event for dataset review session mutations.
+ */
+
+// --- ExportArtifact (backend/src/models/dataset_review_pkg/_execution_models.py)
+/**!
+ * @brief One persisted export artifact reference for documentation and validation outputs.
+ */
+
+// --- DatasetReviewFilterModels (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Imported filter and template variable models for Superset context recovery and execution mapping.
+ */
+
+// --- ImportedFilter (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Recovered Superset filter with confidence and recovery status tracking.
+ */
+
+// --- TemplateVariable (backend/src/models/dataset_review_pkg/_filter_models.py)
+/**!
+ * @brief Discovered template variable from dataset SQL with mapping status tracking.
+ */
+
+// --- DatasetReviewFindingModels (backend/src/models/dataset_review_pkg/_finding_models.py)
+/**!
+ * @brief Validation finding model for tracking blocking, warning, and informational issues during review.
+ */
+
+// --- ValidationFinding (backend/src/models/dataset_review_pkg/_finding_models.py)
+/**!
+ * @brief Structured finding record for dataset review validation issues with resolution tracking.
+ */
+
+// --- DatasetReviewMappingModels (backend/src/models/dataset_review_pkg/_mapping_models.py)
+/**!
+ * @brief Execution mapping model linking imported filters to template variables with approval gates.
+ */
+
+// --- ExecutionMapping (backend/src/models/dataset_review_pkg/_mapping_models.py)
+/**!
+ * @brief One filter-to-variable mapping with approval gate, effective value, and transformation metadata.
+ * @invariant Explicit approval is required before launch when requires_explicit_approval is true.
+ */
+
+// --- DatasetReviewProfileModels (backend/src/models/dataset_review_pkg/_profile_models.py)
+/**!
+ * @brief Dataset profile model capturing business summary, confidence, and completeness metadata.
+ */
+
+// --- DatasetProfile (backend/src/models/dataset_review_pkg/_profile_models.py)
+/**!
+ * @brief One-to-one profile snapshot for a dataset review session, tracking business summary provenance and completeness.
+ */
+
+// --- DatasetReviewSemanticModels (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Semantic source, field entry, and candidate models for dictionary-driven semantic enrichment.
+ * @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+ * @post Semantic ORM models registered with override protection
+ * @pre Database engine initialized
+ */
+
+// --- SemanticSource (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Registered semantic enrichment source with trust level and application status.
+ */
+
+// --- SemanticFieldEntry (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief Per-field semantic metadata entry with provenance tracking, lock state, and candidate set.
+ * @invariant Locked fields preserve their active value regardless of later candidate proposals.
+ */
+
+// --- SemanticCandidate (backend/src/models/dataset_review_pkg/_semantic_models.py)
+/**!
+ * @brief One proposed semantic value for a field entry, ranked by match type and confidence.
+ */
+
+// --- DatasetReviewSessionModels (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief Session aggregate root and collaborator models for dataset review orchestration.
+ * @invariant Session and profile entities are strictly scoped to an authenticated user.
+ * @post Session ORM models registered with optimistic locking
+ * @pre Database engine initialized
+ */
+
+// --- SessionCollaborator (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief RBAC collaborator record linking a user to a dataset review session with a specific role.
+ */
+
+// --- DatasetReviewSession (backend/src/models/dataset_review_pkg/_session_models.py)
+/**!
+ * @brief Aggregate root for the dataset review lifecycle, owning all child entities and driving readiness transitions.
+ * @invariant Optimistic-lock version column prevents lost-update races on concurrent mutations.
+ */
+
+// --- FilterStateModels (backend/src/models/filter_state.py)
+/**!
+ * @brief Pydantic models for Superset native filter state extraction and restoration.
+ */
+
+// --- FilterState (backend/src/models/filter_state.py)
+/**!
+ * @brief Represents the state of a single native filter.
+ */
+
+// --- NativeFilterDataMask (backend/src/models/filter_state.py)
+/**!
+ * @brief Represents the dataMask containing all native filter states.
+ */
+
+// --- ParsedNativeFilters (backend/src/models/filter_state.py)
+/**!
+ * @brief Result of parsing native filters from permalink or native_filters_key.
+ */
+
+// --- DashboardURLFilterExtraction (backend/src/models/filter_state.py)
+/**!
+ * @brief Result of parsing a complete dashboard URL for filter information.
+ */
+
+// --- ExtraFormDataMerge (backend/src/models/filter_state.py)
+/**!
+ * @brief Configuration for merging extraFormData from different sources.
+ */
+
+// --- GitModels (backend/src/models/git.py)
+/**!
+ */
+
+// --- GitServerConfig (backend/src/models/git.py)
+/**!
+ * @brief Configuration for a Git server connection.
+ */
+
+// --- GitRepository (backend/src/models/git.py)
+/**!
+ * @brief Tracking for a local Git repository linked to a dashboard.
+ */
+
+// --- DeploymentEnvironment (backend/src/models/git.py)
+/**!
+ * @brief Target Superset environments for dashboard deployment.
+ */
+
+// --- LlmModels (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy models for LLM provider configuration and validation results.
+ */
+
+// --- ValidationPolicy (backend/src/models/llm.py)
+/**!
+ * @brief Defines a scheduled rule for validating a group of dashboards within an execution window.
+ */
+
+// --- LLMProvider (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy model for LLM provider configuration.
+ */
+
+// --- ValidationRecord (backend/src/models/llm.py)
+/**!
+ * @brief SQLAlchemy model for dashboard validation history.
+ */
+
+// --- MaintenanceModels (backend/src/models/maintenance.py)
+/**!
+ * @brief SQLAlchemy models for the Maintenance Banner feature: event, banner, dashboard state, and settings.
+ * @invariant MaintenanceSettings is a singleton row (id='default') enforced by CheckConstraint
+ */
+
+// --- MaintenanceEventStatus (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- MaintenanceDashboardBannerStatus (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- MaintenanceDashboardStateStatus (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- DashboardScope (backend/src/models/maintenance.py)
+/**!
+ */
+
+// --- MaintenanceEvent (backend/src/models/maintenance.py)
+/**!
+ * @brief A record of a maintenance event with table list, time window, status, and linked dashboard states.
+ */
+
+// --- MaintenanceDashboardBanner (backend/src/models/maintenance.py)
+/**!
+ * @brief The canonical "one chart per dashboard" entity. Unique partial index enforces single active banner per dashboard.
+ * @invariant Unique partial index (environment_id, dashboard_id) WHERE status='active'
+ */
+
+// --- MaintenanceDashboardState (backend/src/models/maintenance.py)
+/**!
+ * @brief Links a maintenance event to a dashboard via a banner. Tracks per-dashboard-per-event lifecycle.
+ */
+
+// --- MaintenanceSettings (backend/src/models/maintenance.py)
+/**!
+ * @brief Single-row maintenance mode configuration. Enforces singleton via CheckConstraint(id='default').
+ * @invariant id must always be 'default' — enforced by CheckConstraint
+ */
+
+// --- MappingModels (backend/src/models/mapping.py)
+/**!
+ * @brief Defines the database schema for environment metadata and database mappings using SQLAlchemy.
+ * @invariant All primary keys are UUID strings.
+ */
+
+// --- Base (backend/src/models/mapping.py)
+/**!
+ * @brief SQLAlchemy declarative base for all domain models.
+ */
+
+// --- ResourceType (backend/src/models/mapping.py)
+/**!
+ * @brief Enumeration of possible Superset resource types for ID mapping.
+ */
+
+// --- MigrationStatus (backend/src/models/mapping.py)
+/**!
+ * @brief Enumeration of possible migration job statuses.
+ */
+
+// --- MigrationJob (backend/src/models/mapping.py)
+/**!
+ * @brief Represents a single migration execution job.
+ */
+
+// --- ResourceMapping (backend/src/models/mapping.py)
+/**!
+ * @brief Maps a universal UUID for a resource to its actual ID on a specific environment.
+ */
+
+// --- ProfileModels (backend/src/models/profile.py)
+/**!
+ * @brief Defines persistent per-user profile settings for dashboard filter, Git identity/token, and UX preferences.
+ * @invariant Sensitive Git token is stored encrypted and never returned in plaintext.
+ * @post Profile ORM models registered
+ * @pre Database engine initialized
+ */
+
+// --- UserDashboardPreference (backend/src/models/profile.py)
+/**!
+ * @brief Stores Superset username binding and default "my dashboards" toggle for one authenticated user.
+ */
+
+// --- ReportModels (backend/src/models/report.py)
+/**!
+ * @brief Canonical report schemas for unified task reporting across heterogeneous task types.
+ * @invariant Canonical report fields are always present for every report item.
+ * @post Provides validated schemas for cross-plugin reporting and UI consumption.
+ * @pre Pydantic library and task manager models are available.
+ */
+
+// --- TaskType (backend/src/models/report.py)
+/**!
+ * @brief Supported normalized task report types.
+ * @invariant Must contain valid generic task type mappings.
+ */
+
+// --- ReportStatus (backend/src/models/report.py)
+/**!
+ * @brief Supported normalized report status values.
+ * @invariant TaskStatus enum mapping logic holds.
+ */
+
+// --- ErrorContext (backend/src/models/report.py)
+/**!
+ * @brief Error and recovery context for failed/partial reports.
+ * @invariant The properties accurately describe error state.
+ */
+
+// --- TaskReport (backend/src/models/report.py)
+/**!
+ * @brief Canonical normalized report envelope for one task execution.
+ * @invariant Must represent canonical task record attributes.
+ */
+
+// --- ReportQuery (backend/src/models/report.py)
+/**!
+ * @brief Query object for server-side report filtering, sorting, and pagination.
+ * @invariant Time and pagination queries are mutually consistent.
+ */
+
+// --- ReportCollection (backend/src/models/report.py)
+/**!
+ * @brief Paginated collection of normalized task reports.
+ * @invariant Represents paginated data correctly.
+ */
+
+// --- ReportDetailView (backend/src/models/report.py)
+/**!
+ * @brief Detailed report representation including diagnostics and recovery actions.
+ * @invariant Incorporates a report and logs correctly.
+ */
+
+// --- StorageModels (backend/src/models/storage.py)
+/**!
+ */
+
+// --- FileCategory (backend/src/models/storage.py)
+/**!
+ * @brief Enumeration of supported file categories in the storage system.
+ */
+
+// --- StorageConfig (backend/src/models/storage.py)
+/**!
+ * @brief Configuration model for the storage system, defining paths and naming patterns.
+ */
+
+// --- StoredFile (backend/src/models/storage.py)
+/**!
+ * @brief Data model representing metadata for a file stored in the system.
+ */
+
+// --- TaskModels (backend/src/models/task.py)
+/**!
+ * @brief Defines the database schema for task execution records.
+ * @invariant All primary keys are UUID strings.
+ */
+
+// --- TaskRecord (backend/src/models/task.py)
+/**!
+ * @brief Represents a persistent record of a task execution.
+ */
+
+// --- TaskLogRecord (backend/src/models/task.py)
+/**!
+ * @brief Represents a single persistent log entry for a task.
+ * @invariant Each log entry belongs to exactly one task.
+ */
+
+// --- TranslateModels (backend/src/models/translate.py)
+/**!
+ * @brief SQLAlchemy ORM models for LLM-based SQL/dashboard translation across dialects.
+ */
+
+// --- TranslationJob (backend/src/models/translate.py)
+/**!
+ * @brief A translation job representing a multi-dialect conversion task with column mappings, LLM config, and dictionary attachments.
+ */
+
+// --- TranslationRun (backend/src/models/translate.py)
+/**!
+ * @brief Represents a single execution of a translation job, capturing status, timing, and Superset execution metadata.
+ */
+
+// --- TranslationBatch (backend/src/models/translate.py)
+/**!
+ * @brief Groups translation records within a run into manageable batches with timing and record counts.
+ */
+
+// --- TranslationRecord (backend/src/models/translate.py)
+/**!
+ * @brief Individual translation result for a single SQL statement or dashboard element, tracking source, target, and error state.
+ */
+
+// --- TranslationEvent (backend/src/models/translate.py)
+/**!
+ * @brief Audit/event log for translation operations, with optional run_id for context.
+ */
+
+// --- TranslationPreviewSession (backend/src/models/translate.py)
+/**!
+ * @brief A preview session allowing users to review proposed translations before applying them.
+ */
+
+// --- TranslationPreviewRecord (backend/src/models/translate.py)
+/**!
+ * @brief Individual preview entry within a preview session, showing original and translated content side by side.
+ */
+
+// --- TerminologyDictionary (backend/src/models/translate.py)
+/**!
+ * @brief A named collection of terminology mappings used during translation to ensure consistent term translation.
+ */
+
+// --- DictionaryEntry (backend/src/models/translate.py)
+/**!
+ * @brief A single term mapping entry with case-insensitive unique constraint on source_term_normalized and origin tracking.
+ */
+
+// --- TranslationSchedule (backend/src/models/translate.py)
+/**!
+ * @brief Defines a cron-based schedule for recurring translation jobs.
+ */
+
+// --- TranslationJobDictionary (backend/src/models/translate.py)
+/**!
+ * @brief Many-to-many association between translation jobs and terminology dictionaries.
+ */
+
+// --- MetricSnapshot (backend/src/models/translate.py)
+/**!
+ * @brief Captures translation performance metrics at a point in time with config/content/dictionary hash keys for aggregation.
+ */
+
+// --- TranslationLanguage (backend/src/models/translate.py)
+/**!
+ * @brief Per-language translation result for a single record, supporting multi-language output.
+ */
+
+// --- TranslationPreviewLanguage (backend/src/models/translate.py)
+/**!
+ * @brief Per-language preview entry within a preview session.
+ */
+
+// --- TranslationRunLanguageStats (backend/src/models/translate.py)
+/**!
+ * @brief Per-language statistics for a translation run (row counts, tokens, cost).
+ */
+
+// --- src.plugins (backend/src/plugins/__init__.py)
+/**!
+ * @brief Plugin package root for dynamic discovery and runtime imports.
+ */
+
+// --- BackupPlugin (backend/src/plugins/backup.py)
+/**!
+ * @brief A plugin that provides functionality to back up Superset dashboards.
+ */
+
+// --- DebugPluginModule (backend/src/plugins/debug.py)
+/**!
+ * @brief Plugin for diagnostics. Inherits PluginBase.
+ */
+
+// --- DebugPlugin (backend/src/plugins/debug.py)
+/**!
+ * @brief Plugin for system diagnostics and debugging.
+ */
+
+// --- GitPluginExt (backend/src/plugins/git/__init__.py)
+/**!
+ * @brief Git plugin extension package root.
+ */
+
+// --- GitLLMExtensionModule (backend/src/plugins/git/llm_extension.py)
+/**!
+ * @brief LLM-based extensions for the Git plugin, specifically for commit message generation.
+ */
+
+// --- GitLLMExtension (backend/src/plugins/git/llm_extension.py)
+/**!
+ * @brief Provides LLM capabilities to the Git plugin.
+ */
+
+// --- GitPluginModule (backend/src/plugins/git_plugin.py)
+/**!
+ * @brief Предоставляет плагин для версионирования и развертывания дашбордов Superset.
+ * @invariant _handle_sync сохраняет backup управляемых директорий перед удалением;
+ */
+
+// --- GitPlugin (backend/src/plugins/git_plugin.py)
+/**!
+ * @brief Реализация плагина Git Integration для управления версиями дашбордов.
+ */
+
+// --- LLMAnalysisPackage (backend/src/plugins/llm_analysis/__init__.py)
+/**!
+ */
+
+// --- LLMAnalysisModels (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Define Pydantic models for LLM Analysis plugin.
+ */
+
+// --- LLMProviderType (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Enum for supported LLM providers.
+ */
+
+// --- LLMProviderConfig (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Configuration for an LLM provider.
+ */
+
+// --- ValidationStatus (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Enum for dashboard validation status.
+ */
+
+// --- DetectedIssue (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Model for a single issue detected during validation.
+ */
+
+// --- ValidationResult (backend/src/plugins/llm_analysis/models.py)
+/**!
+ * @brief Model for dashboard validation result.
+ */
+
+// --- LLMAnalysisPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Implements DashboardValidationPlugin and DocumentationPlugin.
+ * @invariant All LLM interactions must be executed as asynchronous tasks.
+ */
+
+// --- _is_masked_or_invalid_api_key (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Guards against placeholder or malformed API keys in runtime.
+ * @post Returns True when value cannot be used for authenticated provider calls.
+ * @pre value may be None.
+ */
+
+// --- _json_safe_value (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Recursively normalize payload values for JSON serialization.
+ * @post datetime values are converted to ISO strings.
+ * @pre value may be nested dict/list with datetime values.
+ */
+
+// --- DashboardValidationPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Plugin for automated dashboard health analysis using LLMs.
+ */
+
+// --- DocumentationPlugin (backend/src/plugins/llm_analysis/plugin.py)
+/**!
+ * @brief Plugin for automated dataset documentation using LLMs.
+ */
+
+// --- LLMAnalysisScheduler (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Provides helper functions to schedule LLM-based validation tasks.
+ */
+
+// --- schedule_dashboard_validation (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Schedules a recurring dashboard validation task.
+ */
+
+// --- _parse_cron (backend/src/plugins/llm_analysis/scheduler.py)
+/**!
+ * @brief Basic cron parser placeholder.
+ */
+
+// --- LLMAnalysisService (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Services for LLM interaction and dashboard screenshots.
+ * @invariant Screenshots must be 1920px width and capture full page height.
+ */
+
+// --- ScreenshotService (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Handles capturing screenshots of Superset dashboards.
+ */
+
+// --- LLMClient (backend/src/plugins/llm_analysis/service.py)
+/**!
+ * @brief Wrapper for LLM provider APIs.
+ */
+
+// --- MaintenanceBannerPlugin (backend/src/plugins/maintenance_banner.py)
+/**!
+ * @brief TaskManager plugin for executing maintenance banner operations (start, end, end-all).
+ */
+
+// --- MapperPluginModule (backend/src/plugins/mapper.py)
+/**!
+ * @brief Plugin for dataset column mapping. Inherits PluginBase.
+ */
+
+// --- MapperPlugin (backend/src/plugins/mapper.py)
+/**!
+ * @brief Plugin for mapping dataset columns verbose names.
+ */
+
+// --- MigrationPlugin (backend/src/plugins/migration.py)
+/**!
+ * @brief Orchestrates export, DB-mapping transformation, and import of Superset dashboards across environments.
+ * @invariant Dashboards must never be imported with unmapped/source DB connections to prevent data leaks or cross-environment pollution.
+ * @post Plugin metadata remains stable and migration execution preserves mapped-environment import guarantees.
+ * @pre Plugin loader can resolve infrastructure dependencies and execution requests provide validated migration context.
+ */
+
+// --- SearchPluginModule (backend/src/plugins/search.py)
+/**!
+ * @brief Plugin for text search across datasets. Inherits PluginBase.
+ */
+
+// --- SearchPlugin (backend/src/plugins/search.py)
+/**!
+ * @brief Plugin for searching text patterns in Superset datasets.
+ */
+
+// --- StoragePluginPackage (backend/src/plugins/storage/__init__.py)
+/**!
+ */
+
+// --- StoragePlugin (backend/src/plugins/storage/plugin.py)
+/**!
+ * @brief Provides core filesystem operations for managing backups and repositories.
+ * @invariant All file operations must be restricted to the configured storage root.
+ */
+
+// --- TranslatePluginPackage (backend/src/plugins/translate/__init__.py)
+/**!
+ */
+
+// --- TestClickHouseTimestampNormalization (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify Unix timestamp detection and conversion for ClickHouse Date columns.
+ */
+
+// --- TestClickHouseInsertSqlGeneration (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify SQLGenerator produces valid ClickHouse INSERT SQL with normalized dates.
+ */
+
+// --- TestClickHouseJoinVerification (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify the JOIN query SQL is syntactically correct for ClickHouse.
+ */
+
+// --- TestOrchestratorInsertFlow (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief Verify the orchestrator's _generate_and_insert_sql produces correct SQL for ClickHouse.
+ */
+
+// --- TestClickHouseEndToEnd (backend/src/plugins/translate/__tests__/test_clickhouse_insert_integration.py)
+/**!
+ * @brief End-to-end test: generate SQL, verify structure, simulate execution.
+ */
+
+// --- TestDictionaryLegacyHub (backend/src/plugins/translate/__tests__/test_dictionary.py)
+/**!
+ * @brief Legacy test module — all tests migrated to domain-specific test files:
+ */
+
+// --- TestDictionaryCorrection (backend/src/plugins/translate/__tests__/test_dictionary_correction.py)
+/**!
+ * @brief Validate InlineCorrectionService and dictionary correction flows.
+ */
+
+// --- TestDictionaryCRUD (backend/src/plugins/translate/__tests__/test_dictionary_crud.py)
+/**!
+ * @brief Validate DictionaryCRUD and DictionaryEntryCRUD operations.
+ */
+
+// --- TestDictionaryFilter (backend/src/plugins/translate/__tests__/test_dictionary_filter.py)
+/**!
+ * @brief Validate DictionaryBatchFilter operations.
+ */
+
+// --- TestDictionaryImport (backend/src/plugins/translate/__tests__/test_dictionary_import.py)
+/**!
+ * @brief Validate DictionaryImportExport operations.
+ */
+
+// --- TestDictionaryPromptBuilder (backend/src/plugins/translate/__tests__/test_dictionary_prompt_builder.py)
+/**!
+ * @brief Validate ContextAwarePromptBuilder operations: Jaccard similarity, context truncation, entry rendering.
+ */
+
+// --- TestDictionaryUtils (backend/src/plugins/translate/__tests__/test_dictionary_utils.py)
+/**!
+ * @brief Validate utility functions: _normalize_term and _detect_delimiter.
+ */
+
+// --- LanguageDetectServiceTests (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @brief Unit tests for LanguageDetectService — local language detection via lingua.
+ */
+
+// --- test_detect_language_basic (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ * @brief Verify core language detection for common languages.
+ */
+
+// --- test_detect_language_edge_cases (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_batch_detect (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_build_detector (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_get_detector_cache (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- test_code_to_lang_mapping (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- fixtures (backend/src/plugins/translate/__tests__/test_lang_detect.py)
+/**!
+ */
+
+// --- TestTextCleaner (backend/src/plugins/translate/__tests__/test_text_cleaner.py)
+/**!
+ * @brief Verify text cleaning contracts — normalize_whitespace, truncate_text, clean_text.
+ */
+
+// --- TestTokenBudget (backend/src/plugins/translate/__tests__/test_token_budget.py)
+/**!
+ * @brief Verify estimate_token_budget contracts — safe batch sizing, auto-reduction, warning generation.
+ */
+
+// --- BatchInsertService (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @brief Insert successful translation records into target table via Superset SQL Lab.
+ */
+
+// --- insert_batch_to_target (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ * @brief Insert successful records from a single batch into the target table.
+ */
+
+// --- _fetch_batch_records (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _build_target_columns (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _build_context_keys (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _build_insert_rows (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _resolve_insert_backend (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _generate_insert_sql (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- _execute_insert_sql (backend/src/plugins/translate/_batch_insert.py)
+/**!
+ */
+
+// --- BatchProcessingService (backend/src/plugins/translate/_batch_proc.py)
+/**!
+ * @brief Batch processing for translation: classify rows (same-language/cache/preview/LLM),
+ */
+
+// --- process_batch (backend/src/plugins/translate/_batch_proc.py)
+/**!
+ * @brief Process a single batch: create record, classify rows, call LLM, persist.
+ * @post TranslationBatch and TranslationRecord rows are created.
+ * @pre job and batch_rows are valid.
+ */
+
+// --- AdaptiveBatchSizer (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Adaptive batch sizing for LLM translation — splits source rows into variable-sized
+ */
+
+// --- resolve_provider_model (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Resolve the LLM provider model name for token budget estimation.
+ * @post Returns model name string or None if resolution fails.
+ */
+
+// --- auto_size_batches (backend/src/plugins/translate/_batch_sizer.py)
+/**!
+ * @brief Split source rows into variable-sized batches based on content length.
+ * @post Returns list of batches, each batch is a list of row dicts.
+ * @pre source_rows is non-empty. job has valid config.
+ */
+
+// --- LanguageDetectService (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Local language detection powered by lingua-language-detector (no LLM).
+ */
+
+// --- _detector_cache_key (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Build a deterministic cache key from target languages list.
+ */
+
+// --- build_detector (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Build a LanguageDetector restricted to target + common source languages.
+ */
+
+// --- get_detector (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Get or create a cached detector for the given target languages.
+ */
+
+// --- detect_language (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Detect the language of a single text string. Returns BCP-47 code or "und".
+ */
+
+// --- _character_block_fallback (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief When lingua returns "und", check if character-block dominance (e.g. Cyrillic)
+ */
+
+// --- batch_detect (backend/src/plugins/translate/_lang_detect.py)
+/**!
+ * @brief Detect language for multiple texts in batch. Builds detector if not provided.
+ */
+
+// --- LLMTranslationService (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief LLM interaction for batch translation: call provider with retry, handle truncation
+ */
+
+// --- call_llm_for_batch (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief Call LLM for a batch of rows requiring translation. Parse and persist results.
+ * @post Returns dict with successful/failed/skipped counts.
+ * @pre job has valid provider_id. batch_rows is non-empty.
+ */
+
+// --- call_llm (backend/src/plugins/translate/_llm_call.py)
+/**!
+ * @brief Route to provider-specific LLM call implementation.
+ */
+
+// --- LLMHttpClient (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @brief HTTP client for OpenAI-compatible LLM API calls with rate-limit handling and
+ */
+
+// --- call_openai_compatible (backend/src/plugins/translate/_llm_http.py)
+/**!
+ * @brief Call OpenAI-compatible API with rate-limit handling and structured output fallback.
+ * @post Returns (response text, finish_reason).
+ * @pre Valid API endpoint, key, model, and prompt.
+ */
+
+// --- _do_http_request (backend/src/plugins/translate/_llm_http.py)
+/**!
+ */
+
+// --- _handle_response_format_fallback (backend/src/plugins/translate/_llm_http.py)
+/**!
+ */
+
+// --- LLMResponseParser (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ * @brief Parse LLM JSON response into per-row translations with support for markdown code
+ */
+
+// --- _recover_from_markdown (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ */
+
+// --- _recover_truncated_rows (backend/src/plugins/translate/_llm_parse.py)
+/**!
+ */
+
+// --- RunExecutionService (backend/src/plugins/translate/_run_service.py)
+/**!
+ * @brief Full run lifecycle: prepare run, fetch source rows, filter new keys, orchestrate batches,
+ */
+
+// --- RunSourceFetcher (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @brief Fetch source rows for translation runs from Superset datasource or preview session.
+ */
+
+// --- fetch_source_rows (backend/src/plugins/translate/_run_source.py)
+/**!
+ * @brief Fetch source rows from Superset datasource or preview session fallback.
+ */
+
+// --- _extract_chart_data_rows (backend/src/plugins/translate/_run_source.py)
+/**!
+ */
+
+// --- TextCleaner (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Text cleaning utilities for the translation pipeline — whitespace normalization
+ */
+
+// --- normalize_whitespace (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Collapse multiple spaces, tabs, and newlines into single spaces; trim leading/trailing
+ */
+
+// --- truncate_text (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Truncate text to max_length characters, appending "..." if truncation occurs.
+ * @post When len(text) <= max_length, returns text unchanged.
+ * @pre text is a string. max_length >= 0.
+ */
+
+// --- clean_text (backend/src/plugins/translate/_text_cleaner.py)
+/**!
+ * @brief Combine whitespace normalization and truncation into one step.
+ */
+
+// --- estimate_token_budget (backend/src/plugins/translate/_token_budget.py)
+/**!
+ * @brief Calculate safe batch_size and max_tokens for LLM translation calls based on actual content length and model context window limits.
+ */
+
+// --- DEFAULT_CONTEXT_WINDOW (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DEFAULT_MAX_OUTPUT_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- REASONING_OVERHEAD (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- PROVIDER_DEFAULTS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- OUTPUT_PER_ROW_PER_LANG (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- JSON_OVERHEAD_PER_ROW (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- PROMPT_BASE_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DICT_TOKENS_PER_ENTRY (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- DICT_TOKENS_MAX (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- CHARS_PER_TOKEN_MIXED (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- MIN_MAX_TOKENS (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- MAX_OUTPUT_HEADROOM (backend/src/plugins/translate/_token_budget.py)
+/**!
+ */
+
+// --- TranslationUtils (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Shared utility functions for the translation plugin — dictionary enforcement,
+ */
+
+// --- _normalize_term (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Normalize a term for case-insensitive unique constraint lookup.
+ */
+
+// --- _detect_delimiter (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Detect the delimiter used in a CSV/TSV header line.
+ */
+
+// --- _enforce_dictionary (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Post-process LLM output: enforce dictionary term replacements.
+ * @post per_lang_values may be mutated to include forced dictionary replacements.
+ * @pre dict_matches is a list of dict entries with source_term/target_term.
+ */
+
+// --- _compute_source_hash (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Compute deterministic cache key for a source row.
+ */
+
+// --- _check_translation_cache (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Look up a previously successful translation by source_hash.
+ */
+
+// --- _compute_key_hash (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Compute a stable hash from source_data dict for matching preview edits.
+ */
+
+// --- estimate_row_tokens (backend/src/plugins/translate/_utils.py)
+/**!
+ * @brief Estimate token count for a single source row including context fields.
+ * @post Returns estimated token count >= 1.
+ * @pre source_text is a string.
+ */
+
+// --- DictionaryManagerModule (backend/src/plugins/translate/dictionary.py)
+/**!
+ * @brief Business logic for terminology dictionary management, entry CRUD, CSV/TSV import with conflict detection, and per-batch filtering.
+ * @post Dictionary and entry mutations are persisted with conflict detection.
+ * @pre Database session is open and valid.
+ */
+
+// --- DictionaryManager (backend/src/plugins/translate/dictionary.py)
+/**!
+ * @brief Facade for terminology dictionaries: delegates to DictionaryCRUD, DictionaryEntryCRUD, DictionaryImportExport, DictionaryBatchFilter, DictionaryCorrectionService.
+ * @post Dictionary and entry mutations are persisted with conflict detection.
+ * @pre Database session is open and valid.
+ */
+
+// --- DictionaryCorrectionService (backend/src/plugins/translate/dictionary_correction.py)
+/**!
+ * @brief Submit term corrections and bulk corrections to dictionaries with conflict detection.
+ */
+
+// --- DictionaryCRUD (backend/src/plugins/translate/dictionary_crud.py)
+/**!
+ * @brief CRUD operations for TerminologyDictionary records.
+ */
+
+// --- DictionaryEntryCRUD (backend/src/plugins/translate/dictionary_entries.py)
+/**!
+ * @brief CRUD operations for DictionaryEntry records.
+ */
+
+// --- DictionaryBatchFilter (backend/src/plugins/translate/dictionary_filter.py)
+/**!
+ * @brief Scan batch texts for case-insensitive, word-boundary-aware matches against dictionaries.
+ */
+
+// --- DictionaryImportExport (backend/src/plugins/translate/dictionary_import_export.py)
+/**!
+ * @brief Import/export entries as CSV/TSV with conflict detection, and migration of old entries.
+ */
+
+// --- _validate_bcp47 (backend/src/plugins/translate/dictionary_validation.py)
+/**!
+ * @brief Validate that a language tag is a non-empty BCP-47 string.
+ */
+
+// --- TranslationEventLog (backend/src/plugins/translate/events.py)
+/**!
+ * @brief Structured event logging for translation operations with terminal event invariant enforcement.
+ * @invariant Exactly one run_started + exactly one terminal event per non-null run_id.
+ * @post Events are persisted immutably; terminal events enforce exactly-one invariant per run.
+ * @pre Database session is open and valid.
+ */
+
+// --- TranslationExecutor (backend/src/plugins/translate/executor.py)
+/**!
+ * @brief Process translation in batches: fetch source rows, call LLM, persist TranslationBatch
+ */
+
+// --- TranslationMetrics (backend/src/plugins/translate/metrics.py)
+/**!
+ * @brief Aggregate translation metrics from live TranslationEvent + MetricSnapshot for per-job reporting.
+ * @post Metrics are aggregated and returned; no side effects.
+ * @pre Database session is open.
+ */
+
+// --- TranslationOrchestrator (backend/src/plugins/translate/orchestrator.py)
+/**!
+ * @brief Run lifecycle coordination: validate preconditions, dispatch executor, generate SQL, submit to Superset, record events.
+ * @invariant State transitions: PENDING -> RUNNING -> COMPLETED|FAILED|CANCELLED. Exactly one terminal event per run.
+ * @post Translation run is executed, SQL generated and submitted, events recorded.
+ * @pre Valid job and accepted preview (for manual runs). Superset and LLM are reachable.
+ */
+
+// --- TranslationResultAggregator (backend/src/plugins/translate/orchestrator_aggregator.py)
+/**!
+ * @brief Query translation run status, records, and history.
+ * @post Returns structured run data with pagination.
+ * @pre Database session is available.
+ */
+
+// --- orchestrator_cancel (backend/src/plugins/translate/orchestrator_cancel.py)
+/**!
+ * @brief Cancel and retry-insert operations for translation runs.
+ */
+
+// --- orchestrator_config (backend/src/plugins/translate/orchestrator_config.py)
+/**!
+ * @brief Config hash and dictionary snapshot hash utilities for translation planning.
+ */
+
+// --- TranslationExecutionEngine (backend/src/plugins/translate/orchestrator_exec.py)
+/**!
+ * @brief Execute translation runs: dispatch executor, manage completion and failure paths.
+ * @post Run is executed with SQL generated; events recorded.
+ * @pre Database session and config manager are available. Run is in valid state.
+ */
+
+// --- update_language_stats (backend/src/plugins/translate/orchestrator_lang_stats.py)
+/**!
+ * @brief Aggregate TranslationLanguage entries by language_code and update TranslationRunLanguageStats.
+ */
+
+// --- TranslationPlanner (backend/src/plugins/translate/orchestrator_planner.py)
+/**!
+ * @brief Handle translation run planning: validation, config hashing, dictionary snapshot.
+ * @post TranslationRun is planned with hashes and config snapshot; events recorded.
+ * @pre Database session and config manager are available.
+ */
+
+// --- orchestrator_query (backend/src/plugins/translate/orchestrator_query.py)
+/**!
+ * @brief Query translation run records and history with pagination.
+ */
+
+// --- TranslationRunRetryManager (backend/src/plugins/translate/orchestrator_retry.py)
+/**!
+ * @brief Manage retry of translation run batches.
+ * @post Retried batches are re-executed.
+ * @pre Database session and config manager are available.
+ */
+
+// --- orchestrator_run_completion (backend/src/plugins/translate/orchestrator_run_completion.py)
+/**!
+ * @brief Post-execution run completion handlers: cancelled, success-with-insert, and failure paths.
+ */
+
+// --- TranslationStageRunner (backend/src/plugins/translate/orchestrator_runner.py)
+/**!
+ * @brief Coordinate translation run execution, retry, and cancellation via delegated components.
+ * @post Run is executed; events recorded.
+ * @pre Database session and config manager are available. Run is in valid state.
+ */
+
+// --- SQLInsertService (backend/src/plugins/translate/orchestrator_sql.py)
+/**!
+ * @brief Generate INSERT SQL from translation records and submit to Superset SQL Lab.
+ * @post SQL is generated and submitted to Superset; returns execution result.
+ * @pre Job has target table configured. Run has successful records.
+ */
+
+// --- orchestrator_sql_rows (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Column and row building utilities for SQL insertion in translate plugin.
+ */
+
+// --- build_columns (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build list of target columns for SQL INSERT from job configuration.
+ */
+
+// --- build_context_keys (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build list of context keys for SQL row data.
+ */
+
+// --- build_rows (backend/src/plugins/translate/orchestrator_sql_rows.py)
+/**!
+ * @brief Build row data for SQL INSERT with per-language expansion.
+ */
+
+// --- validate_job_preconditions (backend/src/plugins/translate/orchestrator_validation.py)
+/**!
+ * @brief Validate preconditions before starting a translation run.
+ * @post Raises ValueError if any precondition fails.
+ * @pre Job exists and db session is valid.
+ */
+
+// --- TranslatePlugin (backend/src/plugins/translate/plugin.py)
+/**!
+ * @brief TranslatePlugin skeleton for cross-dialect SQL and dashboard translation.
+ */
+
+// --- DEFAULT_EXECUTION_PROMPT_TEMPLATE (backend/src/plugins/translate/preview_constants.py)
+/**!
+ * @brief Default LLM prompt template for full execution (batch translation).
+ */
+
+// --- DEFAULT_PREVIEW_PROMPT_TEMPLATE (backend/src/plugins/translate/preview_constants.py)
+/**!
+ * @brief Default LLM prompt template for preview (sample translation).
+ */
+
+// --- PreviewExecutor (backend/src/plugins/translate/preview_executor.py)
+/**!
+ * @brief Fetch sample data from Superset and call LLM provider for preview.
+ * @post Sample rows fetched, LLM called.
+ * @pre Database session, config manager, and Superset client are available.
+ */
+
+// --- PreviewPromptBuilder (backend/src/plugins/translate/preview_prompt_builder.py)
+/**!
+ * @brief Build LLM prompts for preview sessions including dictionary glossary and row context.
+ */
+
+// --- preview_prompt_helpers (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Token estimation metadata and budget helpers for preview prompt building.
+ */
+
+// --- estimate_token_budget_for_rows (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Check token budget and optionally truncate source rows for preview.
+ * @post Returns adjusted source_rows, actual_row_count, and token_budget dict.
+ */
+
+// --- compute_build_token_metadata (backend/src/plugins/translate/preview_prompt_helpers.py)
+/**!
+ * @brief Compute token estimation metadata for prompt builder return dict.
+ * @post Returns prompt, row_meta, target_languages, cost estimates, and cost_warning.
+ */
+
+// --- preview_response_parser (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Parse LLM JSON responses and Superset data; compute config/dict hashes for preview.
+ */
+
+// --- parse_llm_response (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Parse LLM JSON response into structured translations dict with per-language support.
+ * @post Returns dict mapping row_id -> {detected_source_language, lang_code: translation, ...}.
+ * @pre response_text is a valid JSON string (possibly wrapped in markdown code block).
+ */
+
+// --- extract_data_rows (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Extract data rows from Superset chart data API response.
+ */
+
+// --- compute_config_hash (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Compute a deterministic hash of job configuration for snapshot comparison.
+ */
+
+// --- compute_dict_snapshot_hash (backend/src/plugins/translate/preview_response_parser.py)
+/**!
+ * @brief Compute a hash of dictionary state for snapshot comparison.
+ */
+
+// --- PreviewSessionManager (backend/src/plugins/translate/preview_review.py)
+/**!
+ * @brief Manage preview session row-level actions: approve/edit/reject rows.
+ */
+
+// --- preview_session_ops (backend/src/plugins/translate/preview_session_ops.py)
+/**!
+ * @brief Preview session lifecycle operations: accept and query preview sessions.
+ */
+
+// --- get_preview_session (backend/src/plugins/translate/preview_session_ops.py)
+/**!
+ * @brief Get the latest preview session for a job with its records.
+ */
+
+// --- preview_session_serializer (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Serialization and action helpers for preview sessions: record serialization and per-row approve/reject/edit actions.
+ */
+
+// --- serialize_preview_record (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Serialize a TranslationPreviewRecord to a response dict.
+ */
+
+// --- apply_language_action (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Apply approve/reject/edit action to a TranslationPreviewLanguage entry.
+ */
+
+// --- apply_record_action (backend/src/plugins/translate/preview_session_serializer.py)
+/**!
+ * @brief Apply approve/reject/edit action to a TranslationPreviewRecord and its language entries.
+ */
+
+// --- TokenEstimator (backend/src/plugins/translate/preview_token_estimator.py)
+/**!
+ * @brief Estimate token counts and costs for LLM translation operations.
+ */
+
+// --- ContextAwarePromptBuilder (backend/src/plugins/translate/prompt_builder.py)
+/**!
+ * @brief Pure-function prompt builder that enhances dictionary entries with context annotations.
+ */
+
+// --- TranslationScheduler (backend/src/plugins/translate/scheduler.py)
+/**!
+ * @brief Manage TranslationSchedule rows and register them with core SchedulerService.
+ * @post TranslationSchedule CRUD persisted; APScheduler jobs registered/updated/removed.
+ * @pre Database session and SchedulerService are available.
+ */
+
+// --- execute_scheduled_translation (backend/src/plugins/translate/scheduler.py)
+/**!
+ * @brief APScheduler job handler — runs scheduled translation with concurrency check and new-key-only fallback.
+ * @post Translation run created and executed if no concurrent run exists.
+ * @pre schedule_id is valid.
+ */
+
+// --- TranslateJobService (backend/src/plugins/translate/service.py)
+/**!
+ * @brief Service layer for translation job CRUD with datasource column validation and database dialect detection.
+ * @post Translation jobs are created/updated/deleted with column validation and dialect caching.
+ * @pre Database session and config manager are available.
+ */
+
+// --- BulkFindReplaceService (backend/src/plugins/translate/service_bulk_replace.py)
+/**!
+ * @brief Service for bulk find-and-replace operations on translated values.
+ */
+
+// --- DatasourceMetadataService (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Fetch datasource column metadata and database dialect from Superset.
+ * @post Datasource metadata is fetched with column details and normalized dialect.
+ * @pre Database session and config manager are available.
+ */
+
+// --- get_dialect_from_database (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Extract normalized dialect string from a Superset database record.
+ */
+
+// --- fetch_datasource_metadata (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Fetch datasource columns and database dialect from Superset.
+ */
+
+// --- detect_virtual_columns (backend/src/plugins/translate/service_datasource.py)
+/**!
+ * @brief Identify virtual (calculated) columns from column metadata.
+ */
+
+// --- InlineCorrectionService (backend/src/plugins/translate/service_inline_correction.py)
+/**!
+ * @brief Service for inline editing translated values and submitting corrections to dictionaries.
+ * @post Inline edits applied with optional dictionary submission.
+ * @pre Database session is available.
+ */
+
+// --- TargetSchemaValidation (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Проверка схемы целевой таблицы: запрос колонок через Superset SQL Lab,
+ */
+
+// --- _build_expected_columns (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Собирает список ожидаемых колонок по конфигурации column mapping.
+ */
+
+// --- _extract_columns_from_rows (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Извлекает список колонок таблицы из data-строк результата SQL Lab.
+ */
+
+// --- _parse_sqllab_result (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Извлекает data-строки из ответа Superset SQL Lab.
+ */
+
+// --- validate_target_table_schema (backend/src/plugins/translate/service_target_schema.py)
+/**!
+ * @brief Основная функция: проверяет схему целевой таблицы через Superset SQL Lab.
+ * @post Возвращает TargetSchemaValidationResponse с diff-анализом.
+ * @pre Superset окружение и target_database_id валидны.
+ */
+
+// --- ServiceUtils (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Utility functions for the translate service layer.
+ */
+
+// --- _extract_dialect (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Extract database dialect from Superset backend URI.
+ */
+
+// --- job_to_response (backend/src/plugins/translate/service_utils.py)
+/**!
+ * @brief Convert a TranslationJob ORM model to a TranslateJobResponse schema with dictionary_ids.
+ */
+
+// --- SQLGenerator (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Dialect-aware safe SQL generation for INSERT/UPSERT operations.
+ * @post Returns safe SQL strings for the target dialect.
+ * @pre Job has target_schema and target_table configured. Dialect is one of supported SUPPORTED_DIALECTS.
+ */
+
+// --- _normalize_timestamp_value (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Detect Unix timestamp strings (seconds or millis) and convert to 'YYYY-MM-DD' for Date columns.
+ */
+
+// --- _quote_identifier (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Quote an identifier per dialect rules. PostgreSQL uses double quotes; ClickHouse uses backticks.
+ * @post Returns safely quoted identifier.
+ * @pre identifier is a non-empty string.
+ */
+
+// --- _encode_sql_value (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Encode a Python value into a SQL-safe literal for INSERT VALUES, with ClickHouse timestamp normalization.
+ */
+
+// --- _build_values_clause (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Build a VALUES clause for multiple rows with per-column value encoding and dialect-aware quoting.
+ */
+
+// --- generate_insert_sql (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Generate a dialect-aware plain INSERT SQL statement for the given table, columns, and rows.
+ */
+
+// --- generate_upsert_sql (backend/src/plugins/translate/sql_generator.py)
+/**!
+ * @brief Generate PostgreSQL dialect UPSERT SQL with ON CONFLICT DO UPDATE.
+ * @post Returns UPSERT SQL string or raises ValueError.
+ * @pre dialect is postgresql-compatible. target_table, columns, key_columns are non-empty.
+ */
+
+// --- SupersetSqlLabExecutor (backend/src/plugins/translate/superset_executor.py)
+/**!
+ * @brief Submit SQL to Superset SQL Lab API and poll execution status.
+ * @post SQL is submitted to Superset SQL Lab; execution reference is returned.
+ * @pre Valid Superset environment configuration and authenticated client.
+ */
+
+// --- SchemasPackage (backend/src/schemas/__init__.py)
+/**!
+ * @brief API schema package root.
+ */
+
+// --- TestSettingsAndHealthSchemas (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Regression tests for settings and health schema contracts updated in 026 fix batch.
+ */
+
+// --- test_validation_policy_create_accepts_structured_custom_channels (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Ensure policy schema accepts structured custom channel objects with type/target fields.
+ */
+
+// --- test_validation_policy_create_rejects_legacy_string_custom_channels (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Ensure legacy list[str] custom channel payload is rejected by typed channel contract.
+ */
+
+// --- test_dashboard_health_item_status_accepts_only_whitelisted_values (backend/src/schemas/__tests__/test_settings_and_health_schemas.py)
+/**!
+ * @brief Verify strict grouped regex only accepts PASS/WARN/FAIL/UNKNOWN exact statuses.
+ */
+
+// --- AuthSchemas (backend/src/schemas/auth.py)
+/**!
+ * @brief Pydantic schemas for authentication requests and responses.
+ * @invariant Sensitive fields like password must not be included in response schemas.
+ */
+
+// --- Token (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a JWT access token response.
+ */
+
+// --- TokenData (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents the data encoded in a JWT token.
+ */
+
+// --- PermissionSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a permission in API responses.
+ */
+
+// --- RoleSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents a role in API responses.
+ */
+
+// --- RoleCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating a new role.
+ */
+
+// --- RoleUpdate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for updating an existing role.
+ */
+
+// --- ADGroupMappingSchema (backend/src/schemas/auth.py)
+/**!
+ * @brief Represents an AD Group to Role mapping in API responses.
+ */
+
+// --- ADGroupMappingCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating an AD Group mapping.
+ */
+
+// --- UserBase (backend/src/schemas/auth.py)
+/**!
+ * @brief Base schema for user data.
+ */
+
+// --- UserCreate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for creating a new user.
+ */
+
+// --- UserUpdate (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for updating an existing user.
+ */
+
+// --- User (backend/src/schemas/auth.py)
+/**!
+ * @brief Schema for user data in API responses.
+ */
+
+// --- DatasetReviewSchemas (backend/src/schemas/dataset_review.py)
+/**!
+ * @brief Thin facade re-exporting all dataset review API schemas from decomposed sub-modules.
+ */
+
+// --- DatasetReviewSchemaComposites (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Composite Pydantic DTOs for clarification, preview, run context, and session summary/detail responses.
+ */
+
+// --- ClarificationOptionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification option DTO.
+ */
+
+// --- ClarificationAnswerDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification answer DTO with feedback.
+ */
+
+// --- ClarificationQuestionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification question DTO with nested options and answer.
+ */
+
+// --- ClarificationSessionDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Clarification session DTO with nested questions.
+ */
+
+// --- CompiledPreviewDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Compiled preview DTO with fingerprint and session version.
+ */
+
+// --- DatasetRunContextDto (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Run context DTO with launch audit data and session version.
+ */
+
+// --- SessionSummary (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Lightweight session summary DTO for list responses.
+ */
+
+// --- SessionDetail (backend/src/schemas/dataset_review_pkg/_composites.py)
+/**!
+ * @brief Full session detail DTO with all nested aggregates for detail views.
+ */
+
+// --- DatasetReviewSchemaDtos (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Pydantic DTOs for session, profile, findings, collaborators, and semantic field API payloads.
+ */
+
+// --- SessionCollaboratorDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Collaborator DTO for session access control.
+ */
+
+// --- DatasetProfileDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Dataset profile DTO with business summary and confidence metadata.
+ */
+
+// --- ValidationFindingDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Validation finding DTO with resolution tracking.
+ */
+
+// --- SemanticSourceDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic source DTO with trust level and status.
+ */
+
+// --- SemanticCandidateDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic candidate DTO with match type and confidence score.
+ */
+
+// --- SemanticFieldEntryDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Semantic field entry DTO with nested candidates and session version.
+ */
+
+// --- ImportedFilterDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Imported filter DTO with confidence and recovery status.
+ */
+
+// --- TemplateVariableDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Template variable DTO with mapping status.
+ */
+
+// --- ExecutionMappingDto (backend/src/schemas/dataset_review_pkg/_dtos.py)
+/**!
+ * @brief Execution mapping DTO with approval state and session version.
+ */
+
+// --- HealthSchemas (backend/src/schemas/health.py)
+/**!
+ * @brief Pydantic schemas for dashboard health summary.
+ */
+
+// --- DashboardHealthItem (backend/src/schemas/health.py)
+/**!
+ * @brief Represents the latest health status of a single dashboard.
+ */
+
+// --- HealthSummaryResponse (backend/src/schemas/health.py)
+/**!
+ * @brief Aggregated health summary for all dashboards.
+ */
+
+// --- ProfileSchemas (backend/src/schemas/profile.py)
+/**!
+ * @brief Defines API schemas for profile preference persistence, security read-only snapshot, and Superset account lookup.
+ * @invariant Schema shapes stay stable for profile UI states and backend preference contracts.
+ */
+
+// --- ProfilePermissionState (backend/src/schemas/profile.py)
+/**!
+ * @brief Represents one permission badge state for profile read-only security view.
+ */
+
+// --- ProfileSecuritySummary (backend/src/schemas/profile.py)
+/**!
+ * @brief Read-only security and access snapshot for current user.
+ */
+
+// --- ProfilePreference (backend/src/schemas/profile.py)
+/**!
+ * @brief Represents persisted profile preference for a single authenticated user.
+ */
+
+// --- ProfilePreferenceUpdateRequest (backend/src/schemas/profile.py)
+/**!
+ * @brief Request payload for updating current user's profile settings.
+ */
+
+// --- ProfilePreferenceResponse (backend/src/schemas/profile.py)
+/**!
+ * @brief Response envelope for profile preference read/update endpoints.
+ */
+
+// --- SupersetAccountLookupRequest (backend/src/schemas/profile.py)
+/**!
+ * @brief Query contract for Superset account lookup by selected environment.
+ */
+
+// --- SupersetAccountCandidate (backend/src/schemas/profile.py)
+/**!
+ * @brief Canonical account candidate projected from Superset users payload.
+ */
+
+// --- SupersetAccountLookupResponse (backend/src/schemas/profile.py)
+/**!
+ * @brief Response envelope for Superset account lookup (success or degraded mode).
+ */
+
+// --- SettingsSchemas (backend/src/schemas/settings.py)
+/**!
+ * @brief Pydantic schemas for application settings and automation policies.
+ */
+
+// --- NotificationChannel (backend/src/schemas/settings.py)
+/**!
+ * @brief Structured notification channel definition for policy-level custom routing.
+ */
+
+// --- ValidationPolicyBase (backend/src/schemas/settings.py)
+/**!
+ * @brief Base schema for validation policy data.
+ */
+
+// --- ValidationPolicyCreate (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for creating a new validation policy.
+ */
+
+// --- ValidationPolicyUpdate (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for updating an existing validation policy.
+ */
+
+// --- ValidationPolicyResponse (backend/src/schemas/settings.py)
+/**!
+ * @brief Schema for validation policy response data.
+ */
+
+// --- TranslationScheduleItem (backend/src/schemas/settings.py)
+/**!
+ * @brief Response schema for a translation schedule item with joined job name.
+ */
+
+// --- TranslateSchemas (backend/src/schemas/translate.py)
+/**!
+ * @brief Pydantic v2 schemas for translation API request/response serialization.
+ */
+
+// --- TranslateJobCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for creating a new translation job.
+ */
+
+// --- TranslateJobUpdate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for updating an existing translation job.
+ */
+
+// --- TranslateJobResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation job API responses.
+ */
+
+// --- DatasourceColumnResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for datasource column metadata response.
+ */
+
+// --- DatasourceColumnsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for datasource columns endpoint response.
+ */
+
+// --- DuplicateJobResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for duplicate job response.
+ */
+
+// --- DictionaryCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for creating a new terminology dictionary.
+ */
+
+// --- DictionaryImport (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for importing entries into a terminology dictionary.
+ */
+
+// --- DictionaryResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for terminology dictionary API responses.
+ */
+
+// --- DictionaryEntryCreate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for adding/editing a dictionary entry with language pair support.
+ */
+
+// --- DictionaryEntryResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for dictionary entry API responses.
+ */
+
+// --- DictionaryImportResult (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for dictionary import result.
+ */
+
+// --- PreviewRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for triggering a translation preview.
+ */
+
+// --- PreviewRowUpdate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for approving/editing/rejecting a preview row.
+ */
+
+// --- PreviewAcceptResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for preview accept response.
+ */
+
+// --- CostEstimate (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for cost estimation in preview response.
+ */
+
+// --- TermCorrectionSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting a term correction in a translation preview.
+ */
+
+// --- TermCorrectionBulkSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting multiple term corrections atomically.
+ */
+
+// --- CorrectionConflictResult (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for reporting conflicts in correction submission.
+ */
+
+// --- CorrectionSubmitResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for correction submission response.
+ */
+
+// --- ScheduleResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for schedule API responses.
+ */
+
+// --- NextExecutionResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for next execution preview.
+ */
+
+// --- TranslationRunResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation run API responses.
+ */
+
+// --- RunDetailResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for detailed run response including records, events, and config snapshot.
+ */
+
+// --- RunHistoryFilter (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for filtering run history.
+ */
+
+// --- RunListResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for paginated run list response.
+ */
+
+// --- AggregatedMetricsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for aggregated per-job metrics.
+ */
+
+// --- TranslationPreviewLanguageResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language preview data in API responses.
+ */
+
+// --- PreviewRow (backend/src/schemas/translate.py)
+/**!
+ * @brief A single row in a translation preview showing original and translated content side by side.
+ */
+
+// --- TranslationPreviewResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation preview session API responses.
+ */
+
+// --- TranslationBatchResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation batch API responses.
+ */
+
+// --- MetricsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for translation metrics API responses.
+ */
+
+// --- TranslationLanguageResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language translation data in API responses.
+ */
+
+// --- TranslationRunLanguageStatsResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for per-language statistics in run API responses.
+ */
+
+// --- OverrideLanguageRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for manually overriding the detected source language of a translation.
+ */
+
+// --- BulkFindReplaceRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for bulk find-and-replace within translations for a target language.
+ */
+
+// --- InlineEditRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for inline editing a translated value on a completed run result.
+ */
+
+// --- BulkReplacePreviewItem (backend/src/schemas/translate.py)
+/**!
+ * @brief A single item in a bulk replace preview list.
+ */
+
+// --- BulkReplaceResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Response for bulk find-and-replace operation.
+ */
+
+// --- InlineCorrectionSubmit (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for submitting an inline correction for a specific translated record.
+ */
+
+// --- TargetSchemaValidationRequest (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for requesting target table schema validation.
+ */
+
+// --- TargetSchemaColumnInfo (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for a single column in the schema validation response.
+ */
+
+// --- TargetSchemaValidationResponse (backend/src/schemas/translate.py)
+/**!
+ * @brief Schema for target table schema validation response.
+ */
+
+// --- ValidationSchemas (backend/src/schemas/validation.py)
+/**!
+ * @brief Pydantic v2 schemas for validation task management and run history API serialization.
+ */
+
+// --- ValidationTaskCreate (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for creating a new validation task (policy).
+ */
+
+// --- ValidationTaskUpdate (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for updating an existing validation task (policy).
+ */
+
+// --- ValidationTaskResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for validation task API responses — includes last run status from join.
+ */
+
+// --- ValidationTaskListResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for paginated task list response.
+ */
+
+// --- ValidationRunResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for validation run history listing.
+ */
+
+// --- ValidationRunListResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for paginated run list response.
+ */
+
+// --- ValidationRunDetailResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for full run detail including parsed issues and raw response.
+ */
+
+// --- TriggerRunResponse (backend/src/schemas/validation.py)
+/**!
+ * @brief Schema for trigger-run response — returns spawned task ID.
+ */
+
+// --- ScriptsPackage (backend/src/scripts/__init__.py)
+/**!
+ * @brief Script entrypoint package root.
+ */
+
+// --- CleanReleaseCliScript (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Provide headless CLI commands for candidate registration, artifact import and manifest build.
+ */
+
+// --- build_parser (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Build argparse parser for clean release CLI.
+ */
+
+// --- run_candidate_register (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Register candidate in repository via CLI command.
+ * @post Candidate is persisted in DRAFT status.
+ * @pre Candidate ID must be unique.
+ */
+
+// --- run_artifact_import (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Import single artifact for existing candidate.
+ * @post Artifact is persisted for candidate.
+ * @pre Candidate must exist.
+ */
+
+// --- run_manifest_build (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Build immutable manifest snapshot for candidate.
+ * @post New manifest version is persisted.
+ * @pre Candidate must exist.
+ */
+
+// --- run_compliance_run (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Execute compliance run for candidate with optional manifest fallback.
+ * @post Returns run payload and exit code 0 on success.
+ * @pre Candidate exists and trusted snapshots are configured.
+ */
+
+// --- run_compliance_status (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read run status by run id.
+ * @post Returns run status payload.
+ * @pre Run exists.
+ */
+
+// --- _to_payload (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Serialize domain models for CLI JSON output across SQLAlchemy/Pydantic variants.
+ * @post Returns dictionary payload without mutating value.
+ * @pre value is serializable model or primitive object.
+ */
+
+// --- run_compliance_report (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read immutable report by run id.
+ * @post Returns report payload.
+ * @pre Run and report exist.
+ */
+
+// --- run_compliance_violations (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Read run violations by run id.
+ * @post Returns violations payload.
+ * @pre Run exists.
+ */
+
+// --- run_approve (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Approve candidate based on immutable PASSED report.
+ * @post Persists APPROVED decision and returns success payload.
+ * @pre Candidate and report exist; report is PASSED.
+ */
+
+// --- run_reject (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Reject candidate without mutating compliance evidence.
+ * @post Persists REJECTED decision and returns success payload.
+ * @pre Candidate and report exist.
+ */
+
+// --- run_publish (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Publish approved candidate to target channel.
+ * @post Appends ACTIVE publication record and returns payload.
+ * @pre Candidate is approved and report belongs to candidate.
+ */
+
+// --- run_revoke (backend/src/scripts/clean_release_cli.py)
+/**!
+ * @brief Revoke active publication record.
+ * @post Publication record status becomes REVOKED.
+ * @pre Publication id exists and is ACTIVE.
+ */
+
+// --- CleanReleaseTuiScript (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Interactive terminal interface for Enterprise Clean Release compliance validation.
+ * @invariant TUI refuses startup in non-TTY environments; headless flow is CLI/API only.
+ */
+
+// --- TuiFacadeAdapter (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Thin TUI adapter that routes business mutations through application services.
+ * @post Business actions return service results/errors without direct TUI-owned mutations.
+ * @pre repository contains candidate and trusted policy/registry snapshots for execution.
+ */
+
+// --- CleanReleaseTUI (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Curses-based application for compliance monitoring.
+ */
+
+// --- run_checks (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Execute compliance run via facade adapter and update UI state.
+ * @post UI reflects final run/report/violation state from service result.
+ * @pre Candidate and policy snapshots are present in repository.
+ */
+
+// --- bundle_build_mode (backend/src/scripts/clean_release_tui.py)
+/**!
+ * @brief Interactive bundle build screen — select type, enter tag, watch live build output.
+ * @post Subprocess completes (success/failure). Output displayed. User returns via Esc.
+ * @pre TTY is available. Bundle type selected (1 or 2). Tag is non-empty.
+ */
+
+// --- CreateAdminScript (backend/src/scripts/create_admin.py)
+/**!
+ * @brief CLI tool for creating the initial admin user.
+ * @invariant Admin user must have the "Admin" role.
+ */
+
+// --- create_admin (backend/src/scripts/create_admin.py)
+/**!
+ * @brief Creates an admin user and necessary roles/permissions.
+ * @post Admin user exists in auth.db.
+ * @pre username and password provided via CLI.
+ */
+
+// --- DeleteRunningTasksUtil (backend/src/scripts/delete_running_tasks.py)
+/**!
+ * @brief Script to delete tasks with RUNNING status from the database.
+ */
+
+// --- delete_running_tasks (backend/src/scripts/delete_running_tasks.py)
+/**!
+ * @brief Delete all tasks with RUNNING status from the database.
+ * @post All tasks with status 'RUNNING' are removed from the database.
+ * @pre Database is accessible and TaskRecord model is defined.
+ */
+
+// --- InitAuthDbScript (backend/src/scripts/init_auth_db.py)
+/**!
+ * @brief Initializes the auth database and creates the necessary tables.
+ * @invariant Safe to run multiple times (idempotent).
+ */
+
+// --- run_init (backend/src/scripts/init_auth_db.py)
+/**!
+ * @brief Main entry point for the initialization script.
+ * @post auth.db is initialized with the correct schema and seeded permissions.
+ */
+
+// --- SeedPermissionsScript (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Populates the auth database with initial system permissions.
+ * @invariant Safe to run multiple times (idempotent).
+ */
+
+// --- INITIAL_PERMISSIONS (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Canonical bootstrap permission tuples seeded into auth storage.
+ */
+
+// --- seed_permissions (backend/src/scripts/seed_permissions.py)
+/**!
+ * @brief Inserts missing permissions into the database.
+ * @post All INITIAL_PERMISSIONS exist in the DB.
+ */
+
+// --- SeedSupersetLoadTestScript (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Creates randomized load-test data in Superset by cloning chart configurations and creating dashboards in target environments.
+ * @invariant Created chart and dashboard names are globally unique for one script run.
+ */
+
+// --- _parse_args (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Parses CLI arguments for load-test data generation.
+ * @post Returns validated argument namespace.
+ * @pre Script is called from CLI.
+ */
+
+// --- _extract_result_payload (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Normalizes Superset API payloads that may be wrapped in `result`.
+ * @post Returns the unwrapped object when present.
+ * @pre payload is a JSON-decoded API response.
+ */
+
+// --- _extract_created_id (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Extracts object ID from create/update API response.
+ * @post Returns integer object ID or None if missing.
+ * @pre payload is a JSON-decoded API response.
+ */
+
+// --- _generate_unique_name (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Generates globally unique random names for charts/dashboards.
+ * @post Returns a unique string and stores it in used_names.
+ * @pre used_names is mutable set for collision tracking.
+ */
+
+// --- _resolve_target_envs (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Resolves requested environment IDs from configuration.
+ * @post Returns mapping env_id -> configured environment object.
+ * @pre env_ids is non-empty.
+ */
+
+// --- _build_chart_template_pool (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Builds a pool of source chart templates to clone in one environment.
+ * @post Returns non-empty list of chart payload templates.
+ * @pre Client is authenticated.
+ */
+
+// --- seed_superset_load_data (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief Creates dashboards and cloned charts for load testing across target environments.
+ * @post Returns execution statistics dictionary.
+ * @pre Target environments must be reachable and authenticated.
+ */
+
+// --- main (backend/src/scripts/seed_superset_load_test.py)
+/**!
+ * @brief CLI entrypoint for Superset load-test data seeding.
+ * @post Prints summary and exits with non-zero status on failure.
+ * @pre Command line arguments are valid.
+ */
+
+// --- test_dataset_dashboard_relations_script (backend/src/scripts/test_dataset_dashboard_relations.py)
+/**!
+ * @brief Tests and inspects dataset-to-dashboard relationship responses from Superset API.
+ */
+
+// --- services (backend/src/services/__init__.py)
+/**!
+ * @brief Package initialization for services module
+ * @note GitService, AuthService, LLMProviderService have circular import issues - import directly when needed
+ */
+
+// --- auth_service (backend/src/services/auth_service.py)
+/**!
+ * @brief Orchestrates credential authentication and ADFS JIT user provisioning.
+ * @invariant Authentication succeeds only for active users with valid credentials; issued sessions encode subject and scopes from assigned roles.
+ * @post User identity verified and session tokens issued according to role scopes.
+ * @pre Core auth models and security utilities available.
+ */
+
+// --- AuthService (backend/src/services/auth_service.py)
+/**!
+ * @brief Provides high-level authentication services.
+ */
+
+// --- CleanReleaseContracts (backend/src/services/clean_release/__init__.py)
+/**!
+ * @brief Publish the canonical semantic root for the clean-release backend service cluster.
+ */
+
+// --- ApprovalService (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Enforce approval/rejection gates over immutable compliance reports.
+ * @invariant Approval is allowed only for PASSED report bound to candidate; decisions are append-only.
+ * @post Approval decision appended; candidate lifecycle advanced
+ * @pre Report with PASSED final_status exists for candidate
+ */
+
+// --- _get_or_init_decisions_store (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Provide append-only in-memory storage for approval decisions.
+ * @post Returns mutable decision list attached to repository.
+ * @pre repository is initialized.
+ */
+
+// --- _latest_decision_for_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Resolve latest approval decision for candidate from append-only store.
+ * @post Returns latest ApprovalDecision or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- _resolve_candidate_and_report (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Validate candidate/report existence and ownership prior to decision persistence.
+ * @post Returns tuple(candidate, report); raises ApprovalGateError on contract violation.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- approve_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Persist immutable APPROVED decision and advance candidate lifecycle to APPROVED.
+ * @post Approval decision is appended and candidate transitions to APPROVED.
+ * @pre Candidate exists, report belongs to candidate, report final_status is PASSED, candidate not already APPROVED.
+ */
+
+// --- reject_candidate (backend/src/services/clean_release/approval_service.py)
+/**!
+ * @brief Persist immutable REJECTED decision without promoting candidate lifecycle.
+ * @post Rejected decision is appended; candidate lifecycle is unchanged.
+ * @pre Candidate exists and report belongs to candidate.
+ */
+
+// --- ArtifactCatalogLoader (backend/src/services/clean_release/artifact_catalog_loader.py)
+/**!
+ * @brief Load bootstrap artifact catalogs for clean release real-mode flows.
+ * @invariant Artifact catalog must produce deterministic CandidateArtifact entries with required identity and checksum fields.
+ */
+
+// --- load_bootstrap_artifacts (backend/src/services/clean_release/artifact_catalog_loader.py)
+/**!
+ * @brief Parse artifact catalog JSON into CandidateArtifact models for TUI/bootstrap flows.
+ * @post Returns non-mutated CandidateArtifact models with required fields populated.
+ * @pre path points to readable JSON file; payload is list[artifact] or {"artifacts": list[artifact]}.
+ */
+
+// --- AuditService (backend/src/services/clean_release/audit_service.py)
+/**!
+ * @brief Provide lightweight audit hooks for clean release preparation/check/report lifecycle.
+ * @invariant Audit hooks are append-only log actions.
+ * @post Audit events appended to log
+ * @pre Logger configured
+ */
+
+// --- candidate_service (backend/src/services/clean_release/candidate_service.py)
+/**!
+ * @brief Register release candidates with validated artifacts and advance lifecycle through legal transitions.
+ * @invariant Candidate lifecycle transitions are delegated to domain guard logic.
+ * @post candidate and artifacts are persisted; candidate transitions DRAFT -> PREPARED only.
+ * @pre candidate_id must be unique; artifacts input must be non-empty and valid.
+ */
+
+// --- _validate_artifacts (backend/src/services/clean_release/candidate_service.py)
+/**!
+ * @brief Validate raw artifact payload list for required fields and shape.
+ * @post Returns normalized artifact list or raises ValueError.
+ * @pre artifacts payload is provided by caller.
+ */
+
+// --- ComplianceExecutionService (backend/src/services/clean_release/compliance_execution_service.py)
+/**!
+ * @brief Create and execute compliance runs with trusted snapshots, deterministic stages, violations and immutable report persistence.
+ * @invariant A run binds to exactly one candidate/manifest/policy/registry snapshot set.
+ * @post Candidate-scoped compliance runs persist stage evidence, terminal status, and immutable report artifacts when execution succeeds.
+ * @pre Repository adapters, trusted policy resolution, and deterministic stage implementations are available for the run request.
+ */
+
+// --- ComplianceExecutionResult (backend/src/services/clean_release/compliance_execution_service.py)
+/**!
+ * @brief Return envelope for compliance execution with run/report and persisted stage artifacts.
+ */
+
+// --- ComplianceOrchestrator (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Execute mandatory clean compliance stages and produce final COMPLIANT/BLOCKED/FAILED outcome.
+ * @invariant COMPLIANT is impossible when any mandatory stage fails.
+ * @post OrchestrationResult with compliance status
+ * @pre ManifestService and PolicyEngine are available
+ */
+
+// --- CleanComplianceOrchestrator (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Coordinate clean-release compliance verification stages.
+ */
+
+// --- run_check_legacy (backend/src/services/clean_release/compliance_orchestrator.py)
+/**!
+ * @brief Legacy wrapper for compatibility with previous orchestrator call style.
+ * @post Returns finalized ComplianceRun produced by orchestrator start->execute->finalize sequence.
+ * @pre repository and identifiers are valid and resolvable by orchestrator dependencies.
+ */
+
+// --- DemoDataService (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Provide deterministic namespace helpers and isolated in-memory repository creation for demo and real modes.
+ * @invariant Demo and real namespaces must never collide for generated physical identifiers.
+ */
+
+// --- resolve_namespace (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Resolve canonical clean-release namespace for requested mode.
+ * @post Returns deterministic namespace key for demo/real separation.
+ * @pre mode is a non-empty string identifying runtime mode.
+ */
+
+// --- build_namespaced_id (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Build storage-safe physical identifier under mode namespace.
+ * @post Returns deterministic "{namespace}::{logical_id}" identifier.
+ * @pre namespace and logical_id are non-empty strings.
+ */
+
+// --- create_isolated_repository (backend/src/services/clean_release/demo_data_service.py)
+/**!
+ * @brief Create isolated in-memory repository instance for selected mode namespace.
+ * @post Returns repository instance tagged with namespace metadata.
+ * @pre mode is a valid runtime mode marker.
+ */
+
+// --- clean_release_dto (backend/src/services/clean_release/dto.py)
+/**!
+ * @brief Data Transfer Objects for clean release compliance subsystem.
+ */
+
+// --- clean_release_enums (backend/src/services/clean_release/enums.py)
+/**!
+ * @brief Canonical enums for clean release lifecycle and compliance.
+ */
+
+// --- clean_release_exceptions (backend/src/services/clean_release/exceptions.py)
+/**!
+ * @brief Domain exceptions for clean release compliance subsystem.
+ */
+
+// --- clean_release_facade (backend/src/services/clean_release/facade.py)
+/**!
+ * @brief Unified entry point for clean release operations.
+ */
+
+// --- ManifestBuilder (backend/src/services/clean_release/manifest_builder.py)
+/**!
+ * @brief Build deterministic distribution manifest from classified artifact input.
+ * @invariant Equal semantic artifact sets produce identical deterministic hash values.
+ */
+
+// --- build_distribution_manifest (backend/src/services/clean_release/manifest_builder.py)
+/**!
+ * @brief Build DistributionManifest with deterministic hash and validated counters.
+ * @post Returns DistributionManifest with summary counts matching items cardinality.
+ * @pre artifacts list contains normalized classification values.
+ */
+
+// --- ManifestService (backend/src/services/clean_release/manifest_service.py)
+/**!
+ * @brief Build immutable distribution manifests with deterministic digest and version increment.
+ * @invariant Existing manifests are never mutated.
+ * @post New immutable manifest is persisted with incremented version and deterministic digest.
+ * @pre Candidate exists and is PREPARED or MANIFEST_BUILT; artifacts are present.
+ */
+
+// --- build_manifest_snapshot (backend/src/services/clean_release/manifest_service.py)
+/**!
+ * @brief Create a new immutable manifest version for a candidate.
+ * @post Returns persisted DistributionManifest with monotonically incremented version.
+ * @pre Candidate is prepared, artifacts are available, candidate_id is valid.
+ */
+
+// --- clean_release_mappers (backend/src/services/clean_release/mappers.py)
+/**!
+ * @brief Map between domain entities (SQLAlchemy models) and DTOs.
+ */
+
+// --- PolicyEngine (backend/src/services/clean_release/policy_engine.py)
+/**!
+ * @brief Evaluate artifact/source policies for enterprise clean profile with deterministic outcomes.
+ * @invariant Enterprise-clean policy always treats non-registry sources as violations.
+ * @post PolicyDecision returned with approval status
+ * @pre PolicyRepository is accessible
+ */
+
+// --- CleanPolicyEngine (backend/src/services/clean_release/policy_engine.py)
+/**!
+ * @post Deterministic classification and source validation are available.
+ * @pre Active policy exists and is internally consistent.
+ */
+
+// --- PolicyResolutionService (backend/src/services/clean_release/policy_resolution_service.py)
+/**!
+ * @brief Resolve trusted policy and registry snapshots from ConfigManager without runtime overrides.
+ * @invariant Trusted snapshot resolution is based only on ConfigManager active identifiers.
+ * @post ResolutionResult with matched policies
+ * @pre PolicyRepository and Manifest are available
+ */
+
+// --- resolve_trusted_policy_snapshots (backend/src/services/clean_release/policy_resolution_service.py)
+/**!
+ * @brief Resolve immutable trusted policy and registry snapshots using active config IDs only.
+ * @post Returns immutable policy and registry snapshots; runtime override attempts are rejected.
+ * @pre ConfigManager provides active_policy_id and active_registry_id; repository contains referenced snapshots.
+ */
+
+// --- PreparationService (backend/src/services/clean_release/preparation_service.py)
+/**!
+ * @brief Prepare release candidate by policy evaluation and deterministic manifest creation.
+ * @invariant Candidate preparation always persists manifest and candidate status deterministically.
+ */
+
+// --- prepare_candidate_legacy (backend/src/services/clean_release/preparation_service.py)
+/**!
+ * @brief Legacy compatibility wrapper kept for migration period.
+ * @post Delegates to canonical prepare_candidate and preserves response shape.
+ * @pre Same as prepare_candidate.
+ */
+
+// --- PublicationService (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Enforce publication and revocation gates with append-only publication records.
+ * @invariant Publication records are append-only snapshots; revoke mutates only publication status for targeted record.
+ */
+
+// --- _get_or_init_publications_store (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Provide in-memory append-only publication storage.
+ * @post Returns publication list attached to repository.
+ * @pre repository is initialized.
+ */
+
+// --- _latest_publication_for_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Resolve latest publication record for candidate.
+ * @post Returns latest record or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- _latest_approval_for_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Resolve latest approval decision from repository decision store.
+ * @post Returns latest decision object or None.
+ * @pre candidate_id is non-empty.
+ */
+
+// --- publish_candidate (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Create immutable publication record for approved candidate.
+ * @post New ACTIVE publication record is appended.
+ * @pre Candidate exists, report belongs to candidate, latest approval is APPROVED.
+ */
+
+// --- revoke_publication (backend/src/services/clean_release/publication_service.py)
+/**!
+ * @brief Revoke existing publication record without deleting history.
+ * @post Target publication status becomes REVOKED and updated record is returned.
+ * @pre publication_id exists in repository publication store.
+ */
+
+// --- ReportBuilder (backend/src/services/clean_release/report_builder.py)
+/**!
+ * @brief Build and persist compliance reports with consistent counter invariants.
+ * @invariant blocking_violations_count never exceeds violations_count.
+ * @post Returns immutable report payloads with consistent violation counters and operator summary content.
+ * @pre Compliance run is terminal and repository persistence is available for report storage.
+ */
+
+// --- clean_release_repositories (backend/src/services/clean_release/repositories/__init__.py)
+/**!
+ * @brief Export all clean release repositories.
+ */
+
+// --- approval_repository (backend/src/services/clean_release/repositories/approval_repository.py)
+/**!
+ * @brief Persist and query approval decisions.
+ */
+
+// --- artifact_repository (backend/src/services/clean_release/repositories/artifact_repository.py)
+/**!
+ * @brief Persist and query candidate artifacts.
+ */
+
+// --- audit_repository (backend/src/services/clean_release/repositories/audit_repository.py)
+/**!
+ * @brief Persist and query audit logs for clean release operations.
+ */
+
+// --- candidate_repository (backend/src/services/clean_release/repositories/candidate_repository.py)
+/**!
+ * @brief Persist and query release candidates.
+ */
+
+// --- compliance_repository (backend/src/services/clean_release/repositories/compliance_repository.py)
+/**!
+ * @brief Persist and query compliance runs, stage runs, and violations.
+ */
+
+// --- ManifestRepositoryModule (backend/src/services/clean_release/repositories/manifest_repository.py)
+/**!
+ * @brief Persist and query distribution manifests.
+ */
+
+// --- ManifestRepository (backend/src/services/clean_release/repositories/manifest_repository.py)
+/**!
+ * @brief Encapsulates database CRUD operations for DistributionManifest entities.
+ */
+
+// --- policy_repository (backend/src/services/clean_release/repositories/policy_repository.py)
+/**!
+ * @brief Persist and query policy and registry snapshots.
+ */
+
+// --- publication_repository (backend/src/services/clean_release/repositories/publication_repository.py)
+/**!
+ * @brief Persist and query publication records.
+ */
+
+// --- report_repository (backend/src/services/clean_release/repositories/report_repository.py)
+/**!
+ * @brief Persist and query compliance reports.
+ */
+
+// --- RepositoryRelations (backend/src/services/clean_release/repository.py)
+/**!
+ * @brief Provide repository adapter for clean release entities with deterministic access methods.
+ * @invariant Repository operations are side-effect free outside explicit save/update calls.
+ * @post Repository operations exported
+ * @pre In-memory storage initialized
+ */
+
+// --- CleanReleaseRepository (backend/src/services/clean_release/repository.py)
+/**!
+ * @brief Data access object for clean release lifecycle.
+ */
+
+// --- SourceIsolation (backend/src/services/clean_release/source_isolation.py)
+/**!
+ * @brief Validate that all resource endpoints belong to the approved internal source registry.
+ * @invariant Any endpoint outside enabled registry entries is treated as external-source violation.
+ * @post Source isolation violations identified
+ * @pre Source registry configured
+ */
+
+// --- ComplianceStages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Define compliance stage order and helper functions for deterministic run-state evaluation.
+ * @invariant Stage order remains deterministic for all compliance runs.
+ */
+
+// --- build_default_stages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Build default deterministic stage pipeline implementation order.
+ * @post Returns stage instances in mandatory execution order.
+ * @pre None.
+ */
+
+// --- stage_result_map (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Convert stage result list to dictionary by stage name.
+ * @post Returns stage->status dictionary for downstream evaluation.
+ * @pre stage_results may be empty or contain unique stage names.
+ */
+
+// --- missing_mandatory_stages (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Identify mandatory stages that are absent from run results.
+ * @post Returns ordered list of missing mandatory stages.
+ * @pre stage_status_map contains zero or more known stage statuses.
+ */
+
+// --- derive_final_status (backend/src/services/clean_release/stages/__init__.py)
+/**!
+ * @brief Derive final run status from stage results with deterministic blocking behavior.
+ * @post Returns one of PASSED/BLOCKED/ERROR according to mandatory stage outcomes.
+ * @pre Stage statuses correspond to compliance checks.
+ */
+
+// --- ComplianceStageBase (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Define shared contracts and helpers for pluggable clean-release compliance stages.
+ * @invariant Stage execution is deterministic for equal input context.
+ */
+
+// --- ComplianceStageContext (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Immutable input envelope passed to each compliance stage.
+ */
+
+// --- StageExecutionResult (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Structured stage output containing decision, details and violations.
+ */
+
+// --- ComplianceStage (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Protocol for pluggable stage implementations.
+ */
+
+// --- build_stage_run_record (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Build persisted stage run record from stage result.
+ * @post Returns ComplianceStageRun with deterministic identifiers and timestamps.
+ * @pre run_id and stage_name are non-empty.
+ */
+
+// --- build_violation (backend/src/services/clean_release/stages/base.py)
+/**!
+ * @brief Construct a compliance violation with normalized defaults.
+ * @post Returns immutable-style violation payload ready for persistence.
+ * @pre run_id, stage_name, code and message are non-empty.
+ */
+
+// --- data_purity (backend/src/services/clean_release/stages/data_purity.py)
+/**!
+ * @brief Evaluate manifest purity counters and emit blocking violations for prohibited artifacts.
+ * @invariant prohibited_detected_count > 0 always yields BLOCKED stage decision.
+ */
+
+// --- DataPurityStage (backend/src/services/clean_release/stages/data_purity.py)
+/**!
+ * @brief Validate manifest summary for prohibited artifacts.
+ * @post Returns PASSED when no prohibited artifacts are detected, otherwise BLOCKED with violations.
+ * @pre context.manifest.content_json contains summary block or defaults to safe counters.
+ */
+
+// --- internal_sources_only (backend/src/services/clean_release/stages/internal_sources_only.py)
+/**!
+ * @brief Verify manifest-declared sources belong to trusted internal registry allowlist.
+ * @invariant Any source host outside allowed_hosts yields BLOCKED decision with at least one violation.
+ */
+
+// --- InternalSourcesOnlyStage (backend/src/services/clean_release/stages/internal_sources_only.py)
+/**!
+ * @brief Enforce internal-source-only policy from trusted registry snapshot.
+ * @post Returns PASSED when all hosts are allowed; otherwise BLOCKED and violations captured.
+ * @pre context.registry.allowed_hosts is available.
+ */
+
+// --- manifest_consistency (backend/src/services/clean_release/stages/manifest_consistency.py)
+/**!
+ * @brief Ensure run is bound to the exact manifest snapshot and digest used at run creation time.
+ * @invariant Digest mismatch between run and manifest yields ERROR with blocking violation evidence.
+ */
+
+// --- ManifestConsistencyStage (backend/src/services/clean_release/stages/manifest_consistency.py)
+/**!
+ * @brief Validate run/manifest linkage consistency.
+ * @post Returns PASSED when digests match, otherwise ERROR with one violation.
+ * @pre context.run and context.manifest are loaded from repository for same run.
+ */
+
+// --- no_external_endpoints (backend/src/services/clean_release/stages/no_external_endpoints.py)
+/**!
+ * @brief Block manifest payloads that expose external endpoints outside trusted schemes and hosts.
+ * @invariant Endpoint outside allowed scheme/host always yields BLOCKED stage decision.
+ */
+
+// --- NoExternalEndpointsStage (backend/src/services/clean_release/stages/no_external_endpoints.py)
+/**!
+ * @brief Validate endpoint references from manifest against trusted registry.
+ * @post Returns PASSED when all endpoints are trusted, otherwise BLOCKED with endpoint violations.
+ * @pre context.registry includes allowed hosts and schemes.
+ */
+
+// --- dataset_review (backend/src/services/dataset_review/__init__.py)
+/**!
+ * @brief Provides services for dataset-centered orchestration flow.
+ */
+
+// --- ClarificationEngine (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Manage one-question-at-a-time clarification state, deterministic answer persistence, and readiness/finding updates.
+ * @invariant Only one active clarification question may exist at a time; skipped and expert-review items remain unresolved and visible.
+ * @post Active clarification payload exposes one highest-priority unresolved question, and each recorded answer is persisted before pointer/readiness mutation.
+ * @pre Target session contains a persisted clarification aggregate in the current ownership scope.
+ */
+
+// --- ClarificationQuestionPayload (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Typed active-question payload returned to the API layer.
+ */
+
+// --- ClarificationStateResult (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Clarification state result carrying the current session, active payload, and changed findings.
+ */
+
+// --- ClarificationAnswerCommand (backend/src/services/dataset_review/clarification_engine.py)
+/**!
+ * @brief Typed answer command for clarification state mutation.
+ */
+
+// --- ClarificationHelpers (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Pure helper functions for clarification engine — question selection, counting, normalization, finding upsert, and readiness derivation.
+ */
+
+// --- select_next_open_question (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Select the next unresolved question in deterministic priority order.
+ */
+
+// --- count_resolved_questions (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Count questions whose answers fully resolved the ambiguity.
+ */
+
+// --- count_remaining_questions (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Count questions still unresolved or deferred after clarification interaction.
+ */
+
+// --- normalize_answer_value (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Validate and normalize answer payload based on answer kind and active question options.
+ */
+
+// --- build_impact_summary (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Build a compact audit note describing how the clarification answer affects session state.
+ */
+
+// --- upsert_clarification_finding (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Keep one finding per clarification topic aligned with answer outcome and unresolved visibility rules.
+ */
+
+// --- derive_readiness_state (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Recompute readiness after clarification mutation while preserving unresolved visibility semantics.
+ */
+
+// --- derive_recommended_action (backend/src/services/dataset_review/clarification_pkg/_helpers.py)
+/**!
+ * @brief Recompute next-action guidance after clarification mutations.
+ */
+
+// --- SessionEventLoggerModule (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Persist explicit session mutation events for dataset-review audit trails without weakening ownership or approval invariants.
+ * @post Every logged event is committed as an explicit, queryable audit record with deterministic event metadata.
+ * @pre Caller provides an owned session scope and an authenticated actor identifier for each persisted mutation event.
+ */
+
+// --- SessionEventLoggerImports (backend/src/services/dataset_review/event_logger.py)
+/**!
+ */
+
+// --- SessionEventPayload (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Typed input contract for one persisted dataset-review session audit event.
+ */
+
+// --- SessionEventLogger (backend/src/services/dataset_review/event_logger.py)
+/**!
+ * @brief Persist explicit dataset-review session audit events with meaningful runtime reasoning logs.
+ * @post Returns the committed session event row with a stable identifier and stored detail payload.
+ * @pre The database session is live and payload identifiers are non-empty.
+ */
+
+// --- DatasetReviewOrchestrator (backend/src/services/dataset_review/orchestrator.py)
+/**!
+ * @brief Coordinate dataset review session startup and lifecycle-safe intake recovery for one authenticated user.
+ * @invariant Launch is blocked unless a current session has no open blocking findings, all launch-sensitive mappings are approved, and a non-stale Superset-generated compiled preview matches the current input fingerprint.
+ * @post state transitions are persisted atomically and emit observable progress for long-running steps.
+ * @pre session mutations must execute inside a persisted session boundary scoped to one authenticated user.
+ */
+
+// --- OrchestratorCommands (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed command and result dataclasses for dataset review orchestration boundary.
+ */
+
+// --- StartSessionCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for starting a dataset review session.
+ */
+
+// --- StartSessionResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Session-start result carrying the persisted session and intake recovery metadata.
+ */
+
+// --- PreparePreviewCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for compiling one Superset-backed session preview.
+ */
+
+// --- PreparePreviewResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Result contract for one persisted compiled preview attempt.
+ */
+
+// --- LaunchDatasetCommand (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Typed input contract for launching one dataset-review session into SQL Lab.
+ */
+
+// --- LaunchDatasetResult (backend/src/services/dataset_review/orchestrator_pkg/_commands.py)
+/**!
+ * @brief Launch result carrying immutable run context and any gate blockers.
+ */
+
+// --- OrchestratorHelpers (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Pure helper methods extracted from DatasetReviewOrchestrator for INV_7 compliance — snapshot, blockers, fingerprint, recovery bootstrap.
+ * @post Helper results are deterministic and do not mutate persistence directly.
+ * @pre Caller provides a loaded session aggregate with hydrated child collections.
+ */
+
+// --- parse_dataset_selection (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Normalize dataset-selection payload into canonical session references.
+ */
+
+// --- build_initial_profile (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Create the first profile snapshot so exports and detail views remain usable immediately after intake.
+ */
+
+// --- build_partial_recovery_findings (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Project partial Superset intake recovery into explicit findings without blocking session usability.
+ * @post Returns warning-level findings that preserve usable but incomplete state.
+ * @pre parsed_context.partial_recovery is true.
+ */
+
+// --- extract_effective_filter_value (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Separate normalized filter payload metadata from the user-facing effective filter value.
+ */
+
+// --- build_execution_snapshot (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Build effective filters, template params, approvals, and fingerprint for preview and launch gating.
+ * @post Returns deterministic execution snapshot for current session state without mutating persistence.
+ * @pre Session aggregate includes imported filters, template variables, and current execution mappings.
+ */
+
+// --- build_launch_blockers (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Enforce launch gates from findings, approvals, and current preview truth.
+ * @post Returns explicit blocker codes for every unmet launch invariant.
+ * @pre execution_snapshot was computed from current session state.
+ */
+
+// --- get_latest_preview (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Resolve the current latest preview snapshot for one session aggregate.
+ */
+
+// --- compute_preview_fingerprint (backend/src/services/dataset_review/orchestrator_pkg/_helpers.py)
+/**!
+ * @brief Produce deterministic execution fingerprint for preview truth and staleness checks.
+ */
+
+// --- SessionRepositoryMutations (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persistence mutation operations for dataset review session aggregates — profile/findings, recovery state, preview, run context.
+ * @post Session aggregate writes preserve ownership and version semantics.
+ * @pre All mutations execute within authenticated request or task scope.
+ */
+
+// --- save_profile_and_findings (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist profile state and replace validation findings for an owned session in one transaction.
+ * @post stored profile matches the current session and findings are replaced by the supplied collection.
+ * @pre session_id belongs to user_id and the supplied profile/findings belong to the same aggregate scope.
+ */
+
+// --- save_recovery_state (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist imported filters, template variables, and initial execution mappings for one owned session.
+ * @post Recovery state persisted to database.
+ * @pre session_id belongs to user_id.
+ */
+
+// --- save_preview (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist a preview snapshot and mark prior session previews stale.
+ * @post preview is persisted and the session points to the latest preview identifier.
+ * @pre session_id belongs to user_id and preview is prepared for the same session aggregate.
+ */
+
+// --- save_run_context (backend/src/services/dataset_review/repositories/repository_pkg/_mutations.py)
+/**!
+ * @brief Persist an immutable launch audit snapshot for an owned session.
+ * @post run context is persisted and linked as the latest launch snapshot for the session.
+ * @pre session_id belongs to user_id and run_context targets the same aggregate.
+ */
+
+// --- DatasetReviewSessionRepository (backend/src/services/dataset_review/repositories/session_repository.py)
+/**!
+ * @brief Persist and retrieve dataset review session aggregates, including readiness, findings, semantic decisions, clarification state, previews, and run contexts.
+ * @invariant answers, mapping approvals, preview artifacts, and launch snapshots are never attributed to the wrong user or session.
+ * @post session aggregate reads are structurally consistent and writes preserve ownership and version semantics.
+ * @pre repository operations execute within authenticated request or task scope.
+ */
+
+// --- DatasetReviewSessionVersionConflictError (backend/src/services/dataset_review/repositories/session_repository.py)
+/**!
+ * @brief Signal optimistic-lock conflicts for dataset review session mutations.
+ */
+
+// --- SemanticSourceResolver (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ * @brief Resolve and rank semantic candidates from trusted dictionary-like sources before any inferred fallback.
+ * @invariant Manual overrides are never silently replaced by imported, inferred, or AI-generated values.
+ * @post candidate ranking follows the configured confidence hierarchy and unresolved fuzzy matches remain reviewable.
+ * @pre selected source and target field set must be known.
+ */
+
+// --- imports (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ */
+
+// --- DictionaryResolutionResult (backend/src/services/dataset_review/semantic_resolver.py)
+/**!
+ * @brief Carries field-level dictionary resolution output with explicit review and partial-recovery state.
+ */
+
+// --- GitServiceModule (backend/src/services/git/__init__.py)
+/**!
+ * @brief Composed GitService via multiple inheritance from domain-specific mixins.
+ */
+
+// --- GitService (backend/src/services/git/__init__.py)
+/**!
+ * @brief Composed GitService class providing all Git operations — init, clone, branches, commits, push, pull,
+ */
+
+// --- GitServiceBase (backend/src/services/git/_base.py)
+/**!
+ * @brief Core GitService base class — initialization, path resolution, repo lifecycle (init/delete/get), identity configuration, concurrent locking, and shared HTTP client pool.
+ */
+
+// --- GitServiceBranchMixin (backend/src/services/git/_branch.py)
+/**!
+ * @brief Branch and commit operations for GitService — gitflow branches, list/create/checkout branches, commit changes (all concurrent-safe via per-dashboard locks).
+ */
+
+// --- GitServiceGiteaMixin (backend/src/services/git/_gitea.py)
+/**!
+ * @brief Gitea API operations for GitService — connection testing, repository CRUD, and pull request creation. Uses shared self._http_client for connection pooling.
+ */
+
+// --- GitServiceMergeMixin (backend/src/services/git/_merge.py)
+/**!
+ * @brief Merge operations for GitService — conflict detection, resolution, abort, continue, and direct promote (all concurrent-safe via per-dashboard locks).
+ */
+
+// --- GitServiceRemoteMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief GitHub and GitLab provider operations for GitService — repository creation and PR/MR creation. Uses shared self._http_client for connection pooling.
+ */
+
+// --- GitServiceGithubMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief Mixin providing GitHub API operations for GitService.
+ */
+
+// --- GitServiceGitlabMixin (backend/src/services/git/_remote_providers.py)
+/**!
+ * @brief Mixin providing GitLab API operations for GitService.
+ */
+
+// --- GitServiceStatusMixin (backend/src/services/git/_status.py)
+/**!
+ * @brief Status, diff, and commit history operations for GitService (all concurrent-safe via per-dashboard locks).
+ */
+
+// --- GitServiceSyncMixin (backend/src/services/git/_sync.py)
+/**!
+ * @brief Push and pull operations for GitService with origin host auto-alignment (concurrent-safe).
+ */
+
+// --- GitServiceUrlMixin (backend/src/services/git/_url.py)
+/**!
+ * @brief URL helper mixin for GitService — parse, normalize, align, and strip credentials from Git URLs.
+ */
+
+// --- health_service (backend/src/services/health_service.py)
+/**!
+ * @brief Business logic for aggregating dashboard health status from validation records.
+ */
+
+// --- HealthService (backend/src/services/health_service.py)
+/**!
+ * @brief Aggregate latest dashboard validation state and manage persisted health report lifecycle.
+ * @post Exposes health summary aggregation and validation report deletion operations.
+ * @pre Service is constructed with a live SQLAlchemy session and optional config manager.
+ */
+
+// --- llm_prompt_templates (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Provide default LLM prompt templates and normalization helpers for runtime usage.
+ * @invariant All required prompt template keys are always present after normalization.
+ */
+
+// --- DEFAULT_LLM_PROMPTS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default prompt templates used by documentation, dashboard validation, and git commit generation.
+ */
+
+// --- DEFAULT_LLM_PROVIDER_BINDINGS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default provider binding per task domain.
+ */
+
+// --- DEFAULT_LLM_ASSISTANT_SETTINGS (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Default planner settings for assistant chat intent model/provider resolution.
+ */
+
+// --- normalize_llm_settings (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Ensure llm settings contain stable schema with prompts section and default templates.
+ * @post Returned dict contains prompts with all required template keys.
+ * @pre llm_settings is dictionary-like value or None.
+ */
+
+// --- is_multimodal_model (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Heuristically determine whether model supports image input required for dashboard validation.
+ * @deprecated Use the explicit `db_provider.is_multimodal` flag instead (see migration 9f8e7d6c5b4a).
+ */
+
+// --- resolve_bound_provider_id (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Resolve provider id configured for a task binding with fallback to default provider.
+ * @post Returns configured provider id or fallback id/empty string when not defined.
+ * @pre llm_settings is normalized or raw dict from config.
+ */
+
+// --- render_prompt (backend/src/services/llm_prompt_templates.py)
+/**!
+ * @brief Render prompt template using deterministic placeholder replacement with graceful fallback.
+ * @post Returns rendered prompt text with known placeholders substituted. Warns about unfilled placeholders.
+ * @pre template is a string and variables values are already stringifiable.
+ */
+
+// --- llm_provider (backend/src/services/llm_provider.py)
+/**!
+ * @brief Service for managing LLM provider configurations with encrypted API keys.
+ */
+
+// --- mask_api_key (backend/src/services/llm_provider.py)
+/**!
+ * @brief Mask an API key for safe display, showing first 4 and last 4 characters.
+ * @post Returns "****" for very short keys; "{first 2}...{last 2}" for <=8 chars;
+ * @pre api_key is a plaintext string or None.
+ */
+
+// --- is_masked_or_placeholder (backend/src/services/llm_provider.py)
+/**!
+ * @brief Predicate: True when api_key is None, empty, "********", or contains "...".
+ * @post Returns True only for non-real-key values.
+ * @pre api_key can be None.
+ */
+
+// --- _require_fernet_key (backend/src/services/llm_provider.py)
+/**!
+ * @brief Load and validate the Fernet key used for secret encryption.
+ * @invariant Encryption initialization never falls back to a hardcoded secret.
+ * @post Returns validated key bytes ready for Fernet initialization.
+ * @pre ENCRYPTION_KEY environment variable must be set to a valid Fernet key.
+ */
+
+// --- EncryptionManager (backend/src/services/llm_provider.py)
+/**!
+ * @brief Handles encryption and decryption of sensitive data like API keys.
+ * @invariant Uses only a validated secret key from environment.
+ * @post Manager exposes reversible encrypt/decrypt operations for persisted secrets.
+ * @pre ENCRYPTION_KEY is configured with a valid Fernet key before instantiation.
+ */
+
+// --- LLMProviderService (backend/src/services/llm_provider.py)
+/**!
+ * @brief Service to manage LLM provider lifecycle.
+ */
+
+// --- MaintenancePackage (backend/src/services/maintenance/__init__.py)
+/**!
+ * @brief Maintenance Banner service package. Re-exports all public orchestrators and helpers.
+ */
+
+// --- MaintenanceBannerRenderer (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Banner text rendering and rebuild helpers. Build aggregated markdown from
+ */
+
+// --- build_banner_text (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Build aggregated banner markdown text from events using settings template.
+ */
+
+// --- _build_banner_text_for_dashboard (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Build aggregated banner text for a banner based on all active events linked to it.
+ */
+
+// --- rebuild_banner (backend/src/services/maintenance/_banner_renderer.py)
+/**!
+ * @brief Rebuild aggregated banner text for a banner and update the Superset chart.
+ */
+
+// --- MaintenanceChartManager (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Chart operations for maintenance banners: create/get banner charts, process
+ */
+
+// --- ensure_banner_chart (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Get or create a MaintenanceDashboardBanner for a dashboard in the target environment.
+ */
+
+// --- _process_dashboards_for_start (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Process each dashboard for a start maintenance event: ensure banner chart,
+ */
+
+// --- _process_states_for_end (backend/src/services/maintenance/_chart_manager.py)
+/**!
+ * @brief Process each dashboard state for an end maintenance event: if other events
+ */
+
+// --- MaintenanceDashboardScanner (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Dashboard discovery and filtering helpers for maintenance banner feature.
+ */
+
+// --- find_affected_dashboards (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Find all dashboard IDs whose datasets reference any of the given tables.
+ */
+
+// --- _get_linked_dashboards (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Fetch linked dashboards for a dataset from Superset.
+ */
+
+// --- _apply_dashboard_filters (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Apply scope (published/draft/all), excluded, and forced filters from settings.
+ */
+
+// --- _resolve_dashboard_title (backend/src/services/maintenance/_dashboard_scanner.py)
+/**!
+ * @brief Resolve dashboard title from Superset by ID.
+ */
+
+// --- MaintenanceOrchestrators (backend/src/services/maintenance/_orchestrators.py)
+/**!
+ * @brief C4 orchestrators for maintenance event lifecycle: start, end, end-all.
+ */
+
+// --- build_idempotency_key (backend/src/services/maintenance/_orchestrators.py)
+/**!
+ * @brief Build idempotency key from (tables, start_time, end_time). Sorted lowercased tables, ISO timestamps.
+ * @post Returns a tuple of (frozenset(str), str|None, str|None) for DB comparison.
+ * @pre tables is a list of strings. start_time is a datetime or None. end_time is a datetime or None.
+ */
+
+// --- mapping_service (backend/src/services/mapping_service.py)
+/**!
+ * @brief Orchestrates database fetching and fuzzy matching suggestions.
+ * @invariant Suggestions are based on database names.
+ * @post Exposes stateless mapping suggestion orchestration over configured environments.
+ * @pre source/target environment identifiers are provided by caller.
+ */
+
+// --- MappingService (backend/src/services/mapping_service.py)
+/**!
+ * @brief Service for handling database mapping logic.
+ * @post Provides client resolution and mapping suggestion methods.
+ * @pre config_manager exposes get_environments() with environment objects containing id.
+ */
+
+// --- notifications (backend/src/services/notifications/__init__.py)
+/**!
+ * @brief Notification service package root.
+ */
+
+// --- providers (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Defines abstract base and concrete implementations for external notification delivery.
+ * @invariant Sensitive credentials must be handled via encrypted config.
+ * @post Each provider exposes async send contract returning boolean delivery outcome.
+ * @pre Provider configuration dictionaries are supplied by trusted configuration sources.
+ */
+
+// --- NotificationProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Abstract base class for all notification providers.
+ */
+
+// --- SMTPProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via SMTP.
+ */
+
+// --- TelegramProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via Telegram Bot API.
+ */
+
+// --- SlackProvider (backend/src/services/notifications/providers.py)
+/**!
+ * @brief Delivers notifications via Slack Webhooks or API.
+ */
+
+// --- service (backend/src/services/notifications/service.py)
+/**!
+ * @brief Orchestrates notification routing based on user preferences and policy context.
+ * @invariant NotificationService maintains singleton pattern for per-channel notifications
+ * @post Notification dispatched via configured providers
+ * @pre channel_config is loaded
+ */
+
+// --- NotificationService (backend/src/services/notifications/service.py)
+/**!
+ * @brief Routes validation reports to appropriate users and channels.
+ * @post Service can resolve targets and dispatch provider sends without mutating validation records.
+ * @pre Service receives a live DB session and configuration manager with notification payload settings.
+ */
+
+// --- profile_preference_service (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Profile preference persistence — read, update, and normalize user dashboard filter preferences
+ */
+
+// --- ProfilePreferenceService (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Handles profile preference persistence, validation, and token encryption.
+ * @post Preference CRUD operations are user-scoped and return normalized ProfilePreferenceResponse.
+ * @pre db session is active.
+ */
+
+// --- get_my_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return current user's persisted preference or default non-configured view.
+ * @post Returned payload belongs to current_user only.
+ * @pre current_user is authenticated.
+ */
+
+// --- get_dashboard_filter_binding (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return only dashboard-filter fields required by dashboards listing hot path.
+ * @post Returns normalized username and profile-default filter toggles without security summary expansion.
+ * @pre current_user is authenticated.
+ */
+
+// --- update_my_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Validate and persist current user's profile preference in self-scoped mode.
+ * @post Preference row for current_user is created/updated when validation passes.
+ * @pre current_user is authenticated and payload is provided.
+ */
+
+// --- _to_preference_payload (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Map ORM preference row to API DTO with token metadata.
+ * @post Returns normalized ProfilePreference object.
+ * @pre preference row can contain nullable optional fields.
+ */
+
+// --- _build_default_preference (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Delegate to ProfileUtils.build_default_preference.
+ */
+
+// --- _get_preference_row (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return persisted preference row for user or None.
+ */
+
+// --- _get_or_create_preference_row (backend/src/services/profile_preference_service.py)
+/**!
+ * @brief Return existing preference row or create new unsaved row.
+ */
+
+// --- profile_service (backend/src/services/profile_service.py)
+/**!
+ * @brief Composite facade orchestrating profile preference persistence, Superset account lookup,
+ */
+
+// --- ProfileService (backend/src/services/profile_service.py)
+/**!
+ * @brief Facade that composes ProfilePreferenceService, SupersetLookupService, and
+ */
+
+// --- ProfileUtils (backend/src/services/profile_utils.py)
+/**!
+ * @brief Pure utility helpers for profile data sanitization, normalization, and secret masking.
+ */
+
+// --- ProfileValidationError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Domain validation error for profile preference update requests.
+ */
+
+// --- EnvironmentNotFoundError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Raised when environment_id from lookup request is unknown in app configuration.
+ */
+
+// --- ProfileAuthorizationError (backend/src/services/profile_utils.py)
+/**!
+ * @brief Raised when caller attempts cross-user preference mutation.
+ */
+
+// --- sanitize_text (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize optional text into trimmed form or None.
+ */
+
+// --- sanitize_secret (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize secret input into trimmed form or None.
+ */
+
+// --- sanitize_username (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize raw username into trimmed form or None for empty input.
+ */
+
+// --- normalize_username (backend/src/services/profile_utils.py)
+/**!
+ * @brief Apply deterministic trim+lower normalization for actor matching.
+ */
+
+// --- normalize_start_page (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize supported start page aliases to canonical values.
+ */
+
+// --- normalize_density (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize supported density aliases to canonical values.
+ */
+
+// --- mask_secret_value (backend/src/services/profile_utils.py)
+/**!
+ * @brief Build a safe display value for sensitive secrets.
+ */
+
+// --- validate_update_payload (backend/src/services/profile_utils.py)
+/**!
+ * @brief Validate username/toggle constraints for preference mutation.
+ * @post Returns validation errors list; empty list means valid.
+ */
+
+// --- build_default_preference (backend/src/services/profile_utils.py)
+/**!
+ * @brief Build non-persisted default preference DTO for unconfigured users.
+ */
+
+// --- normalize_owner_tokens (backend/src/services/profile_utils.py)
+/**!
+ * @brief Normalize owners payload into deduplicated lower-cased tokens.
+ */
+
+// --- rbac_permission_catalog (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Discovers declared RBAC permissions from API routes/plugins and synchronizes them into auth database.
+ */
+
+// --- HAS_PERMISSION_PATTERN (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Regex pattern for extracting has_permission("resource", "ACTION") declarations.
+ */
+
+// --- ROUTES_DIR (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Absolute directory path where API route RBAC declarations are defined.
+ */
+
+// --- _iter_route_files (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Iterates API route files that may contain RBAC declarations.
+ * @post Yields Python files excluding test and cache directories.
+ * @pre ROUTES_DIR points to backend/src/api/routes.
+ */
+
+// --- _discover_route_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Extracts explicit has_permission declarations from API route source code.
+ * @post Returns unique set of (resource, action) pairs declared in route guards.
+ * @pre Route files are readable UTF-8 text files.
+ */
+
+// --- _discover_route_permissions_cached (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Cache route permission discovery because route source files are static during normal runtime.
+ * @post Returns stable discovered route permission pairs without repeated filesystem scans.
+ * @pre None.
+ */
+
+// --- _discover_plugin_execute_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Derives dynamic task permissions of form plugin:{plugin_id}:EXECUTE from plugin registry.
+ * @post Returns unique plugin EXECUTE permissions if loader is available.
+ * @pre plugin_loader is optional and may expose get_all_plugin_configs.
+ */
+
+// --- _discover_plugin_execute_permissions_cached (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Cache dynamic plugin EXECUTE permission pairs by normalized plugin id tuple.
+ * @post Returns stable permission tuple without repeated plugin catalog expansion.
+ * @pre plugin_ids is a deterministic tuple of plugin ids.
+ */
+
+// --- discover_declared_permissions (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Builds canonical RBAC permission catalog from routes and plugin registry.
+ * @post Returns union of route-declared and dynamic plugin EXECUTE permissions.
+ * @pre plugin_loader may be provided for dynamic task plugin permission discovery.
+ */
+
+// --- sync_permission_catalog (backend/src/services/rbac_permission_catalog.py)
+/**!
+ * @brief Persists missing RBAC permission pairs into auth database.
+ * @post Missing permissions are inserted; existing permissions remain untouched.
+ * @pre declared_permissions is an iterable of (resource, action) tuples.
+ */
+
+// --- reports (backend/src/services/reports/__init__.py)
+/**!
+ * @brief Report service package root.
+ */
+
+// --- normalizer (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Convert task manager task objects into canonical unified TaskReport entities with deterministic fallback behavior.
+ * @invariant Normalizer instance maintains consistent field order
+ * @post Returns Normalizer output with normalized fields
+ * @pre session is active and valid
+ */
+
+// --- status_to_report_status (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Normalize internal task status to canonical report status.
+ * @post Always returns one of canonical ReportStatus values.
+ * @pre status may be known or unknown string/enum value.
+ */
+
+// --- build_summary (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Build deterministic user-facing summary from task payload and status.
+ * @post Returns non-empty summary text.
+ * @pre report_status is canonical; plugin_id may be unknown.
+ */
+
+// --- extract_error_context (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Extract normalized error context and next actions for failed/partial reports.
+ * @post Returns ErrorContext for failed/partial when context exists; otherwise None.
+ * @pre task is a valid Task object.
+ */
+
+// --- normalize_task_report (backend/src/services/reports/normalizer.py)
+/**!
+ * @brief Convert one Task to canonical TaskReport envelope.
+ * @post Returns TaskReport with required fields and deterministic fallback behavior.
+ * @pre task has valid id and plugin_id fields.
+ */
+
+// --- report_service (backend/src/services/reports/report_service.py)
+/**!
+ * @brief Aggregate, normalize, filter, and paginate task reports for unified list/detail API use cases.
+ * @invariant ReportService maintains consistent report structure
+ * @post Returns Report with generated summary
+ * @pre session is active and valid
+ */
+
+// --- ReportsService (backend/src/services/reports/report_service.py)
+/**!
+ * @brief Service layer for list/detail report retrieval and normalization.
+ * @invariant Service methods are read-only over task history source.
+ * @post Provides deterministic list/detail report responses.
+ * @pre TaskManager dependency is initialized.
+ */
+
+// --- type_profiles (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Deterministic mapping of plugin/task identifiers to canonical report task types and fallback profile metadata.
+ */
+
+// --- PLUGIN_TO_TASK_TYPE (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Maps plugin identifiers to normalized report task types.
+ */
+
+// --- TASK_TYPE_PROFILES (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Profile metadata registry for each normalized task type.
+ */
+
+// --- resolve_task_type (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Resolve canonical task type from plugin/task identifier with guaranteed fallback.
+ * @post Always returns one of TaskType enum values.
+ * @pre plugin_id may be None or unknown.
+ */
+
+// --- get_type_profile (backend/src/services/reports/type_profiles.py)
+/**!
+ * @brief Return deterministic profile metadata for a task type.
+ * @post Returns a profile dict and never raises for unknown types.
+ * @pre task_type may be known or unknown.
+ */
+
+// --- ResourceServiceModule (backend/src/services/resource_service.py)
+/**!
+ * @brief Shared service for fetching resource data with Git status and task status
+ * @invariant All resources include metadata about their current state
+ */
+
+// --- ResourceService (backend/src/services/resource_service.py)
+/**!
+ * @brief Provides centralized access to resource data with enhanced metadata
+ */
+
+// --- security_badge_service (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Builds security summary and permission badges for profile UI — role extraction,
+ */
+
+// --- SecurityBadgeService (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Builds security summary with role names and permission badges for profile UI display.
+ * @post build_security_summary returns ProfileSecuritySummary with deterministic sorted permissions.
+ * @pre plugin_loader may be None for degraded permission discovery.
+ */
+
+// --- build_security_summary (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Build read-only security snapshot with role and permission badges.
+ * @post Returns deterministic security projection for profile UI.
+ * @pre current_user is authenticated.
+ */
+
+// --- _collect_user_permission_pairs (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Collect effective permission tuples from current user's roles.
+ * @post Returns unique normalized (resource, ACTION) tuples.
+ * @pre current_user can include role/permission graph.
+ */
+
+// --- _format_permission_key (backend/src/services/security_badge_service.py)
+/**!
+ * @brief Convert normalized permission pair to compact UI key.
+ */
+
+// --- SqlTableExtractorModule (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Three-phase SQL+Jinja table name extractor for virtual datasets as per FR-003.
+ */
+
+// --- detect_jinja_spans (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 1: Split raw SQL text into Jinja spans and SQL spans.
+ * @post Returns a list of (span_type: str, text: str) tuples.
+ * @pre raw_sql is a string (possibly empty).
+ */
+
+// --- extract_tables_from_jinja (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 2: Extract "schema.table" references from Jinja string values.
+ */
+
+// --- is_string_literal (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Check if a sqlparse Token is a string literal (not a schema.table identifier).
+ * @post Returns True if the token is a string/Single/Literal.String.
+ * @pre token is a sqlparse Token.
+ */
+
+// --- extract_tables_from_sql_span (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Phase 3: Extract schema.table references from SQL text using regex + sqlparse filtering.
+ */
+
+// --- extract_tables_from_sql (backend/src/services/sql_table_extractor.py)
+/**!
+ * @brief Three-phase entry point: extract all schema.table references from raw SQL+Jinja text.
+ * @post Returns a set of lowercased fully-qualified table names (schema.table format).
+ * @pre raw_sql is a string (possibly empty).
+ */
+
+// --- superset_lookup_service (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Environment-scoped Superset account lookup with degradation fallback for network failures.
+ */
+
+// --- SupersetLookupService (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Resolves environments and queries Superset users in selected environment,
+ */
+
+// --- _resolve_environment (backend/src/services/superset_lookup_service.py)
+/**!
+ * @brief Resolve environment model from configured environments by id.
+ * @post Returns environment object when found else None.
+ * @pre environment_id is provided.
+ */
+
+// --- ValidationRunService (backend/src/services/validation_run_service.py)
+/**!
+ * @brief Business logic for validation run queries: list, detail, delete.
+ */
+
+// --- _resolve_task_name (backend/src/services/validation_run_service.py)
+/**!
+ */
+
+// --- ValidationService (backend/src/services/validation_service.py)
+/**!
+ * @brief Business logic for validation task CRUD and trigger-run.
+ */
+
+// --- ValidationTaskService (backend/src/services/validation_service.py)
+/**!
+ * @brief Validation task (policy) CRUD with provider validation and trigger-run.
+ */
+
+// --- _validate_provider (backend/src/services/validation_service.py)
+/**!
+ */
+
+// --- _validate_environment (backend/src/services/validation_service.py)
+/**!
+ */
+
+// --- _policy_to_response (backend/src/services/validation_service.py)
+/**!
+ */
+
+// --- TestSessionConfig (backend/tests/conftest.py)
+/**!
+ * @brief Shared pytest fixtures and session configuration for backend tests.
+ * @post Database tables exist before test session executes.
+ * @pre All test modules use sys.path patching to import from src/.
+ */
+
+// --- TestArchiveParser (backend/tests/core/migration/test_archive_parser.py)
+/**!
+ * @brief Unit tests for MigrationArchiveParser ZIP extraction contract.
+ */
+
+// --- test_extract_objects_from_zip_collects_all_types (backend/tests/core/migration/test_archive_parser.py)
+/**!
+ * @brief Verify archive parser collects dashboard/chart/dataset YAML objects into typed buckets.
+ */
+
+// --- TestDryRunOrchestrator (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Unit tests for MigrationDryRunService diff and risk computation contracts.
+ */
+
+// --- _load_fixture (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Load canonical migration dry-run fixture payload used by deterministic orchestration assertions.
+ */
+
+// --- test_migration_dry_run_service_builds_diff_and_risk (backend/tests/core/migration/test_dry_run_orchestrator.py)
+/**!
+ * @brief Verify dry-run orchestration returns stable diff summary and required risk codes.
+ */
+
+// --- test_git_service_get_repo_path_guard (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_get_repo_path_recreates_base_dir (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_superset_client_import_dashboard_guard (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_init_repo_reclones_when_path_is_not_a_git_repo (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_ensure_gitflow_branches_creates_and_pushes_missing_defaults (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- test_git_service_configure_identity_updates_repo_local_config (backend/tests/core/test_defensive_guards.py)
+/**!
+ */
+
+// --- TestGitServiceGiteaPr (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Validate Gitea PR creation fallback behavior when configured server URL is stale.
+ * @invariant A 404 from primary Gitea URL retries once against remote-url host when different.
+ */
+
+// --- test_derive_server_url_from_remote_strips_credentials (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Ensure helper returns host base URL and removes embedded credentials.
+ * @post Result is scheme+host only.
+ * @pre remote_url is an https URL with username/token.
+ */
+
+// --- test_create_gitea_pull_request_retries_with_remote_host_on_404 (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Verify create_gitea_pull_request retries with remote URL host after primary 404.
+ * @post Method returns success payload from fallback request.
+ * @pre primary server_url differs from remote_url host.
+ */
+
+// --- test_create_gitea_pull_request_returns_branch_error_when_target_missing (backend/tests/core/test_git_service_gitea_pr.py)
+/**!
+ * @brief Ensure Gitea 404 on PR creation is mapped to actionable target-branch validation error.
+ * @post Service raises HTTPException 400 with explicit missing target branch message.
+ * @pre PR create call returns 404 and target branch is absent.
+ */
+
+// --- TestMappingService (backend/tests/core/test_mapping_service.py)
+/**!
+ * @brief Unit tests for the IdMappingService matching UUIDs to integer IDs.
+ */
+
+// --- test_sync_environment_upserts_correctly (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_id_returns_integer (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_ids_batch_returns_dict (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_updates_existing_mapping (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_skips_resources_without_uuid (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_handles_api_error_gracefully (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_id_returns_none_for_missing (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_get_remote_ids_batch_returns_empty_for_empty_input (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_mapping_service_alignment_with_test_data (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_requires_existing_env (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- test_sync_environment_deletes_stale_mappings (backend/tests/core/test_mapping_service.py)
+/**!
+ */
+
+// --- TestMigrationEngine (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Unit tests for MigrationEngine's cross-filter patching algorithms.
+ */
+
+// --- MockMappingService (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Deterministic mapping service double for native filter ID remapping scenarios.
+ * @invariant Returns mappings only for requested UUID keys present in seeded map.
+ */
+
+// --- _write_dashboard_yaml (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Serialize dashboard metadata into YAML fixture with json_metadata payload for patch tests.
+ */
+
+// --- test_patch_dashboard_metadata_replaces_chart_ids (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify native filter target chartId values are remapped via mapping service results.
+ */
+
+// --- test_patch_dashboard_metadata_replaces_dataset_ids (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify native filter target datasetId values are remapped via mapping service results.
+ */
+
+// --- test_patch_dashboard_metadata_skips_when_no_metadata (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure dashboard files without json_metadata are left unchanged by metadata patching.
+ */
+
+// --- test_patch_dashboard_metadata_handles_missing_targets (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify patching updates mapped targets while preserving unmapped native filter IDs.
+ */
+
+// --- test_extract_chart_uuids_from_archive (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify chart archive scan returns complete local chart id-to-uuid mapping.
+ */
+
+// --- test_transform_yaml_replaces_database_uuid (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure dataset YAML database_uuid fields are replaced when source UUID mapping exists.
+ */
+
+// --- test_transform_yaml_ignores_unmapped_uuid (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Ensure transform_yaml leaves dataset files untouched when database_uuid is not mapped.
+ */
+
+// --- test_transform_zip_end_to_end (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Validate full ZIP transform pipeline remaps datasets and dashboard cross-filter chart IDs.
+ */
+
+// --- test_transform_zip_invalid_path (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify transform_zip returns False when source archive path does not exist.
+ */
+
+// --- test_transform_yaml_nonexistent_file (backend/tests/core/test_migration_engine.py)
+/**!
+ * @brief Verify transform_yaml raises FileNotFoundError for missing YAML source files.
+ */
+
+// --- test_clean_release_cli (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Smoke tests for the redesigned clean release CLI.
+ */
+
+// --- test_cli_candidate_register_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify candidate-register command exits successfully for valid required arguments.
+ */
+
+// --- test_cli_manifest_build_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify candidate-register/artifact-import/manifest-build smoke path succeeds end-to-end.
+ */
+
+// --- test_cli_compliance_run_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify compliance run/status/violations/report commands complete for prepared candidate.
+ * @invariant SimpleNamespace substitutes for GlobalSettings — any field rename in GlobalSettings will silently not propagate here; re-verify on GlobalSettings schema changes.
+ */
+
+// --- test_cli_release_gate_commands_scaffold (backend/tests/scripts/test_clean_release_cli.py)
+/**!
+ * @brief Verify approve/reject/publish/revoke release-gate commands execute with valid fixtures.
+ */
+
+// --- TestCleanReleaseTui (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ * @brief Unit tests for the interactive curses TUI of the clean release process.
+ * @invariant TUI initializes, handles hotkeys (F5, F10) and safely falls back without TTY.
+ */
+
+// --- test_headless_fallback (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_initial_render (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_run_checks_f5 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_exit_f10 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_clear_history_f7 (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_tui_real_mode_bootstrap_imports_artifacts_catalog (backend/tests/scripts/test_clean_release_tui.py)
+/**!
+ */
+
+// --- test_clean_release_tui_v2 (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Smoke tests for thin-client TUI action dispatch and blocked transition behavior.
+ */
+
+// --- _build_mock_stdscr (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Build deterministic curses screen mock with default terminal geometry and exit key.
+ */
+
+// --- test_tui_f5_dispatches_run_action (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify F5 key dispatch invokes run_checks exactly once before graceful exit.
+ */
+
+// --- test_tui_f5_run_smoke_reports_blocked_state (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify blocked compliance state is surfaced after F5-triggered run action.
+ */
+
+// --- test_tui_non_tty_refuses_startup (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify non-TTY execution returns exit code 2 with actionable stderr guidance.
+ */
+
+// --- test_tui_f8_blocked_without_facade_binding (backend/tests/scripts/test_clean_release_tui_v2.py)
+/**!
+ * @brief Verify F8 path reports disabled action instead of mutating hidden facade state.
+ */
+
+// --- TestApprovalService (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Define approval gate contracts for approve/reject operations over immutable compliance evidence.
+ * @invariant Approval is allowed only for PASSED report bound to candidate; duplicate approve and foreign report must be rejected.
+ */
+
+// --- _seed_candidate_with_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Seed candidate and report fixtures for approval gate tests.
+ * @post Repository contains candidate and report linked by candidate_id.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- test_approve_rejects_blocked_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure approve is rejected when latest report final status is not PASSED.
+ * @post approve_candidate raises ApprovalGateError.
+ * @pre Candidate has BLOCKED report.
+ */
+
+// --- test_approve_rejects_foreign_report (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure approve is rejected when report belongs to another candidate.
+ * @post approve_candidate raises ApprovalGateError.
+ * @pre Candidate exists, report candidate_id differs.
+ */
+
+// --- test_approve_rejects_duplicate_approve (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure repeated approve decision for same candidate is blocked.
+ * @post Second approve_candidate call raises ApprovalGateError.
+ * @pre Candidate has already been approved once.
+ */
+
+// --- test_reject_persists_decision_without_promoting_candidate_state (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure reject decision is immutable and does not promote candidate to APPROVED.
+ * @post reject_candidate persists REJECTED decision; candidate status remains unchanged.
+ * @pre Candidate has PASSED report and CHECK_PASSED lifecycle state.
+ */
+
+// --- test_reject_then_publish_is_blocked (backend/tests/services/clean_release/test_approval_service.py)
+/**!
+ * @brief Ensure latest REJECTED decision blocks publication gate.
+ * @post publish_candidate raises PublicationGateError.
+ * @pre Candidate is rejected for passed report.
+ */
+
+// --- test_candidate_manifest_services (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Test lifecycle and manifest versioning for release candidates.
+ */
+
+// --- test_candidate_lifecycle_transitions (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify release candidate allows legal status transitions and rejects forbidden back-transitions.
+ */
+
+// --- test_manifest_versioning_and_immutability (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify manifest versions increment monotonically and older snapshots remain queryable.
+ */
+
+// --- _valid_artifacts (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Provide canonical valid artifact payload used by candidate registration tests.
+ */
+
+// --- test_register_candidate_rejects_duplicate_candidate_id (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify duplicate candidate_id registration is rejected by service invariants.
+ */
+
+// --- test_register_candidate_rejects_malformed_artifact_input (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify candidate registration rejects artifact payloads missing required fields.
+ */
+
+// --- test_register_candidate_rejects_empty_artifact_set (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify candidate registration rejects empty artifact collections.
+ */
+
+// --- test_manifest_service_rebuild_creates_new_version (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify repeated manifest build creates a new incremented immutable version.
+ */
+
+// --- test_manifest_service_existing_manifest_cannot_be_mutated (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify existing manifest snapshot remains immutable when rebuilding newer manifest version.
+ */
+
+// --- test_manifest_service_rejects_missing_candidate (backend/tests/services/clean_release/test_candidate_manifest_services.py)
+/**!
+ * @brief Verify manifest build fails with missing candidate identifier.
+ */
+
+// --- TestComplianceExecutionService (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Validate stage pipeline and run finalization contracts for compliance execution.
+ * @invariant Missing manifest prevents run startup; failed execution cannot finalize as PASSED.
+ */
+
+// --- _seed_with_candidate_policy_registry (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Build deterministic repository state for run startup tests.
+ * @post Returns repository with candidate, policy and registry; manifest is optional.
+ * @pre candidate_id and snapshot ids are non-empty.
+ */
+
+// --- test_run_without_manifest_rejected (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure compliance run cannot start when manifest is unresolved.
+ * @post start_check_run raises ValueError and no run is persisted.
+ * @pre Candidate/policy exist but manifest is missing.
+ */
+
+// --- test_task_crash_mid_run_marks_failed (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure execution crash conditions force FAILED run status.
+ * @post execute_stages persists run with FAILED status.
+ * @pre Run exists, then required dependency becomes unavailable before execute_stages.
+ */
+
+// --- test_blocked_run_finalization_blocks_report_builder (backend/tests/services/clean_release/test_compliance_execution_service.py)
+/**!
+ * @brief Ensure blocked runs require blocking violations before report creation.
+ * @post finalize keeps BLOCKED and report_builder rejects zero blocking violations.
+ * @pre Manifest contains prohibited artifacts leading to BLOCKED decision.
+ */
+
+// --- TestComplianceTaskIntegration (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify clean release compliance runs execute through TaskManager lifecycle with observable success/failure outcomes.
+ * @invariant Compliance execution triggered as task produces terminal task status and persists run evidence.
+ */
+
+// --- _seed_repository (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Prepare deterministic candidate/policy/registry/manifest fixtures for task integration tests.
+ * @post Returns initialized repository and identifiers for compliance run startup.
+ * @pre with_manifest controls manifest availability.
+ */
+
+// --- CleanReleaseCompliancePlugin (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief TaskManager plugin shim that executes clean release compliance orchestration.
+ */
+
+// --- _PluginLoaderStub (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Provide minimal plugin loader contract used by TaskManager in integration tests.
+ * @invariant has_plugin/get_plugin only acknowledge the seeded compliance plugin id.
+ */
+
+// --- _make_task_manager (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Build TaskManager with mocked persistence services for isolated integration tests.
+ * @post Returns TaskManager ready for async task execution.
+ */
+
+// --- _wait_for_terminal_task (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Poll task registry until target task reaches terminal status.
+ * @post Returns task with SUCCESS or FAILED status, otherwise raises TimeoutError.
+ * @pre task_id exists in manager registry.
+ */
+
+// --- test_compliance_run_executes_as_task_manager_task (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify successful compliance execution is observable as TaskManager SUCCESS task.
+ * @post Task ends with SUCCESS; run is persisted with SUCCEEDED status and task binding.
+ * @pre Candidate, policy and manifest are available in repository.
+ */
+
+// --- test_compliance_run_missing_manifest_marks_task_failed (backend/tests/services/clean_release/test_compliance_task_integration.py)
+/**!
+ * @brief Verify missing manifest startup failure is surfaced as TaskManager FAILED task.
+ * @post Task ends with FAILED and run history remains empty.
+ * @pre Candidate/policy exist but manifest is absent.
+ */
+
+// --- TestDemoModeIsolation (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Verify demo and real mode namespace isolation contracts before TUI integration.
+ */
+
+// --- test_resolve_namespace_separates_demo_and_real (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Ensure namespace resolver returns deterministic and distinct namespaces.
+ * @post Demo and real namespaces are different and stable.
+ * @pre Mode names are provided as user/runtime strings.
+ */
+
+// --- test_build_namespaced_id_prevents_cross_mode_collisions (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Ensure ID generation prevents demo/real collisions for identical logical IDs.
+ * @post Produced physical IDs differ by namespace prefix.
+ * @pre Same logical candidate id is used in two different namespaces.
+ */
+
+// --- test_create_isolated_repository_keeps_mode_data_separate (backend/tests/services/clean_release/test_demo_mode_isolation.py)
+/**!
+ * @brief Verify demo and real repositories do not leak state across mode boundaries.
+ * @post Candidate mutations in one mode are not visible in the other mode.
+ * @pre Two repositories are created for distinct modes.
+ */
+
+// --- TestPolicyResolutionService (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Verify trusted policy snapshot resolution contract and error guards.
+ * @invariant Resolution uses only ConfigManager active IDs and rejects runtime override attempts.
+ */
+
+// --- _config_manager (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Build deterministic ConfigManager-like stub for tests.
+ * @invariant Only settings.clean_release.active_policy_id and active_registry_id are populated; any other settings field access raises AttributeError.
+ * @post Returns object exposing get_config().settings.clean_release active IDs.
+ * @pre policy_id and registry_id may be None or non-empty strings.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_missing_profile (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure resolution fails when trusted profile is not configured.
+ * @post Raises PolicyResolutionError with missing trusted profile reason.
+ * @pre active_policy_id is None.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_missing_registry (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure resolution fails when trusted registry is not configured.
+ * @post Raises PolicyResolutionError with missing trusted registry reason.
+ * @pre active_registry_id is None and active_policy_id is set.
+ */
+
+// --- test_resolve_trusted_policy_snapshots_rejects_override_attempt (backend/tests/services/clean_release/test_policy_resolution_service.py)
+/**!
+ * @brief Ensure runtime override attempt is rejected even if snapshots exist.
+ * @post Raises PolicyResolutionError with override forbidden reason.
+ * @pre valid trusted snapshots exist in repository and override is provided.
+ */
+
+// --- TestPublicationService (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Define publication gate contracts over approved candidates and immutable publication records.
+ * @invariant Publish requires approval; revoke requires existing publication; republish after revoke is allowed as a new record.
+ */
+
+// --- _seed_candidate_with_passed_report (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Seed candidate/report fixtures for publication gate scenarios.
+ * @post Repository contains candidate and PASSED report.
+ * @pre candidate_id and report_id are non-empty.
+ */
+
+// --- test_publish_without_approval_rejected (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure publish action is blocked until candidate is approved.
+ * @post publish_candidate raises PublicationGateError.
+ * @pre Candidate has PASSED report but status is not APPROVED.
+ */
+
+// --- test_revoke_unknown_publication_rejected (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure revocation is rejected for unknown publication id.
+ * @post revoke_publication raises PublicationGateError.
+ * @pre Repository has no matching publication record.
+ */
+
+// --- test_republish_after_revoke_creates_new_active_record (backend/tests/services/clean_release/test_publication_service.py)
+/**!
+ * @brief Ensure republish after revoke is allowed and creates a new ACTIVE record.
+ * @post New publish call returns distinct publication id with ACTIVE status.
+ * @pre Candidate is APPROVED and first publication has been revoked.
+ */
+
+// --- TestReportAuditImmutability (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Validate report snapshot immutability expectations and append-only audit hook behavior for US2.
+ * @invariant Built reports are immutable snapshots; audit hooks produce append-only event traces.
+ */
+
+// --- _terminal_run (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Build deterministic terminal run fixture for report snapshot tests.
+ * @post Returns a terminal ComplianceRun suitable for report generation.
+ * @pre final_status is a valid ComplianceDecision value.
+ */
+
+// --- test_report_builder_sets_immutable_snapshot_flag (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Ensure generated report payload is marked immutable and persisted as snapshot.
+ * @post Built report has immutable=True and repository stores same immutable object.
+ * @pre Terminal run exists.
+ */
+
+// --- test_repository_rejects_report_overwrite_for_same_report_id (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Define immutability contract that report snapshots cannot be overwritten by same identifier.
+ * @post Second save for same report id is rejected with explicit immutability error.
+ * @pre Existing report with id is already persisted.
+ */
+
+// --- test_audit_hooks_emit_append_only_event_stream (backend/tests/services/clean_release/test_report_audit_immutability.py)
+/**!
+ * @brief Verify audit hooks emit one event per action call and preserve call order.
+ * @post Three calls produce three ordered info entries with molecular prefixes.
+ * @pre Logger backend is patched.
+ */
+
+// --- SupersetCompatibilityMatrixTests (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Verifies Superset preview and SQL Lab endpoint fallback strategy used by dataset-review orchestration.
+ */
+
+// --- make_adapter (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Build an adapter with a mock Superset client and deterministic environment for compatibility tests.
+ */
+
+// --- test_preview_prefers_supported_client_method_before_network_fallback (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms preview compilation uses a supported client method first when the capability exists.
+ */
+
+// --- test_preview_falls_back_across_matrix_until_supported_endpoint_returns_sql (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms preview fallback walks the compatibility matrix from preferred to legacy endpoints until one returns compiled SQL.
+ */
+
+// --- test_sql_lab_launch_falls_back_to_legacy_execute_endpoint (backend/tests/services/dataset_review/test_superset_matrix.py)
+/**!
+ * @brief Confirms SQL Lab launch falls back from modern to legacy execute endpoint and preserves canonical session reference extraction.
+ */
+
+// --- TestAPIKeyAuth (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Contract tests for API key authentication — valid key, invalid, revoked, expired, missing permission,
+ */
+
+// --- test_no_header_returns_none (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief No X-API-Key header → returns None.
+ */
+
+// --- test_valid_key_returns_principal (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Valid API key → returns APIKeyPrincipal with correct fields.
+ */
+
+// --- test_invalid_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Invalid API key → 401.
+ */
+
+// --- test_revoked_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Revoked (active=False) API key → 401.
+ */
+
+// --- test_expired_key_raises_401 (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Expired API key → 401.
+ */
+
+// --- test_api_key_auth_valid (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Valid API key with matching permission → 202.
+ */
+
+// --- test_api_key_auth_wrong_permission (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief API key lacks required permission → 403.
+ */
+
+// --- test_api_key_auth_revoked (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Revoked API key → 401.
+ */
+
+// --- test_api_key_auth_expired (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Expired API key → 401.
+ */
+
+// --- test_api_key_auth_invalid (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Non-existent key → 401.
+ */
+
+// --- test_api_key_auth_environment_scope (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Key scoped to ss-dev, request for ss-prod → 400.
+ */
+
+// --- test_api_key_auth_environment_scope_ok (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Key scoped to ss-dev, request for ss-dev → 202.
+ */
+
+// --- test_jwt_precedence (backend/tests/test_api_key_auth.py)
+/**!
+ * @brief Both valid API key + valid JWT → JWT takes precedence.
+ */
+
+// --- TestAPIKeyModel (backend/tests/test_api_key_model.py)
+/**!
+ * @brief Contract tests for the APIKey SQLAlchemy model — creation, hash storage, and field constraints.
+ */
+
+// --- clean_db (backend/tests/test_api_key_model.py)
+/**!
+ * @brief In-memory SQLite fixture for APIKey model tests.
+ */
+
+// --- test_create_api_key (backend/tests/test_api_key_model.py)
+/**!
+ * @brief Create APIKey with required fields and verify defaults.
+ */
+
+// --- test_key_hash_unique (backend/tests/test_api_key_model.py)
+/**!
+ * @brief key_hash is unique — duplicate raises IntegrityError.
+ */
+
+// --- test_prefix_length (backend/tests/test_api_key_model.py)
+/**!
+ * @brief prefix is exactly 11 characters.
+ */
+
+// --- test_active_default_true (backend/tests/test_api_key_model.py)
+/**!
+ * @brief active column defaults to True.
+ */
+
+// --- TestAPIKeyRoutes (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Contract tests for admin API key CRUD endpoints — list, create (raw key present), revoke, idempotent revoke.
+ */
+
+// --- test_list_empty (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief No keys → returns empty list.
+ */
+
+// --- test_list_with_keys (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Keys exist → returns list without raw_key or key_hash fields.
+ */
+
+// --- test_create_valid (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Valid request → 201 with raw_key, prefix, id.
+ */
+
+// --- test_create_missing_name (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Missing name → 400 or 422.
+ */
+
+// --- test_create_empty_permissions (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Empty permissions → 400 or 422.
+ */
+
+// --- test_revoke_valid (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke existing active key → 200 with status=revoked.
+ */
+
+// --- test_revoke_already_revoked (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke already revoked key → 404.
+ */
+
+// --- test_revoke_not_found (backend/tests/test_api_key_routes.py)
+/**!
+ * @brief Revoke non-existent key → 404.
+ */
+
+// --- TestAuth (backend/tests/test_auth.py)
+/**!
+ * @brief Covers authentication service/repository behavior and auth bootstrap helpers.
+ */
+
+// --- test_create_admin_creates_user_with_optional_email (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_create_admin_is_idempotent_for_existing_user (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_ensure_encryption_key_generates_backend_env_file (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_ensure_encryption_key_reuses_existing_env_file_value (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- test_ensure_encryption_key_prefers_process_environment (backend/tests/test_auth.py)
+/**!
+ */
+
+// --- TestConstantsAuditFixes (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Verify Class 5 fix — hardcoded values extracted to named module-level constants.
+ */
+
+// --- test_page_size_constant_exists (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief DEFAULT_PAGE_SIZE contract: importable, int > 0 (not yet defined in source).
+ */
+
+// --- test_llm_analysis_timeout_constants (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Named timeout constants should exist per RATIONALE comment (not yet defined).
+ */
+
+// --- test_base_dir_constant_replaces_parents (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief BASE_DIR resolves to backend/ root, not __file__-dependent relative path.
+ */
+
+// --- test_git_service_repositorys_typo_regression (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief services/git/_base.py still has "repositorys" (old typo) at line 148 — known bug.
+ */
+
+// --- test_git_default_repos_path_constant (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief DEFAULT_GIT_REPOS_PATH should be defined per RATIONALE (not yet defined).
+ */
+
+// --- test_superset_client_module_loads (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief superset_client._base is importable (no dependency on crashing modules).
+ */
+
+// --- test_constants_are_immutable (backend/tests/test_constants_audit_fixes.py)
+/**!
+ * @brief Module-level constants use int/str types (immutable by convention).
+ */
+
+// --- TestCoreScheduler (backend/tests/test_core_scheduler.py)
+/**!
+ * @brief Verify SchedulerService load_schedules and translation job add/remove contracts.
+ */
+
+// --- test_load_schedules_reloads_translation_schedules (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_add_and_remove_translation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_remove_nonexistent_translation_job_no_error (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_add_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_load_schedules_loads_validation_policies (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_creates_tasks (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_skips_missing_policy (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_skips_inactive_policy (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_trigger_validation_skips_no_dashboards (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_remove_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_remove_nonexistent_validation_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_reload_validation_policy_adds_job (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- test_reload_validation_policy_removes_job_when_policy_gone (backend/tests/test_core_scheduler.py)
+/**!
+ */
+
+// --- TestDashboardsApi (backend/tests/test_dashboards_api.py)
+/**!
+ * @brief Comprehensive contract-driven tests for Dashboard Hub API
+ */
+
+// --- test_get_dashboard_tasks_history_success (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_get_dashboard_tasks_history_sorting (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_get_dashboard_thumbnail_env_not_found (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_get_dashboard_thumbnail_202 (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_migrate_dashboards_pre_checks (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_backup_dashboards_pre_checks (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_backup_dashboards_with_schedule (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- test_task_matches_dashboard_logic (backend/tests/test_dashboards_api.py)
+/**!
+ */
+
+// --- TestDeprecationAuditFixes (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Verify Class 7 fix — is_multimodal_model should emit DeprecationWarning.
+ */
+
+// --- test_is_multimodal_model_emits_warning (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief is_multimodal_model should emit DeprecationWarning (shim not yet implemented).
+ */
+
+// --- test_multimodal_model_returns_true (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Known multimodal models (gpt-4o, claude-3, gemini) return True.
+ */
+
+// --- test_text_only_model_returns_false (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Text-only models (embedding, whisper, rerank) return False.
+ */
+
+// --- test_empty_model_returns_false (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Empty or None model name returns False without error.
+ */
+
+// --- test_case_insensitive_matching (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief Model name matching is case-insensitive.
+ */
+
+// --- test_deprecation_comment_exists (backend/tests/test_deprecation_audit_fixes.py)
+/**!
+ * @brief The source module documents the @DEPRECATED rationale in the region header.
+ */
+
+// --- TestLayoutUtils (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Contract tests for layout utility functions — _estimate_markdown_height.
+ */
+
+// --- test_empty_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Empty string returns minimum height 19.
+ */
+
+// --- test_single_line_text (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Short text without padding returns expected computed height.
+ */
+
+// --- test_content_with_padding (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Content with padding:12 — 24px added to content height.
+ */
+
+// --- test_very_long_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief Very long content (3000 chars) capped at max height 200.
+ */
+
+// --- test_html_only_content (backend/tests/test_layout_utils.py)
+/**!
+ * @brief HTML-only content (no visible text) returns minimum height 19.
+ */
+
+// --- test_log_persistence (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Unit tests for TaskLogPersistenceService.
+ */
+
+// --- TestLogPersistence (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test suite for TaskLogPersistenceService.
+ */
+
+// --- test_add_logs_single (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding a single log entry.
+ * @post Log entry persisted to database.
+ * @pre Service and session initialized.
+ */
+
+// --- test_add_logs_batch (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding multiple log entries in batch.
+ * @post All log entries persisted to database.
+ * @pre Service and session initialized.
+ */
+
+// --- test_add_logs_empty (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test adding empty log list (should be no-op).
+ * @post No logs added.
+ * @pre Service initialized.
+ */
+
+// --- test_get_logs_by_task_id (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs by task ID.
+ * @post Returns logs for the specified task.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_filters (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with level and source filters.
+ * @post Returns filtered logs.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_pagination (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with pagination.
+ * @post Returns paginated logs.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_logs_with_search (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving logs with search query.
+ * @post Returns logs matching search query.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_log_stats (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving log statistics.
+ * @post Returns LogStats model with counts by level and source.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_get_sources (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test retrieving unique log sources.
+ * @post Returns list of unique sources.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_task (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting logs by task ID.
+ * @post Logs for the task are deleted.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_tasks (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting logs for multiple tasks.
+ * @post Logs for all specified tasks are deleted.
+ * @pre Service and session initialized, logs exist.
+ */
+
+// --- test_delete_logs_for_tasks_empty (backend/tests/test_log_persistence.py)
+/**!
+ * @brief Test deleting with empty list (no-op).
+ * @post No error, no deletion.
+ * @pre Service initialized.
+ */
+
+// --- TestLogger (backend/tests/test_logger.py)
+/**!
+ * @brief Unit tests for the custom logger CoT JSON formatters and configuration context manager.
+ * @invariant All required log statements must correctly check the threshold.
+ */
+
+// --- test_belief_scope_success_coherence (backend/tests/test_logger.py)
+/**!
+ * @brief Test that belief_scope logs REFLECT marker on success.
+ * @post Logs are verified to contain REFLECT marker.
+ * @pre belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
+ */
+
+// --- test_belief_scope_reason_not_visible_at_info (backend/tests/test_logger.py)
+/**!
+ * @brief Test that belief_scope REASON/REFLECT markers are NOT visible at INFO level.
+ * @post REASON/REFLECT markers are not captured at INFO level.
+ * @pre belief_scope is available. caplog fixture is used.
+ */
+
+// --- test_cot_json_formatter_output (backend/tests/test_logger.py)
+/**!
+ * @brief Test that CotJsonFormatter produces valid JSON with expected fields.
+ */
+
+// --- test_cot_json_formatter_plain_message (backend/tests/test_logger.py)
+/**!
+ * @brief Test that CotJsonFormatter wraps plain messages (no extra) with default marker.
+ */
+
+// --- TestLoggingAuditFixes (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief Verify Class 2 fix — no bare `except: pass` patterns remain in src/.
+ */
+
+// --- _collect_src_files (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief Collect all .py files under src/ excluding test/ and mock/ directories.
+ */
+
+// --- test_except_pass_replaced_with_log (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief AST audit: bare `except: pass` nodes are absent from src/ source files.
+ */
+
+// --- test_plugin_loader_uses_logger_not_print (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py (src/core/) uses logger for error/warning, not print().
+ */
+
+// --- test_plugin_loader_imports_logger (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py imports a logger or _logger for structured reporting.
+ */
+
+// --- test_plugin_loader_logger_calls_exist (backend/tests/test_logging_audit_fixes.py)
+/**!
+ * @brief plugin_loader.py references logger.error/warning/info in its code.
+ */
+
+// --- test_maintenance_api (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Contract tests for Maintenance Banner API endpoints — T016, T025.
+ */
+
+// --- test_start_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Valid request returns 202 with task_id and maintenance_id.
+ */
+
+// --- test_start_missing_tables (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Missing tables field returns 422.
+ */
+
+// --- test_start_end_time_before_start (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief end_time before start_time returns 400.
+ */
+
+// --- test_start_too_many_tables (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief More than 100 tables returns 422 (Pydantic validation).
+ */
+
+// --- test_start_idempotency (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Same (tables, start, end) returns already_active.
+ */
+
+// --- test_end_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Valid maintenance_id returns 202.
+ */
+
+// --- test_end_not_found (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Non-existent maintenance_id returns 404.
+ */
+
+// --- test_end_all_returns_202 (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief end-all returns 202.
+ */
+
+// --- test_list_events (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Returns active and completed events.
+ */
+
+// --- test_expired_event_auto_ends (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event past end_time with ACTIVE status → create_task called with auto-end params.
+ */
+
+// --- test_future_end_time_skipped (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event with future end_time → no task created, skipped by < now filter.
+ */
+
+// --- test_no_end_time_skipped (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Event with end_time=None → no task created, skipped by isnot(None) filter.
+ */
+
+// --- test_list_banners (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief Returns list of active banners.
+ */
+
+// --- test_get_settings (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief GET returns settings.
+ */
+
+// --- test_put_settings (backend/tests/test_maintenance_api.py)
+/**!
+ * @brief PUT updates settings.
+ */
+
+// --- test_maintenance_service (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Integration tests for MaintenanceService — T018, T026, T026a.
+ */
+
+// --- test_basic_key (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Basic idempotency key with tables and times.
+ */
+
+// --- test_key_without_end_time (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Idempotency key with None end_time.
+ */
+
+// --- test_key_table_sorting (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Tables are sorted alphabetically in frozenset.
+ */
+
+// --- test_empty_tables (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Empty tables list returns empty.
+ */
+
+// --- test_table_based_match (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Table-based dataset matching.
+ */
+
+// --- test_virtual_dataset_match (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Virtual SQL dataset matching via SqlTableExtractor.
+ */
+
+// --- test_superset_api_failure (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Superset API failure propagates.
+ */
+
+// --- test_creates_new_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No existing banner — creates new chart and banner row.
+ */
+
+// --- test_returns_existing_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Existing active banner — returns it.
+ */
+
+// --- test_chart_creation_failure (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Chart creation failure propagates.
+ */
+
+// --- test_single_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Single event — direct substitution.
+ */
+
+// --- test_multiple_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Multiple events — combined message.
+ */
+
+// --- test_empty_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Empty events list returns empty string.
+ */
+
+// --- test_missing_variables (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Missing variables replaced with empty string.
+ */
+
+// --- test_html_escaping (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Message is HTML-escaped.
+ */
+
+// --- test_happy_path (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Happy path: event with matching dashboards.
+ */
+
+// --- test_no_matching_dashboards (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No dashboards match the tables.
+ */
+
+// --- test_event_not_found (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Event ID not in DB.
+ */
+
+// --- test_already_processed_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Event already ACTIVE — idempotent.
+ */
+
+// --- test_rebuild_active_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Active banner with active state — rebuilds text.
+ */
+
+// --- test_banner_not_found (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Banner ID not found.
+ */
+
+// --- test_end_active_event_single_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief End event with single active dashboard — banner removed entirely.
+ */
+
+// --- test_end_event_shared_banner (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Two events, same dashboard — ending one rebuilds banner, doesn't delete.
+ */
+
+// --- test_end_already_completed_event (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Already completed event — idempotent.
+ */
+
+// --- test_end_all_active_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief End all active events.
+ */
+
+// --- test_no_active_events (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief No active events.
+ */
+
+// --- test_mixed_active_and_completed (backend/tests/test_maintenance_service.py)
+/**!
+ * @brief Mix of active and completed events — only active get ended.
+ */
+
+// --- TestResourceHubs (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Contract tests for resource hub dashboards/datasets listing and pagination boundary validation.
+ */
+
+// --- test_dashboards_api (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify GET /api/dashboards contract compliance
+ */
+
+// --- mock_deps (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Provide dependency override fixture for resource hub route tests.
+ * @invariant unconstrained mock — no spec= enforced; attribute typos will silently pass
+ */
+
+// --- test_get_dashboards_not_found (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint returns 404 for unknown environment identifier.
+ */
+
+// --- test_get_dashboards_search (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint search filter returns matching subset.
+ */
+
+// --- test_datasets_api (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify GET /api/datasets contract compliance
+ */
+
+// --- test_get_datasets_not_found (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint returns 404 for unknown environment identifier.
+ */
+
+// --- test_get_datasets_search (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint search filter returns matching dataset subset.
+ */
+
+// --- test_get_datasets_service_failure (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint surfaces backend fetch failure as HTTP 503.
+ */
+
+// --- test_pagination_boundaries (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify pagination validation for GET endpoints
+ */
+
+// --- test_get_dashboards_pagination_zero_page (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint rejects page=0 with HTTP 400 validation error.
+ */
+
+// --- test_get_dashboards_pagination_oversize (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify dashboards endpoint rejects oversized page_size with HTTP 400.
+ */
+
+// --- test_get_datasets_pagination_zero_page (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint rejects page=0 with HTTP 400.
+ */
+
+// --- test_get_datasets_pagination_oversize (backend/tests/test_resource_hubs.py)
+/**!
+ * @brief Verify datasets endpoint rejects oversized page_size with HTTP 400.
+ */
+
+// --- TestSecurityAuditFixes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Verify Class 1 security audit fixes — env-only secrets, crash-early, CORS parsing.
+ */
+
+// --- test_missing_secret_key_crashes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig.validate_secret_key raises ValueError when value is empty (crash-early).
+ */
+
+// --- test_missing_auth_db_url_crashes (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig.validate_auth_db_url raises ValueError when URL is empty and DEV_MODE is off.
+ */
+
+// --- test_auth_db_dev_fallback_works (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief When DEV_MODE=true and AUTH_DATABASE_URL is unset, dev fallback is used without crash.
+ */
+
+// --- test_allowed_origins_parsing (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief os.getenv("ALLOWED_ORIGINS").split(",") correctly parses comma-separated origins.
+ */
+
+// --- test_cors_wildcard_default (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief When ALLOWED_ORIGINS is not set, default returns ["*"].
+ */
+
+// --- test_cors_parsing_single_value (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Single origin returns single-element list.
+ */
+
+// --- test_cors_parsing_with_trailing_spaces (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief Origins with trailing spaces are preserved (no strip).
+ */
+
+// --- test_database_url_env_override (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief DATABASE_URL env var takes precedence over POSTGRES_URL.
+ */
+
+// --- test_database_url_postgres_fallback (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief POSTGRES_URL is used when DATABASE_URL is unset.
+ */
+
+// --- test_database_url_raises_when_both_unset (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief RuntimeError is expected when both DATABASE_URL and POSTGRES_URL are unset (non-dev).
+ */
+
+// --- test_auth_config_module_contract (backend/tests/test_security_audit_fixes.py)
+/**!
+ * @brief AuthConfig contract: the class exists, validators are documented.
+ */
+
+// --- test_sql_table_extractor (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Unit tests for SqlTableExtractor — T017. Verifies three-phase extraction of schema.table references from SQL+Jinja.
+ */
+
+// --- test_simple_select (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Happy path: simple SELECT with FROM schema.table.
+ */
+
+// --- test_multiple_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief JOIN with multiple schema-qualified tables.
+ */
+
+// --- test_empty_input (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Empty string returns empty set.
+ */
+
+// --- test_no_schema_qualified_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Unqualified table names are NOT matched.
+ */
+
+// --- test_case_insensitive (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Matching is case-insensitive; result is lowercased.
+ */
+
+// --- test_string_literal_false_positive (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Date literal like '2026.04.30' must NOT be matched as schema.table.
+ */
+
+// --- test_jinja_string_concat (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Table reference inside Jinja {{ 'raw.sales' }} as a direct string.
+ */
+
+// --- test_jinja_set_block (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Table name in Jinja {% set %} block string value.
+ */
+
+// --- test_mixed_jinja_and_sql (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Mixed Jinja string and plain SQL schema.table references.
+ */
+
+// --- test_cte_with_schema_tables (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief CTE body with schema-qualified table references.
+ */
+
+// --- test_jinja_comment_excluded (backend/tests/test_sql_table_extractor.py)
+/**!
+ * @brief Jinja comment {# ... #} content should not produce table extraction (no string patterns inside comments).
+ */
+
+// --- TestStorageAuditFixes (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief Verify Class 7 typo fix — "repositorys" → "repositories" across all storage/git modules.
+ */
+
+// --- test_repository_typo_fixed (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief FileCategory.REPOSITORY equals "repositories", NOT "repositorys".
+ */
+
+// --- test_repo_path_default_fixed (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief StorageConfig().repo_path defaults to "repositories".
+ */
+
+// --- test_storage_model_compiles (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief All storage model classes import without errors.
+ */
+
+// --- test_backup_category_unchanged (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief FileCategory.BACKUP still equals "backups" (not affected by typo fix).
+ */
+
+// --- test_storage_config_fields_have_correct_types (backend/tests/test_storage_audit_fixes.py)
+/**!
+ * @brief StorageConfig fields are all strings with correct defaults.
+ */
+
+// --- TestStorageConfigMigration (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify StorageConfig root_path change from "backups" to "/app/storage",
+ */
+
+// --- TestStorageConfigDefaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify StorageConfig default field values after the root_path change.
+ */
+
+// --- test_root_path_default (backend/tests/test_storage_config.py)
+/**!
+ * @brief StorageConfig().root_path must equal "/app/storage" (was "backups").
+ */
+
+// --- test_root_path_is_string (backend/tests/test_storage_config.py)
+/**!
+ * @brief root_path is always a str (type safety).
+ */
+
+// --- test_other_defaults_unchanged (backend/tests/test_storage_config.py)
+/**!
+ * @brief Other StorageConfig fields were not affected by the root_path change.
+ */
+
+// --- test_global_settings_propagates_storage (backend/tests/test_storage_config.py)
+/**!
+ * @brief GlobalSettings().storage.root_path inherits the StorageConfig default.
+ */
+
+// --- test_override_root_path (backend/tests/test_storage_config.py)
+/**!
+ * @brief Explicit root_path overrides the default.
+ */
+
+// --- TestConfigManagerDefaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify ConfigManager produces correct defaults when no config.json exists.
+ */
+
+// --- test_init_falls_to_defaults (backend/tests/test_storage_config.py)
+/**!
+ * @brief ConfigManager(…nonexistent…) loads defaults when both DB and config.json are absent.
+ */
+
+// --- test_default_config_root_path (backend/tests/test_storage_config.py)
+/**!
+ * @brief _default_config() hardcodes root_path == "/app/storage" via StorageConfig default.
+ */
+
+// --- test_features_from_env_still_applied (backend/tests/test_storage_config.py)
+/**!
+ * @brief Even without config.json, _apply_features_from_env runs during default init.
+ */
+
+// --- TestValidatePath (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify ConfigManager.validate_path contract.
+ */
+
+// --- test_validate_path_creates_directory (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path creates the target directory and returns (True, "OK").
+ */
+
+// --- test_validate_path_already_exists (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path succeeds when the directory already exists.
+ */
+
+// --- test_validate_path_nonexistent_root (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path returns False for a path under / (non-writable by non-root).
+ */
+
+// --- test_validate_path_read_only_parent (backend/tests/test_storage_config.py)
+/**!
+ * @brief validate_path returns False when the parent directory is not writable.
+ */
+
+// --- TestGitPluginConfigIntegration (backend/tests/test_storage_config.py)
+/**!
+ * @brief Verify GitPlugin uses shared config_manager from src.dependencies (no config.json fallback).
+ */
+
+// --- test_git_plugin_uses_shared_config_manager (backend/tests/test_storage_config.py)
+/**!
+ * @brief GitPlugin.__init__ picks up the shared config_manager from src.dependencies.
+ */
+
+// --- test_git_plugin_fallback_creates_new (backend/tests/test_storage_config.py)
+/**!
+ * @brief When from src.dependencies import config_manager fails,
+ */
+
+// --- TestRegressionGuard (backend/tests/test_storage_config.py)
+/**!
+ * @brief Guard against regressions in existing test contracts and stale assertions.
+ */
+
+// --- test_existing_test_would_fail (backend/tests/test_storage_config.py)
+/**!
+ * @brief Existing test_storage_audit_fixes.py still asserts root_path=="backups" (WRONG).
+ */
+
+// --- test_storage_settings_endpoint_shape (backend/tests/test_storage_config.py)
+/**!
+ * @brief The API response shape for storage settings is still StorageConfig.
+ */
+
+// --- test_task_manager (backend/tests/test_task_manager.py)
+/**!
+ * @brief Unit tests for TaskManager lifecycle, CRUD, log buffering, and filtering.
+ * @invariant TaskManager state changes are deterministic and testable with mocked dependencies.
+ */
+
+// --- _make_manager (backend/tests/test_task_manager.py)
+/**!
+ */
+
+// --- _cleanup_manager (backend/tests/test_task_manager.py)
+/**!
+ */
+
+// --- test_task_persistence (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Unit tests for TaskPersistenceService.
+ */
+
+// --- TestTaskPersistenceHelpers (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test suite for TaskPersistenceService static helper methods.
+ */
+
+// --- test_json_load_if_needed_none (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with None input.
+ */
+
+// --- test_json_load_if_needed_dict (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with dict input.
+ */
+
+// --- test_json_load_if_needed_list (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with list input.
+ */
+
+// --- test_json_load_if_needed_json_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with JSON string.
+ */
+
+// --- test_json_load_if_needed_empty_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with empty/null strings.
+ */
+
+// --- test_json_load_if_needed_plain_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with non-JSON string.
+ */
+
+// --- test_json_load_if_needed_integer (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _json_load_if_needed with integer.
+ */
+
+// --- test_parse_datetime_none (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with None.
+ */
+
+// --- test_parse_datetime_datetime_object (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with datetime object.
+ */
+
+// --- test_parse_datetime_iso_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with ISO string.
+ */
+
+// --- test_parse_datetime_invalid_string (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with invalid string.
+ */
+
+// --- test_parse_datetime_integer (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test _parse_datetime with non-string, non-datetime.
+ */
+
+// --- TestTaskPersistenceService (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test suite for TaskPersistenceService CRUD operations.
+ */
+
+// --- setup_class (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Setup in-memory test database.
+ */
+
+// --- teardown_class (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Dispose of test database.
+ */
+
+// --- setup_method (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Clean task_records table before each test.
+ */
+
+// --- test_persist_task_new (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting a new task creates a record.
+ * @post TaskRecord exists in database.
+ * @pre Empty database.
+ */
+
+// --- test_persist_task_update (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test updating an existing task.
+ * @post Task record updated with new status.
+ * @pre Task already persisted.
+ */
+
+// --- test_persist_task_with_logs (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting a task with log entries.
+ * @post Logs serialized as JSON in task record.
+ * @pre Task has logs attached.
+ */
+
+// --- test_persist_task_failed_extracts_error (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test that FAILED task extracts last error message.
+ * @post record.error contains last error message.
+ * @pre Task has FAILED status with ERROR logs.
+ */
+
+// --- test_persist_tasks_batch (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test persisting multiple tasks.
+ * @post All task records created.
+ * @pre Empty database.
+ */
+
+// --- test_load_tasks (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks from database.
+ * @post Returns list of Task objects with correct data.
+ * @pre Tasks persisted.
+ */
+
+// --- test_load_tasks_with_status_filter (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks filtered by status.
+ * @post Returns only tasks matching status filter.
+ * @pre Tasks with different statuses persisted.
+ */
+
+// --- test_load_tasks_with_limit (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test loading tasks with limit.
+ * @post Returns at most `limit` tasks.
+ * @pre Multiple tasks persisted.
+ */
+
+// --- test_delete_tasks (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test deleting tasks by ID list.
+ * @post Specified tasks deleted, others remain.
+ * @pre Tasks persisted.
+ */
+
+// --- test_delete_tasks_empty_list (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test deleting with empty list (no-op).
+ * @post No error, no changes.
+ * @pre None.
+ */
+
+// --- test_persist_task_with_datetime_in_params (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Test json_serializable handles datetime in params.
+ * @post Params serialized correctly.
+ * @pre Task params contain datetime values.
+ */
+
+// --- test_persist_task_resolves_environment_slug_to_existing_id (backend/tests/test_task_persistence.py)
+/**!
+ * @brief Ensure slug-like environment token resolves to environments.id before persisting task.
+ * @post task_records.environment_id stores actual environments.id and does not violate FK.
+ * @pre environments table contains env with name convertible to provided slug token.
+ */
+
+// --- TranslateCorrectionTests (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Tests for term correction API endpoints and DictionaryManager correction methods.
+ */
+
+// --- test_submit_correction_creates_entry (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify that a correction creates a new dictionary entry.
+ */
+
+// --- test_submit_correction_conflict_detected (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify conflict detection when entry already exists.
+ */
+
+// --- test_submit_correction_overwrite (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify that correction overwrites existing entry.
+ */
+
+// --- test_bulk_corrections_atomic (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify bulk corrections are applied atomically.
+ */
+
+// --- test_api_correction_missing_dict (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify POST corrections without dictionary_id returns 422.
+ */
+
+// --- test_api_bulk_corrections (backend/tests/test_translate_corrections.py)
+/**!
+ * @brief Verify POST /corrections/bulk works.
+ */
+
+// --- TestTranslateExecutorFilter (backend/tests/test_translate_executor_filter.py)
+/**!
+ * @brief Verify TranslationExecutor._filter_new_keys contracts — key dedup, empty-set, guard triggers.
+ */
+
+// --- test_no_prior_run_returns_all_rows (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_filters_existing_keys (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_composite_keys (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_all_keys_existing_returns_empty (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_empty_key_cols_returns_all_rows (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_null_source_data_handled (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_prior_run_no_records_returns_all (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- test_key_cols_none_returns_all (backend/tests/test_translate_executor_filter.py)
+/**!
+ */
+
+// --- TranslateHistoryTests (backend/tests/test_translate_history.py)
+/**!
+ * @brief Tests for run history list/detail endpoints and metrics aggregation.
+ */
+
+// --- test_list_runs_empty (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify runs list returns empty result initially.
+ */
+
+// --- test_list_runs_with_data (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify runs list returns data when runs exist.
+ */
+
+// --- test_list_runs_filter_job_id (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify filtering runs by job_id works.
+ */
+
+// --- test_list_runs_filter_status (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify filtering runs by status works.
+ */
+
+// --- test_get_run_detail (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify run detail returns config_snapshot, records, events.
+ */
+
+// --- test_get_job_metrics (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics endpoint returns aggregated data.
+ */
+
+// --- test_get_all_metrics (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify global metrics endpoint returns data.
+ */
+
+// --- test_metrics_empty_job (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics for job with no runs returns zeros.
+ */
+
+// --- test_run_detail_not_found (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify 404 on non-existent run detail.
+ */
+
+// --- test_list_runs_includes_language_info (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify run list includes target_languages, total_translated, and language_stats.
+ */
+
+// --- test_metrics_per_language_breakdown (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify metrics endpoint returns per_language_metrics.
+ */
+
+// --- test_metric_snapshot_stores_per_language (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify MetricSnapshot stores per_language_metrics via prune_expired.
+ */
+
+// --- test_combined_metrics_live_and_snapshot (backend/tests/test_translate_history.py)
+/**!
+ * @brief Verify combined metrics merge live + snapshot per-language data.
+ */
+
+// --- TranslateJobTests (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Tests for translation job CRUD endpoints and service layer with column validation.
+ */
+
+// --- valid_job_payload (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Standard valid payload for creating a translation job.
+ */
+
+// --- MockConfigManager (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Mock ConfigManager for service tests that returns a test environment.
+ */
+
+// --- db_session (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Create a fresh DB session with transaction rollback for each test.
+ */
+
+// --- mock_api_deps (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Override FastAPI dependencies (including get_db with in-memory SQLite) for API route tests.
+ */
+
+// --- client (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief FastAPI TestClient for API route tests.
+ */
+
+// --- test_create_job_valid (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a valid job payload creates a job successfully.
+ */
+
+// --- test_create_job_missing_translation_column (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that creating a job with datasource but no translation column raises ValueError.
+ */
+
+// --- test_create_job_invalid_upsert_strategy (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that an invalid upsert strategy is rejected.
+ */
+
+// --- test_get_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be retrieved by ID.
+ */
+
+// --- test_get_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that getting a non-existent job raises ValueError.
+ */
+
+// --- test_list_jobs (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that listing jobs returns all created jobs.
+ */
+
+// --- test_list_jobs_with_status_filter (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that listing jobs with a status filter works.
+ */
+
+// --- test_update_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be updated.
+ */
+
+// --- test_delete_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be deleted.
+ */
+
+// --- test_duplicate_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be duplicated.
+ */
+
+// --- test_duplicate_job_custom_name (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that a job can be duplicated with a custom name.
+ */
+
+// --- test_detect_virtual_columns (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify virtual column detection from column metadata.
+ */
+
+// --- test_get_dialect_from_database (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify dialect extraction from Superset database records.
+ */
+
+// --- test_get_dialect_from_database_unsupported (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify that unsupported dialects raise ValueError.
+ */
+
+// --- test_api_create_job (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify POST /api/translate/jobs returns 201 with valid payload.
+ */
+
+// --- test_api_list_jobs (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify GET /api/translate/jobs returns 200.
+ */
+
+// --- test_api_get_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify GET non-existent job returns 404.
+ */
+
+// --- test_api_delete_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify DELETE non-existent job returns 404.
+ */
+
+// --- test_api_duplicate_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify duplicating a non-existent job returns 404.
+ */
+
+// --- test_api_create_job_422_missing_name (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify POST with missing required fields returns 422.
+ */
+
+// --- test_api_datasource_columns_missing_env (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify datasource columns endpoint without env_id returns 422.
+ */
+
+// --- test_api_datasource_columns_bad_env (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify datasource columns with unknown env returns 400.
+ */
+
+// --- test_api_update_job_not_found (backend/tests/test_translate_jobs.py)
+/**!
+ * @brief Verify PUT non-existent job returns 404.
+ */
+
+// --- TranslateSchedulerTests (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Tests for TranslationScheduler CRUD and APScheduler integration.
+ */
+
+// --- test_create_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule creation with valid params.
+ */
+
+// --- test_update_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule update.
+ */
+
+// --- test_delete_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify schedule deletion.
+ */
+
+// --- test_enable_disable_schedule (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify enable/disable toggle.
+ */
+
+// --- test_get_schedule_not_found (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify ValueError on getting non-existent schedule.
+ */
+
+// --- test_list_active_schedules (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify listing only active schedules.
+ */
+
+// --- test_get_next_executions (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify next execution time computation.
+ */
+
+// --- test_get_next_executions_invalid (backend/tests/test_translate_scheduler.py)
+/**!
+ * @brief Verify invalid cron returns empty list.
+ */
+
+// --- TestTranslateSchedulerExecution (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ * @brief Verify execute_scheduled_translation contracts — trigger_type dispatch, baseline expiry fallback.
+ */
+
+// --- test_new_key_only_mode (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_baseline_expired_fallback (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_full_mode_default (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_inactive_schedule_skips (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_schedule_not_found_skips (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_baseline_expired_full_mode (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- test_execution_error_handled (backend/tests/test_translate_scheduler_execution.py)
+/**!
+ */
+
+// --- TestTranslateSchedulerGuard (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ * @brief Verify execute_scheduled_translation concurrency guard and stale-PENDING clearance contracts.
+ */
+
+// --- test_concurrent_run_skips (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- test_recent_pending_run_not_stale (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- test_stale_pending_cleared_and_proceeds (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- test_multiple_stale_pending_all_cleared (backend/tests/test_translate_scheduler_guard.py)
+/**!
+ */
+
+// --- docker.backend.Dockerfile (docker/backend.Dockerfile)
+/**!
+ * @brief Backend Dockerfile — Python 3.11 slim + Playwright + entrypoint с установкой сертификатов.
+ * @post Образ с backend API, Playwright, entrypoint для bootstrap admin и установки сертификатов.
+ * @pre Docker builder context — корень проекта. backend/ и docker/ доступны.
+ */
+
+// --- docker.backend.entrypoint (docker/backend.entrypoint.sh)
+/**!
+ * @brief Container entrypoint — установка корп. сертификатов, Playwright (lazy), bootstrap admin,
+ */
+
+// --- docker.backend.entrypoint.install_certificates (docker/backend.entrypoint.sh)
+/**!
+ * @brief Устанавливает корпоративные .crt сертификаты из CERTS_PATH в системное хранилище Debian.
+ * @pre CERTS_PATH указывает на директорию (может быть пуста или не существовать).
+ */
+
+// --- docker.backend.entrypoint.bootstrap_admin (docker/backend.entrypoint.sh)
+/**!
+ * @brief Создание admin пользователя из переменных окружения (идемпотентно).
+ * @post Admin пользователь создан в БД (если ещё не существовал).
+ * @pre INITIAL_ADMIN_CREATE=true, INITIAL_ADMIN_USERNAME и INITIAL_ADMIN_PASSWORD заданы.
+ */
+
+// --- docker.backend.entrypoint.install_playwright (docker/backend.entrypoint.sh)
+/**!
+ * @brief Lazy установка Playwright Chromium (~377 MB) при первом запуске.
+ * @post Chromium установлен в PLAYWRIGHT_BROWSERS_PATH.
+ * @pre ~/.cache/ms-playwright доступен (можно закешировать volume).
+ */
+
+// --- docker.frontend.Dockerfile (docker/frontend.Dockerfile)
+/**!
+ * @brief Frontend Dockerfile — сборка SvelteKit (node:20) + nginx runtime с опциональным SSL.
+ * @post nginx:alpine образ со статикой SvelteKit, entrypoint для выбора HTTP/SSL конфига.
+ * @pre Docker builder context — корень проекта. frontend/ и docker/ доступны.
+ */
+
+// --- docker.frontend.entrypoint (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Entrypoint для nginx-контейнера — установка корп. CA-сертификатов в Alpine,
+ */
+
+// --- docker.frontend.entrypoint.install_ca_certificates (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Устанавливает .crt файлы из /opt/certs в системное хранилище Alpine.
+ * @post Сертификаты скопированы в /usr/local/share/ca-certificates/ и добавлены в trust.
+ * @pre /opt/certs может быть пуст или не существовать.
+ */
+
+// --- docker.frontend.entrypoint.select_nginx_config (docker/frontend.entrypoint.sh)
+/**!
+ * @brief Определяет, есть ли сертификаты для SSL, и копирует нужный nginx конфиг.
+ * @post Если есть оба файла — /etc/nginx/ssl/ создан, server.crt/key скопированы,
+ * @pre /opt/certs/server.crt и /opt/certs/server.key — опциональные SSL-сертификаты.
+ */
+
+// --- docker.nginx.ssl.conf (docker/nginx.ssl.conf)
+/**!
+ * @brief Nginx config с опциональным SSL — HTTP (порт 80) + HTTPS (порт 443).
+ */
+
+// --- AuthFixture (frontend/e2e/fixtures/auth.fixture.js)
+/**!
+ * @brief Playwright fixture for authenticated browser contexts.
+ */
+
+// --- GlobalSetup (frontend/e2e/fixtures/global-setup.js)
+/**!
+ * @brief Pre-flight check before any E2E tests run.
+ * @post Exits with 1 if either service is down, else sets ENV vars.
+ * @pre Backend and frontend must be reachable.
+ */
+
+// --- ApiHelper (frontend/e2e/helpers/api.helper.js)
+/**!
+ * @brief Helper for backend API calls in E2E tests (settings CRUD, etc.)
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::getToken (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiGet (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiPost (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiPut (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- frontend/e2e/helpers/api.helper.js::apiDelete (frontend/e2e/helpers/api.helper.js)
+/**!
+ */
+
+// --- run-enterprise-clean-e2e (frontend/e2e/run-enterprise-clean-e2e.sh)
+/**!
+ * @brief Enterprise Clean E2E Orchestrator — полный протокол тестирования пустого образа перед передачей.
+ */
+
+// --- EnterpriseCleanSetupE2E (frontend/e2e/tests/enterprise-clean-setup.e2e.js)
+/**!
+ * @brief Stage 1: E2E test for enterprise-clean empty image — first-run setup via StartupEnvironmentWizard.
+@@RATIONALE All 4 tests pass after fixing: (1) button ambiguity — zero-state page and wizard modal both have 'Начать настройку' button, resolved by scoping to wizard modal via .fixed.inset-0.z-50; (2) wizard detection — changed from waitForSelector('text=...') to getByText() with regex for locale-robust matching; (3) form fill — connections.* i18n keys missing in Docker build, switched to placeholder-based locators scoped within wizard; (4) settings navigation — use authPage fixture for consistent login
+@@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues
+ */
+
+// --- GitE2E (frontend/e2e/tests/git.e2e.js)
+/**!
+ * @brief E2E tests for Git integration — config CRUD, connection test.
+ */
+
+// --- LiveProjectCheckE2E (frontend/e2e/tests/live-project-check.e2e.js)
+/**!
+ * @brief Stage 2: E2E test for live project verification — validates dashboard LLM analysis,
+ */
+
+// --- LoginE2E (frontend/e2e/tests/login.e2e.js)
+/**!
+ * @brief E2E tests for login/logout flow.
+ */
+
+// --- MigrationE2E (frontend/e2e/tests/migration.e2e.js)
+/**!
+ * @brief E2E tests for dataset/environment migration and sync.
+ */
+
+// --- SettingsE2E (frontend/e2e/tests/settings.e2e.js)
+/**!
+ * @brief E2E tests for Settings page — environments, LLM providers, Git config.
+ */
+
+// --- SmokeE2E (frontend/e2e/tests/smoke.e2e.js)
+/**!
+ * @brief Golden-path smoke test: login → settings → translate → git → verify.
+ */
+
+// --- TranslationE2E (frontend/e2e/tests/translation.e2e.js)
+/**!
+ * @brief E2E tests for the translation job lifecycle: create → preview → accept → run.
+ */
+
+// --- PlaywrightConfig (frontend/playwright.config.js)
+/**!
+ * @brief Playwright E2E test configuration for ss-tools frontend.
+ * @invariant All E2E tests run against a fully deployed stack (DB + backend + frontend).
+ */
+
+// --- handleValidate:Function (frontend/src/components/DashboardGrid.svelte)
+/**!
+ * @brief Triggers dashboard validation task.
+ */
+
+// --- openGit:Function (frontend/src/components/DashboardGrid.svelte)
+/**!
+ * @brief Opens the Git management modal for a dashboard.
+ */
+
+// --- initializeForm:Function (frontend/src/components/DynamicForm.svelte)
+/**!
+ * @brief Initialize form data with default values from the schema.
+ * @post formData is initialized with default values or empty strings.
+ * @pre schema is provided and contains properties.
+ */
+
+// --- Footer (frontend/src/components/Footer.svelte)
+/**!
+ * @brief Displays the application footer with copyright information.
+ */
+
+// --- updateMapping:Function (frontend/src/components/MappingTable.svelte)
+/**!
+ * @brief Updates a mapping for a specific source database.
+ * @post Parent callback receives normalized mapping payload.
+ * @pre sourceUuid and targetUuid are provided.
+ */
+
+// --- getSuggestion:Function (frontend/src/components/MappingTable.svelte)
+/**!
+ * @brief Finds a suggestion for a source database.
+ * @post Returns matching suggestion object or undefined.
+ * @pre sourceUuid is provided.
+ */
+
+// --- MissingMappingModal (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Prompts the user to provide a database mapping when one is missing during migration.
+ * @invariant Modal blocks migration progress until resolved or cancelled.
+ */
+
+// --- resolve:Function (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Resolves the missing mapping via callback prop.
+ * @post Parent callback receives mapping payload and modal closes.
+ * @pre selectedTargetUuid must be set.
+ */
+
+// --- cancel:Function (frontend/src/components/MissingMappingModal.svelte)
+/**!
+ * @brief Cancels the mapping resolution modal.
+ * @post Parent cancel callback is invoked and modal is hidden.
+ * @pre Modal is open.
+ */
+
+// --- Navbar (frontend/src/components/Navbar.svelte)
+/**!
+ * @brief Main navigation bar for the application.
+ */
+
+// --- PasswordPrompt (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief A modal component to prompt the user for database passwords when a migration task is paused.
+ */
+
+// --- handleSubmit:Function (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief Validates and forwards passwords to resume the task.
+ * @post Parent resume callback receives passwords payload.
+ * @pre All database passwords must be entered.
+ */
+
+// --- handleCancel:Function (frontend/src/components/PasswordPrompt.svelte)
+/**!
+ * @brief Cancels the password prompt.
+ * @post Parent cancel callback is invoked and show is set to false.
+ * @pre Modal is open.
+ */
+
+// --- handleSort:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Toggles sort direction or changes sort column.
+ * @post sortColumn and sortDirection state updated.
+ * @pre column name is provided.
+ */
+
+// --- handleSelectionChange:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Handles individual checkbox changes.
+ * @post selectedIds array updated.
+ * @pre dashboard ID and checked status provided.
+ */
+
+// --- handleSelectAll:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Handles select all checkbox.
+ * @post selectedIds array updated for all paginated items.
+ * @pre checked status provided.
+ */
+
+// --- goToPage:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Changes current page.
+ * @post currentPage state updated if within valid range.
+ * @pre page index is provided.
+ */
+
+// --- getRepositoryStatusToken:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns normalized repository status token for a dashboard.
+ * @post Returns one of loading|no_repo|synced|changes|behind_remote|ahead_remote|diverged|error.
+ * @pre Dashboard exists.
+ */
+
+// --- isRepositoryReady:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Determines whether git actions can run for a dashboard.
+ */
+
+// --- invalidateRepositoryStatuses:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Marks dashboard statuses as loading so they are refetched.
+ */
+
+// --- resolveRepositoryStatusToken:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Converts git status payload into a stable UI status token.
+ */
+
+// --- loadRepositoryStatuses:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Hydrates repository status map for dashboards in repository mode.
+ */
+
+// --- runBulkGitAction:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Executes git action for selected dashboards with limited parallelism.
+ */
+
+// --- handleBulkSync:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkCommit:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkPull:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkPush:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ */
+
+// --- handleBulkDelete:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Removes selected repositories from storage and binding table.
+ */
+
+// --- handleManageSelected:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager for exactly one selected dashboard.
+ */
+
+// --- resolveDashboardRef:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Resolves dashboard slug from payload fields.
+ * @post Returns slug string or null if unavailable.
+ * @pre Dashboard metadata is provided.
+ */
+
+// --- openGitManagerForDashboard:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager for provided dashboard metadata.
+ */
+
+// --- handleInitializeRepositories:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Opens Git manager from bulk actions to initialize selected repository.
+ */
+
+// --- getSortStatusValue:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns sort value for status column based on mode.
+ */
+
+// --- getStatusLabel:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns localized label for status column.
+ */
+
+// --- getStatusBadgeClass:Function (frontend/src/components/RepositoryDashboardGrid.svelte)
+/**!
+ * @brief Returns badge style for status column.
+ */
+
+// --- TaskHistory (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Displays a list of recent tasks with their status and allows selecting them for viewing logs.
+ */
+
+// --- getStatusColor:Function (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Returns the CSS color class for a given task status.
+ * @post Returns tailwind color class string.
+ * @pre status string is provided.
+ */
+
+// --- onDestroy:Function (frontend/src/components/TaskHistory.svelte)
+/**!
+ * @brief Cleans up the polling interval when the component is destroyed.
+ * @post Polling interval is cleared.
+ * @pre Component is being destroyed.
+ */
+
+// --- TaskList (frontend/src/components/TaskList.svelte)
+/**!
+ * @brief Displays a list of tasks with their status and execution details.
+ */
+
+// --- handleTaskClick:Function (frontend/src/components/TaskList.svelte)
+/**!
+ * @brief Forwards the selected task through a callback prop.
+ * @post Parent callback receives task id and task payload.
+ * @pre taskId is provided.
+ */
+
+// --- TaskLogViewer (frontend/src/components/TaskLogViewer.svelte)
+/**!
+ * @brief Displays task logs inline (in drawer) or as modal. Merges real-time WebSocket logs with polled historical logs.
+ * @invariant Real-time logs are always appended without duplicates.
+ */
+
+// --- connect:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Establishes WebSocket connection with exponential backoff and filter parameters.
+ * @post WebSocket instance created and listeners attached.
+ * @pre selectedTask must be set in the store.
+ */
+
+// --- handleFilterChange:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Handles filter changes and reconnects WebSocket with new parameters.
+ * @post WebSocket reconnected with new filter parameters, logs cleared.
+ * @pre event.detail contains source and level filter values.
+ */
+
+// --- fetchTargetDatabases:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Fetches available databases from target environment for mapping.
+ * @post targetDatabases array populated with available databases.
+ * @pre selectedTask must have to_env parameter set.
+ */
+
+// --- handleMappingResolve:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Resolves missing database mapping and continues migration.
+ * @post Mapping created in backend, task resumed with resolution params.
+ * @pre event.detail contains sourceDbUuid, targetDbUuid, targetDbName.
+ */
+
+// --- handlePasswordResume:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Submits passwords and resumes paused migration task.
+ * @post Task resumed with passwords, connection status restored to connected.
+ * @pre event.detail contains passwords object.
+ */
+
+// --- startDataTimeout:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Starts timeout timer to detect idle connection.
+ * @post waitingForData set to true after 5 seconds if no data received.
+ * @pre connectionStatus is 'connected'.
+ */
+
+// --- resetDataTimeout:Function (frontend/src/components/TaskRunner.svelte)
+/**!
+ * @brief Resets data timeout timer when new data arrives.
+ * @post waitingForData reset to false, new timeout started.
+ * @pre dataTimeout must be set.
+ */
+
+// --- Toast (frontend/src/components/Toast.svelte)
+/**!
+ * @brief Displays transient notifications (toasts) in the bottom-right corner.
+ */
+
+// --- TaskLogViewerTest:Module (frontend/src/components/__tests__/task_log_viewer.test.js)
+/**!
+ * @brief Unit tests for TaskLogViewer component by mounting it and observing the DOM.
+ * @invariant Duplicate logs are never appended. Polling only active for in-progress tasks.
+ */
+
+// --- verifySessionAndAccess:Function (frontend/src/components/auth/ProtectedRoute.svelte)
+/**!
+ * @brief Validates session and optional permission gate before allowing protected content render.
+ * @post hasRouteAccess=true only when user identity is valid and permission check (if provided) passes.
+ * @pre auth store is initialized and can provide token/user state; navigation is available.
+ */
+
+// --- handleCreateBackup:Function (frontend/src/components/backups/BackupManager.svelte)
+/**!
+ * @brief Triggers a new backup task for the selected environment.
+ * @post A new task is created on the backend.
+ * @pre selectedEnvId must be a valid environment ID.
+ * @return {Promise}
+ */
+
+// --- handleUpdateSchedule:Function (frontend/src/components/backups/BackupManager.svelte)
+/**!
+ * @brief Updates the backup schedule for the selected environment.
+ * @post Environment config is updated on the backend.
+ * @pre selectedEnvId must be set.
+ */
+
+// --- loadBranches:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Загружает список веток для дашборда.
+ * @post branches обновлен.
+ * @pre dashboardId is provided.
+ */
+
+// --- handleSelect:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Handles branch selection from dropdown.
+ * @post handleCheckout is called with selected branch.
+ * @pre event contains branch name.
+ */
+
+// --- handleCheckout:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Переключает текущую ветку.
+ * @param {string} branchName - Имя ветки.
+ * @post currentBranch обновлен, родительский callback вызван.
+ */
+
+// --- handleCreate:Function (frontend/src/components/git/BranchSelector.svelte)
+/**!
+ * @brief Создает новую ветку.
+ * @post Новая ветка создана и загружена; showCreate reset.
+ * @pre newBranchName is not empty.
+ */
+
+// --- loadHistory:Function (frontend/src/components/git/CommitHistory.svelte)
+/**!
+ * @brief Fetch commit history from the backend.
+ * @post history state is updated.
+ * @pre dashboardId is valid.
+ */
+
+// --- handleGenerateMessage:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Generates a commit message using LLM.
+ */
+
+// --- loadStatus:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Загружает текущий статус репозитория и diff.
+ * @pre dashboardId должен быть валидным.
+ */
+
+// --- handleCommit:Function (frontend/src/components/git/CommitModal.svelte)
+/**!
+ * @brief Создает коммит с указанным сообщением.
+ * @post Коммит создан и модальное окно закрыто.
+ * @pre message не должно быть пустым.
+ */
+
+// --- loadStatus:Watcher (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ */
+
+// --- normalizeEnvStage:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Normalize environment stage with legacy production fallback.
+ * @post Returns DEV/PREPROD/PROD.
+ */
+
+// --- resolveEnvUrl:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Resolve environment URL from consolidated or git-specific payload shape.
+ * @post Returns stable URL string.
+ */
+
+// --- loadEnvironments:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Fetch available environments from API.
+ * @post environments state is populated.
+ */
+
+// --- handleDeploy:Function (frontend/src/components/git/DeploymentModal.svelte)
+/**!
+ * @brief Trigger deployment to selected environment.
+ * @post Deploy request finishes and modal closes on success.
+ * @pre selectedEnv must be set.
+ */
+
+// --- GitInitPanel (frontend/src/components/git/GitInitPanel.svelte)
+/**!
+ * @brief Git initialization panel: select config, create remote repo, init local repo.
+ */
+
+// --- GitManager (frontend/src/components/git/GitManager.svelte)
+/**!
+ * @brief Central Git management UI — thin shell delegating to sub-panels and composable handlers.
+ */
+
+// --- GitMergeDialog (frontend/src/components/git/GitMergeDialog.svelte)
+/**!
+ * @brief Unfinished merge recovery dialog: abort, continue, resolve conflicts.
+ */
+
+// --- GitOperationsPanel (frontend/src/components/git/GitOperationsPanel.svelte)
+/**!
+ * @brief Git server operations panel: pull, push, and deploy actions.
+ */
+
+// --- GitReleasePanel (frontend/src/components/git/GitReleasePanel.svelte)
+/**!
+ * @brief Git release panel: promote branches via MR or direct mode.
+ */
+
+// --- GitWorkspacePanel (frontend/src/components/git/GitWorkspacePanel.svelte)
+/**!
+ * @brief Git workspace panel: sync, commit message input, diff viewer, commit action.
+ */
+
+// --- GitManagerUnfinishedMergeIntegrationTest:Module (frontend/src/components/git/__tests__/git_manager.unfinished_merge.integration.test.js)
+/**!
+ * @brief Protect unresolved-merge dialog contract in GitManager pull flow.
+ */
+
+// --- UseGitManager (frontend/src/components/git/useGitManager.js)
+/**!
+ * @brief Composable for GitManager handler functions — extracted to reduce component size per INV_7.
+ */
+
+// --- DocPreview (frontend/src/components/llm/DocPreview.svelte)
+/**!
+ * @brief UI component for previewing generated dataset documentation before saving.
+ */
+
+// --- ProviderConfig (frontend/src/components/llm/ProviderConfig.svelte)
+/**!
+ * @brief UI form for managing LLM provider configurations.
+ */
+
+// --- ValidationReport (frontend/src/components/llm/ValidationReport.svelte)
+/**!
+ * @brief Displays the results of an LLM-based dashboard validation task.
+ */
+
+// --- provider_config_edit_contract_tests:Function (frontend/src/components/llm/__tests__/provider_config.integration.test.js)
+/**!
+ * @brief Validate edit and delete handler wiring plus normalized edit form state mapping.
+ * @post Contract checks ensure edit click cannot degrade into no-op flow.
+ * @pre ProviderConfig component source exists in expected path.
+ */
+
+// --- isDirectory:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Checks if a file object represents a directory.
+ * @param {Object} file - The file object to check.
+ * @post Returns boolean.
+ * @pre file object has mime_type property.
+ * @return {boolean} True if it's a directory, false otherwise.
+ */
+
+// --- formatSize:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Formats file size in bytes into a human-readable string.
+ * @param {number} bytes - The size in bytes.
+ * @post Returns formatted string.
+ * @pre bytes is a number.
+ * @return {string} Formatted size (e.g., "1.2 MB").
+ */
+
+// --- formatDate:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Formats an ISO date string into a localized readable format.
+ * @param {string} dateStr - The date string to format.
+ * @post Returns localized string.
+ * @pre dateStr is a valid date string.
+ * @return {string} Localized date and time.
+ */
+
+// --- handleDownload:Function (frontend/src/components/storage/FileList.svelte)
+/**!
+ * @brief Downloads selected file through authenticated API request.
+ * @post Browser download starts or user sees toast on failure.
+ * @pre file is a non-directory storage entry with category/path.
+ */
+
+// --- handleUpload:Function (frontend/src/components/storage/FileUpload.svelte)
+/**!
+ * @brief Handles the file upload process.
+ * @post The file is uploaded to the server and a success toast is shown.
+ * @pre A file must be selected in the file input.
+ */
+
+// --- handleDrop:Function (frontend/src/components/storage/FileUpload.svelte)
+/**!
+ * @brief Handles the file drop event for drag-and-drop.
+ * @param {DragEvent} event - The drop event.
+ */
+
+// --- LogEntryRow (frontend/src/components/tasks/LogEntryRow.svelte)
+/**!
+ * @brief Renders a single log entry with stacked layout optimized for narrow drawer panels.
+ */
+
+// --- formatTime:Function (frontend/src/components/tasks/LogEntryRow.svelte)
+/**!
+ * @brief Format ISO timestamp to HH:MM:SS
+ */
+
+// --- LogFilterBar (frontend/src/components/tasks/LogFilterBar.svelte)
+/**!
+ * @brief Compact filter toolbar for logs — level, source, and text search in a single dense row.
+ */
+
+// --- TaskLogPanel (frontend/src/components/tasks/TaskLogPanel.svelte)
+/**!
+ * @brief Combines log filtering and display into a single cohesive light-themed panel.
+ * @invariant Must always display logs in chronological order and respect auto-scroll preference.
+ */
+
+// --- TaskResultPanel (frontend/src/components/tasks/TaskResultPanel.svelte)
+/**!
+ * @brief Displays formatted task result summary with status badges and result details.
+ */
+
+// --- handleRunDebug:Function (frontend/src/components/tools/DebugTool.svelte)
+/**!
+ * @brief Triggers the debug task.
+ * @post Task is started and polling begins.
+ * @pre Required fields are selected.
+ * @return {Promise}
+ */
+
+// --- startPolling:Function (frontend/src/components/tools/DebugTool.svelte)
+/**!
+ * @brief Polls for task completion.
+ * @param {string} taskId - ID of the task.
+ * @post Polls until success/failure.
+ * @pre Task ID is valid.
+ * @return {void}
+ */
+
+// --- MapperTool (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief UI component for mapping dataset column verbose names using Superset SQL Lab or Excel files.
+ */
+
+// --- fetchData:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Fetches environments.
+ * @post envs array is populated.
+ * @pre None.
+ */
+
+// --- handleRunMapper:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Triggers the MapperPlugin task via new sqllab/excel sources.
+ * @post Mapper task is started and selectedTask is updated.
+ * @pre selectedEnv and datasetId are set; source-specific fields are valid.
+ */
+
+// --- handleGenerateDocs:Function (frontend/src/components/tools/MapperTool.svelte)
+/**!
+ * @brief Triggers the LLM Documentation task.
+ * @post Documentation task is started.
+ * @pre selectedEnv and datasetId are set.
+ */
+
+// --- Counter (frontend/src/lib/Counter.svelte)
+/**!
+ * @brief Simple counter demo component
+ */
+
+// --- ApiModule (frontend/src/lib/api.js)
+/**!
+ * @brief Handles all communication with the backend API via fetch wrappers with auth, error normalization, and toast feedback.
+ */
+
+// --- ReportsApiTest (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+ */
+
+// --- ReportsApiTest:Module (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Unit tests for reports API client functions: query string building, error normalization, and fetch wrappers.
+ * @invariant Pure functions produce deterministic output. Async wrappers propagate structured errors.
+ */
+
+// --- TestBuildReportQueryString:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate query string construction from filter options.
+ * @post Correct URLSearchParams string produced.
+ * @pre Options object with various filter fields.
+ */
+
+// --- TestNormalizeApiError:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate error normalization for UI-state mapping.
+ * @post Always returns {message, code, retryable} object.
+ * @pre Various error types (Error, string, object).
+ */
+
+// --- TestGetReportsAsync:Class (frontend/src/lib/api/__tests__/reports_api.test.js)
+/**!
+ * @brief Validate getReports and getReportDetail with mocked api.fetchApi.
+ * @post Functions call correct endpoints and propagate results/errors.
+ * @pre api.fetchApi is mocked via vi.mock.
+ */
+
+// --- AssistantApi (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, conversation management, and history retrieval.
+ */
+
+// --- AssistantApi:Module (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief API client wrapper for assistant chat, session-scoped prompts, confirmation actions, and history retrieval.
+ * @invariant All assistant requests must use requestApi wrapper (no native fetch).
+ */
+
+// --- sendAssistantMessage:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Send a user message to assistant orchestrator endpoint.
+ * @post Returns assistant response object with deterministic state.
+ * @pre payload.message is a non-empty string.
+ */
+
+// --- buildAssistantSeedMessage:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Compose visible assistant seed text from context label and prompt body.
+ * @post Returns trimmed seed message string for prefilled input.
+ * @pre prompt contains the user-visible request.
+ */
+
+// --- confirmAssistantOperation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Confirm a pending risky assistant operation.
+ * @post Returns execution response (started/success/failed).
+ * @pre confirmationId references an existing pending token.
+ */
+
+// --- cancelAssistantOperation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Cancel a pending risky assistant operation.
+ * @post Operation is cancelled and cannot be executed by this token.
+ * @pre confirmationId references an existing pending token.
+ */
+
+// --- getAssistantHistory:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Retrieve paginated assistant conversation history.
+ * @post Returns a paginated payload with history items.
+ * @pre page/pageSize are positive integers.
+ */
+
+// --- getAssistantConversations:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Retrieve paginated conversation list for assistant sidebar/history switcher.
+ * @post Returns paginated conversation summaries.
+ * @pre page/pageSize are positive integers.
+ */
+
+// --- deleteAssistantConversation:Function (frontend/src/lib/api/assistant.js)
+/**!
+ * @brief Soft-delete or hard-delete a conversation.
+ * @post Returns success status.
+ * @pre conversationId string is provided.
+ */
+
+// --- DatasetReviewApi (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and session DTO normalization.
+ */
+
+// --- DatasetReviewApi:Module (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Provide shared frontend helpers for dataset review session-scoped API requests, optimistic-lock propagation, and refreshed session DTO normalization.
+ */
+
+// --- buildDatasetReviewRequestOptions:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Attach optimistic-lock session version header when the current version is known.
+ * @post Returns requestApi-compatible options object.
+ * @pre sessionVersion may be null when no loaded session version exists yet.
+ */
+
+// --- requestDatasetReviewApi:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Proxy dataset review mutations through requestApi with optional optimistic-lock headers.
+ * @post Executes requestApi with X-Session-Version only when a session version is known.
+ * @pre endpoint and method are valid requestApi inputs.
+ */
+
+// --- isDatasetReviewConflictError:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Detect optimistic-lock conflicts from dataset review mutations.
+ * @post Returns true when the mutation failed with 409 conflict semantics.
+ * @pre error may be null or a normalized API error.
+ */
+
+// --- getDatasetReviewConflictMessage:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Return explicit 409-style guidance for stale dataset review mutations.
+ * @post Returns a user-facing conflict message string.
+ * @pre error may be null or a normalized API error.
+ */
+
+// --- extractDatasetReviewVersion:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Resolve the latest session version from refreshed DTO fragments.
+ * @post Returns the newest known session version or null.
+ * @pre payload may be a session summary, a detail payload, or a mutation fragment.
+ */
+
+// --- normalizeDatasetReviewDetail:Function (frontend/src/lib/api/datasetReview.js)
+/**!
+ * @brief Normalize refreshed session-detail DTOs into the legacy route-friendly workspace shape.
+ * @post Returns a shape with flattened summary fields plus refreshed collections and version metadata.
+ * @pre detail may already be legacy-flat or refreshed with nested session/session_version fields.
+ */
+
+// --- MaintenanceApi (frontend/src/lib/api/maintenance.js)
+/**!
+ * @brief API client for Maintenance Banner endpoints. Uses requestApi for all calls.
+ */
+
+// --- frontend/src/lib/api/maintenance.js::startMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::endMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::endAllMaintenance (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::getSettings (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::updateSettings (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::listEvents (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/maintenance.js::listDashboardBanners (frontend/src/lib/api/maintenance.js)
+/**!
+ */
+
+// --- ReportsApi (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Wrapper-based reports API client for list/detail retrieval through the shared API wrapper.
+ * @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+ * @pre Shared API wrapper is configured for the current frontend auth/session context.
+ */
+
+// --- ReportsApi:Module (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Wrapper-based reports API client for list/detail retrieval without direct native fetch usage.
+ * @invariant Uses existing api wrapper methods and returns structured errors for UI-state mapping.
+ * @post Report list and detail helpers return backend payloads or normalized UI-safe errors.
+ * @pre Shared API wrapper is configured for the current frontend auth/session context.
+ */
+
+// --- buildReportQueryString:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Build query string for reports list endpoint from filter options.
+ * @post Returns URL query string without leading '?'.
+ * @pre options is an object with optional report query fields.
+ */
+
+// --- normalizeApiError:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Convert unknown API exceptions into deterministic UI-consumable error objects.
+ * @post Returns structured error object.
+ * @pre error may be Error/string/object.
+ */
+
+// --- getReports:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Fetch unified report list using existing request wrapper.
+ * @post Returns parsed payload or structured error for UI-state mapping.
+ * @pre valid auth context for protected endpoint.
+ */
+
+// --- getReportDetail:Function (frontend/src/lib/api/reports.js)
+/**!
+ * @brief Fetch one report detail by report_id.
+ * @post Returns parsed detail payload or structured error object.
+ * @pre reportId is non-empty string; valid auth context.
+ */
+
+// --- TranslateApi (frontend/src/lib/api/translate.js)
+/**!
+ * @brief Barrel module re-exporting all translate API functions from domain-split modules.
+ */
+
+// --- TargetSchemaApiTest (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief Unit tests for checkTargetTableSchema API client fetch wrapper.
+ */
+
+// --- test_success (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief Happy path — API returns full validation result.
+ */
+
+// --- test_api_error (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief API error returns fallback response with error message.
+ */
+
+// --- test_error_string_fallback (frontend/src/lib/api/translate/__tests__/test-target-schema.test.js)
+/**!
+ * @brief String error is captured as message.
+ */
+
+// --- TranslateCorrectionsApi (frontend/src/lib/api/translate/corrections.js)
+/**!
+ * @brief API client for translation corrections — inline edits, dictionary submission, bulk find-and-replace, CSV download.
+ */
+
+// --- TranslateDatasourcesApi (frontend/src/lib/api/translate/datasources.js)
+/**!
+ * @brief API client for translation datasources — column fetching, preview, row-level review actions.
+ */
+
+// --- TranslateDictionariesApi (frontend/src/lib/api/translate/dictionaries.js)
+/**!
+ * @brief API client for translation dictionary CRUD — list, create, update, delete, entries, import.
+ */
+
+// --- TranslateJobsApi (frontend/src/lib/api/translate/jobs.js)
+/**!
+ * @brief API client for translation job CRUD — list, create, update, delete, duplicate.
+ */
+
+// --- TranslateRunsApi (frontend/src/lib/api/translate/runs.js)
+/**!
+ * @brief API client for translation run control — trigger, status, history, records, retry, cancel, metrics.
+ */
+
+// --- TranslateSchedulesApi (frontend/src/lib/api/translate/schedules.js)
+/**!
+ * @brief API client for translation job scheduling — CRUD, enable/disable, next executions.
+ */
+
+// --- TranslateTargetSchemaApi (frontend/src/lib/api/translate/target-schema.js)
+/**!
+ * @brief API client for target table schema validation.
+ */
+
+// --- frontend/src/lib/api/translate/target-schema.js::checkTargetTableSchema (frontend/src/lib/api/translate/target-schema.js)
+/**!
+ */
+
+// --- ValidationApi (frontend/src/lib/api/validation.js)
+/**!
+ * @brief API client functions for the Validation section — tasks and runs CRUD.
+ */
+
+// --- buildParams:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @brief Build URLSearchParams from a params object, skipping null/undefined/empty values.
+ * @param {Record} params
+ */
+
+// --- frontend/src/lib/api/validation.js::buildParams (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchTasks (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- createTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {Record} data
+ */
+
+// --- frontend/src/lib/api/validation.js::createTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- updateTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id @param {Record} data
+ */
+
+// --- frontend/src/lib/api/validation.js::updateTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- deleteTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id @param {boolean} [deleteRuns]
+ */
+
+// --- frontend/src/lib/api/validation.js::deleteTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- triggerRun:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::triggerRun (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- duplicateTask:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::duplicateTask (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchRuns:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {{ task_id?: string, dashboard_id?: string, environment_id?: string, status?: string, date_from?: string, date_to?: string, page?: number, page_size?: number }} [params]
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchRuns (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- fetchRunDetail:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::fetchRunDetail (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- deleteRun:Function (frontend/src/lib/api/validation.js)
+/**!
+ * @param {string} id
+ */
+
+// --- frontend/src/lib/api/validation.js::deleteRun (frontend/src/lib/api/validation.js)
+/**!
+ */
+
+// --- PermissionsTest (frontend/src/lib/auth/__tests__/permissions.test.js)
+/**!
+ * @brief Verifies frontend RBAC permission parsing and access checks.
+ */
+
+// --- PermissionsTest:Module (frontend/src/lib/auth/__tests__/permissions.test.js)
+/**!
+ * @brief Verifies frontend RBAC permission parsing and access checks.
+ */
+
+// --- PermissionsModule (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Shared frontend RBAC utilities for route guards, permission checks, and menu visibility based on user roles.
+ */
+
+// --- Permissions:Module (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Shared frontend RBAC utilities for route guards and menu visibility.
+ * @invariant Admin role always bypasses explicit permission checks.
+ */
+
+// --- normalizePermissionRequirement:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Convert permission requirement string to canonical resource/action tuple.
+ * @post Returns normalized object with action in uppercase.
+ * @pre Permission can be "resource" or "resource:ACTION" where resource itself may contain ":".
+ */
+
+// --- isAdminUser:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Determine whether user has Admin role.
+ * @post Returns true when at least one role name equals "Admin" (case-insensitive).
+ * @pre user can be null or partially populated.
+ */
+
+// --- hasPermission:Function (frontend/src/lib/auth/permissions.js)
+/**!
+ * @brief Check if user has a required resource/action permission.
+ * @post Returns true when requirement is empty, user is admin, or matching permission exists.
+ * @pre user contains roles with permissions from /api/auth/me payload.
+ */
+
+// --- AuthStore (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Manages the global authentication state including JWT token, user profile, and login/logout lifecycle.
+ */
+
+// --- authStore:Store (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Manages the global authentication state on the frontend.
+ */
+
+// --- AuthState:Interface (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Defines the structure of the authentication state.
+ */
+
+// --- frontend/src/lib/auth/store.ts::AuthState (frontend/src/lib/auth/store.ts)
+/**!
+ */
+
+// --- createAuthStore:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Creates and configures the auth store with helper methods.
+ * @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+ * @pre No preconditions - initialization function.
+ * @return {Writable}
+ */
+
+// --- frontend/src/lib/auth/store.ts::createAuthStore (frontend/src/lib/auth/store.ts)
+/**!
+ * @post Returns configured auth store with subscribe, setToken, setUser, logout, setLoading methods.
+ * @pre No preconditions - initialization function.
+ */
+
+// --- setToken:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Updates the store with a new JWT token.
+ * @param {string} token - The JWT access token.
+ * @post Store updated with new token, isAuthenticated set to true.
+ * @pre token must be a valid JWT string.
+ */
+
+// --- setUser:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Sets the current user profile data.
+ * @param {any} user - The user profile object.
+ * @post Store updated with user, isAuthenticated true, loading false.
+ * @pre User object must contain valid profile data.
+ */
+
+// --- logout:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Clears authentication state and storage.
+ * @post Auth token removed from localStorage, store reset to initial state.
+ * @pre User is currently authenticated.
+ */
+
+// --- setLoading:Function (frontend/src/lib/auth/store.ts)
+/**!
+ * @brief Updates the loading state.
+ * @param {boolean} loading - Loading status.
+ * @post Store loading state updated.
+ * @pre None.
+ */
+
+// --- AssistantClarificationCard (frontend/src/lib/components/assistant/AssistantClarificationCard.svelte)
+/**!
+ * @brief Render the active dataset-review clarification queue inside AssistantChatPanel so users can answer, skip, defer, and resume questions without leaving the assistant workspace.
+ * @post Clarification queue state is readable in-chat and answer mutations refresh the active question state without requiring a dedicated dialog.
+ * @pre sessionId belongs to the current dataset review workspace and the assistant drawer is open for session-scoped work.
+ */
+
+// --- readJson:Function (frontend/src/lib/components/assistant/__tests__/assistant_chat.integration.test.js)
+/**!
+ * @brief Read and parse JSON fixture file from disk.
+ * @post Returns parsed object representation.
+ * @pre filePath points to existing UTF-8 JSON file.
+ */
+
+// --- AssistantClarificationIntegrationTest:Module (frontend/src/lib/components/assistant/__tests__/assistant_clarification.integration.test.js)
+/**!
+ * @brief Verify AssistantChatPanel hosts the resumable dataset-review clarification flow inside the assistant drawer and refreshes workspace session state after answering.
+ */
+
+// --- AssistantFirstMessageIntegrationTest:Module (frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js)
+/**!
+ * @brief Verify first optimistic user message stays visible while a new conversation request is pending.
+ * @invariant Starting a new conversation must not trigger history reload that overwrites the first local user message.
+ */
+
+// --- assistant_first_message_tests:Function (frontend/src/lib/components/assistant/__tests__/assistant_first_message.integration.test.js)
+/**!
+ * @brief Guard optimistic first-message UX against history reload race in new conversation flow.
+ * @post First user message remains visible before pending send request resolves.
+ * @pre Assistant panel renders with open state and mocked network dependencies.
+ */
+
+// --- CompiledSQLPreview (frontend/src/lib/components/dataset-review/CompiledSQLPreview.svelte)
+/**!
+ * @brief Present the exact Superset-generated compiled SQL preview, expose readiness or staleness clearly, and preserve readable recovery paths when preview generation fails.
+ * @post Users can distinguish missing, pending, ready, stale, and error preview states and can trigger only Superset-backed preview generation.
+ * @pre Session id is available and preview state comes from the current ownership-scoped session detail payload.
+ */
+
+// --- ExecutionMappingReview (frontend/src/lib/components/dataset-review/ExecutionMappingReview.svelte)
+/**!
+ * @brief Review imported-filter to template-variable mappings, surface effective values and blockers, and require explicit approval for warning-sensitive execution inputs before preview or launch.
+ * @post Users can review effective mapping values, approve warning-sensitive transformations, or manually override them while unresolved required-value blockers remain visible.
+ * @pre Session id, execution mappings, imported filters, and template variables belong to the current ownership-scoped session payload.
+ */
+
+// --- LaunchConfirmationPanel (frontend/src/lib/components/dataset-review/LaunchConfirmationPanel.svelte)
+/**!
+ * @brief Summarize final execution context, surface launch blockers explicitly, and confirm only a gate-complete SQL Lab launch request.
+ * @post Users can see why launch is blocked or confirm a run-ready launch with explicit SQL Lab handoff evidence.
+ * @pre Session detail, mappings, findings, preview state, and latest run context belong to the current ownership-scoped session payload.
+ */
+
+// --- SemanticLayerReview (frontend/src/lib/components/dataset-review/SemanticLayerReview.svelte)
+/**!
+ * @brief Surface field-level semantic decisions with provenance, confidence, candidate acceptance, and manual override safeguards for US2 review flow.
+ * @post Users can review the current semantic value, accept a candidate, apply manual override, and lock or unlock field state without violating backend provenance rules.
+ * @pre Session id is available and semantic field entries come from the current ownership-scoped session detail payload.
+ */
+
+// --- SourceIntakePanel (frontend/src/lib/components/dataset-review/SourceIntakePanel.svelte)
+/**!
+ * @brief Collect initial dataset source input through Superset link paste or dataset selection entry paths.
+ */
+
+// --- ValidationFindingsPanel (frontend/src/lib/components/dataset-review/ValidationFindingsPanel.svelte)
+/**!
+ * @brief Present validation findings grouped by severity with explicit resolution and actionability signals.
+ */
+
+// --- SourceIntakePanelUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/source_intake_panel.ux.test.js)
+/**!
+ * @brief Verify source intake entry paths, validation feedback, and submit payload behavior for US1.
+ */
+
+// --- DatasetReviewUs2WorkspaceUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/us2_semantic_workspace.ux.test.js)
+/**!
+ * @brief Verify US2 dataset review surfaces keep semantic review actionable, route clarification through AssistantChatPanel, and preserve explicit preview/mapping gates.
+ */
+
+// --- DatasetReviewUs3UxTests:Module (frontend/src/lib/components/dataset-review/__tests__/us3_execution_batch.ux.test.js)
+/**!
+ * @brief Verify US3 mapping review, Superset preview, and launch confirmation UX contracts.
+ */
+
+// --- ValidationFindingsPanelUxTests:Module (frontend/src/lib/components/dataset-review/__tests__/validation_findings_panel.ux.test.js)
+/**!
+ * @brief Verify grouped findings visibility, empty state, and remediation jump behavior for US1.
+ */
+
+// --- HealthMatrix (frontend/src/lib/components/health/HealthMatrix.svelte)
+/**!
+ * @brief Visual grid summary representing dashboard health status counts.
+ */
+
+// --- PolicyForm (frontend/src/lib/components/health/PolicyForm.svelte)
+/**!
+ * @brief Form for creating and editing validation policies.
+ * @post Form submission forwards the current draft to onSave and cancel delegates dismissal to the parent callback without mutating external state directly.
+ * @pre Parent provides callable onSave/onCancel handlers and an environments collection that may be empty but remains array-like.
+ */
+
+// --- ScheduleAtAGlance (frontend/src/lib/components/health/ScheduleAtAGlance.svelte)
+/**!
+ * @brief Compact weekly schedule widget showing active validation tasks with day grid, time windows, and cross-referenced health status.
+ */
+
+// --- Sidebar (frontend/src/lib/components/layout/Sidebar.svelte)
+/**!
+ * @brief Persistent left sidebar with grouped sections (Resources/Operations/System), expand/collapse, health indicators, RBAC filtering, profile footer.
+ */
+
+// --- disconnectWebSocket:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Disconnects the active WebSocket connection
+ * @post ws is closed and set to null
+ * @pre ws may or may not be initialized
+ */
+
+// --- loadRecentTasks:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Load recent tasks for list mode display
+ * @post recentTasks array populated with task list
+ * @pre User is on task drawer or api is ready.
+ */
+
+// --- selectTask:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Select a task from list to view details
+ * @post drawer state updated to show task details
+ * @pre task is a valid task object
+ */
+
+// --- goBackToList:Function (frontend/src/lib/components/layout/TaskDrawer.svelte)
+/**!
+ * @brief Return to task list view from task details
+ * @post Drawer switches to list view and reloads tasks
+ * @pre Drawer is open and activeTaskId is set
+ */
+
+// --- SidebarNavigationTest:Module (frontend/src/lib/components/layout/__tests__/sidebarNavigation.test.js)
+/**!
+ * @brief Verifies RBAC-based sidebar sections and category visibility.
+ */
+
+// --- BreadcrumbsContractTest:Module (frontend/src/lib/components/layout/__tests__/test_breadcrumbs.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for Breadcrumbs.svelte logic and UX annotations
+ */
+
+// --- SidebarStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_sidebar.svelte.js)
+/**!
+ * @brief Unit tests for Sidebar.svelte component
+ */
+
+// --- TaskDrawerStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_taskDrawer.svelte.js)
+/**!
+ * @brief Unit tests for TaskDrawer.svelte component
+ */
+
+// --- TopNavbarStoreTest:Module (frontend/src/lib/components/layout/__tests__/test_topNavbar.svelte.js)
+/**!
+ * @brief Unit tests for TopNavbar.svelte component
+ */
+
+// --- PageContracts (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Contract implemented by all Svelte route pages — defines page-level behavior and routing structure.
+ */
+
+// --- NavigationContracts (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Contract for navigation structure — sidebar sections, route categories, and menu item hierarchy.
+ */
+
+// --- SidebarNavigation:Module (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Build sidebar navigation sections and categories filtered by user permissions and feature flags.
+ * @invariant Admin role can access all categories and subitems through permission utility.
+ */
+
+// --- isItemAllowed:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Check whether a single menu node can be shown for a given user.
+ * @post Returns true when no permission is required or permission check passes.
+ * @pre item can contain optional requiredPermission/requiredAction.
+ */
+
+// --- isFeatureEnabled:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ */
+
+// --- buildSidebarSections:Function (frontend/src/lib/components/layout/sidebarNavigation.js)
+/**!
+ * @brief Build translated sidebar sections with categories, filtered by RBAC permissions and feature flags.
+ * @post Returns only sections/categories/subitems available for provided user and enabled features.
+ * @pre i18nState provides nav labels; user can be null; features default to {} (all enabled).
+ */
+
+// --- ReportCardTest:Module (frontend/src/lib/components/reports/__tests__/report_card.ux.test.js)
+/**!
+ * @brief Test UX states and transitions for ReportCard component
+ * @invariant Each test asserts at least one observable UX contract outcome.
+ */
+
+// --- ReportDetailIntegrationTest:Module (frontend/src/lib/components/reports/__tests__/report_detail.integration.test.js)
+/**!
+ * @brief Validate detail-panel behavior for failed reports and recovery guidance visibility.
+ * @invariant Failed report detail exposes actionable next actions when available.
+ */
+
+// --- ReportDetailUxTest:Module (frontend/src/lib/components/reports/__tests__/report_detail.ux.test.js)
+/**!
+ * @brief Test UX states and recovery for ReportDetailPanel component
+ * @invariant Detail UX tests keep placeholder-safe rendering and recovery visibility verifiable.
+ */
+
+// --- [EXT:frontend:ReportTypeProfiles]Test:Module (frontend/src/lib/components/reports/__tests__/report_type_profiles.test.js)
+/**!
+ * @brief Validate report type profile mapping and unknown fallback behavior.
+ * @invariant Unknown task_type always resolves to the fallback profile.
+ */
+
+// --- ReportsFilterPerformanceTest:Module (frontend/src/lib/components/reports/__tests__/reports_filter_performance.test.js)
+/**!
+ * @brief Guard test for report filter responsiveness on moderate in-memory dataset.
+ */
+
+// --- ReportsListTest:Module (frontend/src/lib/components/reports/__tests__/reports_list.ux.test.js)
+/**!
+ * @brief Test ReportsList component iteration and event forwarding.
+ */
+
+// --- ReportsPageTest:Module (frontend/src/lib/components/reports/__tests__/reports_page.integration.test.js)
+/**!
+ * @brief Integration-style checks for unified mixed-type reports rendering expectations.
+ * @invariant Mixed fixture includes all supported report types in one list.
+ */
+
+// --- ReportTypeProfiles:Module (frontend/src/lib/components/reports/reportTypeProfiles.js)
+/**!
+ * @brief Deterministic mapping from report task_type to visual profile with one fallback.
+ */
+
+// --- getReportTypeProfile:Function (frontend/src/lib/components/reports/reportTypeProfiles.js)
+/**!
+ * @brief Resolve visual profile by task type with guaranteed fallback.
+ * @post Returns one profile object.
+ * @pre taskType may be known/unknown/empty.
+ */
+
+// --- ApiKeysTab (frontend/src/lib/components/settings/ApiKeysTab.svelte)
+/**!
+ * @brief API Key management tab — list, generate (one-time reveal), and revoke API keys.
+ */
+
+// --- BulkCorrectionSidebar (frontend/src/lib/components/translate/BulkCorrectionSidebar.svelte)
+/**!
+ * @brief Component component: lib/components/translate/BulkCorrectionSidebar.svelte
+ */
+
+// --- BulkReplaceModal (frontend/src/lib/components/translate/BulkReplaceModal.svelte)
+/**!
+ * @brief Modal dialog for bulk find-and-replace on translated values within a completed run.
+ */
+
+// --- CorrectionCell (frontend/src/lib/components/translate/CorrectionCell.svelte)
+/**!
+ * @brief Inline-editable cell for translation run results with edit-save-cancel UX and submit-to-dictionary flow.
+ */
+
+// --- ScheduleConfig (frontend/src/lib/components/translate/ScheduleConfig.svelte)
+/**!
+ * @brief Component component: lib/components/translate/ScheduleConfig.svelte
+ */
+
+// --- TargetSchemaHint (frontend/src/lib/components/translate/TargetSchemaHint.svelte)
+/**!
+ * @brief Подсказка о колонках целевой таблицы + кнопка "Проверить схему".
+ */
+
+// --- TermCorrectionPopup (frontend/src/lib/components/translate/TermCorrectionPopup.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TermCorrectionPopup.svelte
+ */
+
+// --- TranslationMetricsDashboard (frontend/src/lib/components/translate/TranslationMetricsDashboard.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationMetricsDashboard.svelte
+ */
+
+// --- TranslationPreview (frontend/src/lib/components/translate/TranslationPreview.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationPreview.svelte
+ */
+
+// --- TranslationRunGlobalIndicator (frontend/src/lib/components/translate/TranslationRunGlobalIndicator.svelte)
+/**!
+ * @brief Persistent rich progress panel for active translation runs, rendered in root layout.
+ */
+
+// --- TranslationRunProgress (frontend/src/lib/components/translate/TranslationRunProgress.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationRunProgress.svelte
+ */
+
+// --- TranslationRunResult (frontend/src/lib/components/translate/TranslationRunResult.svelte)
+/**!
+ * @brief Component component: lib/components/translate/TranslationRunResult.svelte
+ */
+
+// --- TargetSchemaHintTest (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Contract-focused unit tests for TargetSchemaHint.svelte component.
+ */
+
+// --- test_component_exists (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Verify component file exists.
+ */
+
+// --- test_ux_state_contracts (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component contains required UX state tags.
+ */
+
+// --- test_props_definition (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component accepts required props.
+ */
+
+// --- test_button_check_disabled_logic (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Button disabled logic: canCheck derived checks all required props.
+ */
+
+// --- test_idle_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Idle state shows hint text and check button.
+ */
+
+// --- test_checking_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Checking state shows spinner and disables button.
+ */
+
+// --- test_complete_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Complete state shows result with green/yellow/red indicators.
+ */
+
+// --- test_error_state (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Error state shows connection error message.
+ */
+
+// --- test_i18n_usage (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component uses i18n _() for all user-facing strings with fallbacks.
+ */
+
+// --- test_abort_controller (frontend/src/lib/components/translate/__tests__/TargetSchemaHint.test.js)
+/**!
+ * @brief Component uses AbortController for request cancellation.
+ */
+
+// --- BulkReplaceModalTests (frontend/src/lib/components/translate/__tests__/test_bulk_replace_modal.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for BulkReplaceModal.svelte component.
+ */
+
+// --- CorrectionCellTests (frontend/src/lib/components/translate/__tests__/test_correction_cell.svelte.js)
+/**!
+ * @brief Contract-focused unit tests for CorrectionCell.svelte component.
+ */
+
+// --- test_component_file_exists:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify component file exists and has required contracts
+ */
+
+// --- TranslateApiTests:Class (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Unit tests for translate API preview functions.
+ */
+
+// --- test_fetchPreview:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify fetchPreview calls postApi with correct endpoint and payload.
+ */
+
+// --- test_approveRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify approveRow calls requestApi with correct action.
+ */
+
+// --- test_editRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify editRow calls requestApi with edit action and translation.
+ */
+
+// --- test_rejectRow:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify rejectRow calls requestApi with reject action.
+ */
+
+// --- test_acceptPreview:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify acceptPreview calls postApi with correct endpoint.
+ */
+
+// --- test_fetchPreviewRecords:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify fetchPreviewRecords calls fetchApi with correct endpoint.
+ */
+
+// --- test_normalizeTranslateError:Function (frontend/src/lib/components/translate/__tests__/test_translation_preview.svelte.js)
+/**!
+ * @brief Verify API errors are normalized consistently.
+ */
+
+// --- I18nModule (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Centralized internationalization management using Svelte stores with Russian and English locale support persisted in LocalStorage.
+ */
+
+// --- i18n:Module (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Centralized internationalization management using Svelte stores.
+ * @invariant Persistence is handled via LocalStorage.
+ */
+
+// --- locale:Store (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Holds the current active locale string.
+ */
+
+// --- t:Store (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Derived store providing the translation dictionary.
+ */
+
+// --- _:Function (frontend/src/lib/i18n/index.ts)
+/**!
+ * @brief Get translation by key path.
+ * @param key - Translation key path (e.g., 'nav.dashboard')
+ * @return Translation string or key if not found
+ */
+
+// --- frontend/src/lib/i18n/index.ts::_ (frontend/src/lib/i18n/index.ts)
+/**!
+ */
+
+// --- StoresModule (frontend/src/lib/stores.js)
+/**!
+ * @brief Global Svelte writable stores for plugins, tasks, and UI page state management.
+ */
+
+// --- stores_module:Module (frontend/src/lib/stores.js)
+/**!
+ * @brief Global state management using Svelte stores.
+ */
+
+// --- plugins:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the list of available plugins.
+ */
+
+// --- tasks:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the list of tasks.
+ */
+
+// --- selectedPlugin:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the currently selected plugin.
+ */
+
+// --- selectedTask:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the currently selected task.
+ */
+
+// --- currentPage:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the current page.
+ */
+
+// --- taskLogs:Data (frontend/src/lib/stores.js)
+/**!
+ * @brief Store for the logs of the currently selected task.
+ */
+
+// --- fetchPlugins:Function (frontend/src/lib/stores.js)
+/**!
+ * @brief Fetches plugins from the API and updates the plugins store.
+ * @post plugins store is updated with data from the API.
+ * @pre None.
+ */
+
+// --- fetchTasks:Function (frontend/src/lib/stores.js)
+/**!
+ * @brief Fetches tasks from the API and updates the tasks store.
+ * @post tasks store is updated with data from the API.
+ * @pre None.
+ */
+
+// --- [EXT:frontend:AssistantChatTest]s (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Unit tests for assistant chat store validating open/close/toggle, conversation binding, session context, and seed message state transitions.
+ */
+
+// --- [EXT:frontend:AssistantChatTest]:Module (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Validate assistant chat store visibility and conversation binding transitions.
+ * @invariant Each test starts from default closed state.
+ */
+
+// --- assistantChatStore_tests:Function (frontend/src/lib/stores/__tests__/assistantChat.test.js)
+/**!
+ * @brief Group store unit scenarios for assistant panel behavior.
+ * @post Open/close/toggle/conversation transitions are validated.
+ * @pre Store can be reset to baseline state in beforeEach hook.
+ */
+
+// --- MockEnvPublic (frontend/src/lib/stores/__tests__/mocks/env_public.js)
+/**!
+ */
+
+// --- mock_env_public:Module (frontend/src/lib/stores/__tests__/mocks/env_public.js)
+/**!
+ * @brief Mock for $env/static/public SvelteKit module in vitest
+ */
+
+// --- EnvironmentMock (frontend/src/lib/stores/__tests__/mocks/environment.js)
+/**!
+ * @brief Mock for $app/environment in vitest, supplying browser, dev, and building flags.
+ */
+
+// --- EnvironmentMock:Module (frontend/src/lib/stores/__tests__/mocks/environment.js)
+/**!
+ * @brief Mock for $app/environment in tests
+ */
+
+// --- NavigationMock (frontend/src/lib/stores/__tests__/mocks/navigation.js)
+/**!
+ * @brief Mock for $app/navigation in vitest, supplying goto, push, replace, prefetch, and prefetchRoutes stubs.
+ */
+
+// --- NavigationMock:Module (frontend/src/lib/stores/__tests__/mocks/navigation.js)
+/**!
+ * @brief Mock for $app/navigation in tests
+ * @invariant Includes SvelteKit v1-only APIs (push, prefetchRoutes) as compatibility surface for legacy test consumers; keep until all imports migrate to SvelteKit v2-compatible mocks.
+ */
+
+// --- StateMock (frontend/src/lib/stores/__tests__/mocks/state.js)
+/**!
+ * @brief Mock for $app/state page data in vitest route/component tests, supplying default params, route, URL, status, and data.
+ */
+
+// --- state_mock:Module (frontend/src/lib/stores/__tests__/mocks/state.js)
+/**!
+ * @brief Mock for AppState in vitest route/component tests.
+ */
+
+// --- StoresMock (frontend/src/lib/stores/__tests__/mocks/stores.js)
+/**!
+ */
+
+// --- StoresMock:Module (frontend/src/lib/stores/__tests__/mocks/stores.js)
+/**!
+ * @brief Mock for $app/stores in tests
+ * @invariant Mocks $app/stores which is a SvelteKit v1 module; SvelteKit v2 uses $app/state. Verify no active test files import this mock before removal.
+ */
+
+// --- SetupTestsModule (frontend/src/lib/stores/__tests__/setupTests.js)
+/**!
+ * @brief Global vitest test setup with mocks for SvelteKit modules ($app/environment, $app/stores, $app/navigation, localStorage).
+ */
+
+// --- setupTests:Module (frontend/src/lib/stores/__tests__/setupTests.js)
+/**!
+ * @brief Global test setup with mocks for SvelteKit modules
+ */
+
+// --- SidebarTest (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Unit tests for sidebar store validating expansion toggles, active item selection, and mobile open/close transitions.
+ */
+
+// --- SidebarTest:Module (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Unit tests for sidebar store
+ * @invariant Sidebar store transitions must be deterministic across desktop/mobile toggles.
+ */
+
+// --- test_sidebar_initial_state:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify initial sidebar store values when no persisted state is available.
+ * @post Default state is { isExpanded: true, activeCategory: 'dashboards', activeItem: '/dashboards', isMobileOpen: false }
+ * @pre No localStorage state
+ * @test Store initializes with default values
+ */
+
+// --- test_toggleSidebar:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify desktop sidebar expansion toggles deterministically.
+ * @post isExpanded is toggled from previous value
+ * @pre Store is initialized
+ * @test toggleSidebar toggles isExpanded state
+ */
+
+// --- test_setActiveItem:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify active-category updates remain deterministic after item selection.
+ * @post activeCategory and activeItem are updated
+ * @pre Store is initialized
+ * @test setActiveItem updates activeCategory and activeItem
+ */
+
+// --- test_mobile_functions:Function (frontend/src/lib/stores/__tests__/sidebar.test.js)
+/**!
+ * @brief Verify mobile sidebar helpers update open-state transitions predictably.
+ * @post isMobileOpen is correctly updated
+ * @pre Store is initialized
+ * @test Mobile functions correctly update isMobileOpen
+ */
+
+// --- TaskDrawerTests (frontend/src/lib/stores/__tests__/taskDrawer.test.js)
+/**!
+ * @brief Unit tests for task drawer store validating open/close, preference-aware opening, resource task mapping, and status-driven cleanup.
+ */
+
+// --- ActivityTestModule (frontend/src/lib/stores/__tests__/test_activity.js)
+/**!
+ * @brief Unit tests validating activity store derived count and recent task tracking behavior.
+ */
+
+// --- ActivityTest:Module (frontend/src/lib/stores/__tests__/test_activity.js)
+/**!
+ * @brief Unit tests for activity store
+ */
+
+// --- DatasetReviewSessionTests (frontend/src/lib/stores/__tests__/test_datasetReviewSession.js)
+/**!
+ * @brief Unit tests for dataset review session store: session set/reset, loading, error, dirty flag, and patch operations.
+ */
+
+// --- DatasetReviewSessionStoreTests:Module (frontend/src/lib/stores/__tests__/test_datasetReviewSession.js)
+/**!
+ * @brief Unit tests for dataset review session store.
+ */
+
+// --- SidebarTestModule (frontend/src/lib/stores/__tests__/test_sidebar.js)
+/**!
+ * @brief Unit tests for sidebar store validating initial state, toggle, navigation, mobile overlay, and localStorage persistence.
+ */
+
+// --- SidebarIntegrationTest:Module (frontend/src/lib/stores/__tests__/test_sidebar.js)
+/**!
+ * @brief Unit tests for sidebar store
+ */
+
+// --- TaskDrawerTestModule (frontend/src/lib/stores/__tests__/test_taskDrawer.js)
+/**!
+ * @brief Unit tests for task drawer store validating open/close transitions, preference-aware opening, and resource-task mapping lifecycle.
+ */
+
+// --- TaskDrawerTest:Module (frontend/src/lib/stores/__tests__/test_taskDrawer.js)
+/**!
+ * @brief Unit tests for task drawer store
+ * @invariant Store state transitions remain deterministic for open/close and task-status mapping.
+ */
+
+// --- ActivityStore (frontend/src/lib/stores/activity.js)
+/**!
+ * @brief Derived store that counts active running tasks for navbar indicator badge.
+ */
+
+// --- activity:Store (frontend/src/lib/stores/activity.js)
+/**!
+ * @brief Track active task count for navbar indicator
+ */
+
+// --- AssistantChatStore (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Control assistant chat panel visibility, conversation binding, session context, and seeded prompts.
+ */
+
+// --- assistantChat:Store (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Control assistant chat panel visibility and active conversation binding.
+ */
+
+// --- toggleAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Toggle assistant panel visibility.
+ * @post isOpen value inverted.
+ * @pre Store is initialized.
+ */
+
+// --- openAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Open assistant panel.
+ * @post isOpen = true.
+ * @pre Store is initialized.
+ */
+
+// --- openAssistantChatWithContext:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Open assistant panel with dataset review session context and optional seeded prompt/focus target.
+ * @post Assistant drawer opens with session binding and visible focus metadata.
+ * @pre Context payload may be partial.
+ */
+
+// --- closeAssistantChat:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Close assistant panel.
+ * @post isOpen = false.
+ * @pre Store is initialized.
+ */
+
+// --- setAssistantConversationId:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Bind current conversation id in UI state.
+ * @post store.conversationId updated.
+ * @pre conversationId is string-like identifier.
+ */
+
+// --- setAssistantDatasetReviewSessionId:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Bind active dataset review session to assistant state.
+ * @post store.datasetReviewSessionId updated.
+ * @pre session identifier may be null when workspace context is cleared.
+ */
+
+// --- setAssistantSeedMessage:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Stage a seeded assistant prompt for contextual send UX.
+ * @post store.seedMessage updated.
+ * @pre seedMessage can be empty to clear staged draft.
+ */
+
+// --- setAssistantFocusTarget:Function (frontend/src/lib/stores/assistantChat.js)
+/**!
+ * @brief Track the workspace entity currently referenced by assistant context.
+ * @post store.focusTarget updated.
+ * @pre focusTarget may be null to clear prior focus.
+ */
+
+// --- DatasetReviewSessionStore (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ * @brief Manage active dataset review session state including loading, local edits, error capture, and reset semantics.
+ * @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+ * @pre Consumers provide session-shaped payloads and initialize the store before reading derived session fields.
+ */
+
+// --- datasetReviewSession:Store (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ * @brief Manage active dataset review session state, including loading, local edits, error capture, and reset semantics for the active review workspace.
+ * @post Store transitions keep session, loading, error, and dirty flags internally consistent after each helper call.
+ * @pre Consumers provide session-shaped payloads when setting or patching state and initialize the store before reading derived session fields.
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setLoading (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setError (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::setDirty (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::resetSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::patchSession (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/datasetReviewSession.js::getSessionUiPhase (frontend/src/lib/stores/datasetReviewSession.js)
+/**!
+ */
+
+// --- EnvironmentContextStore (frontend/src/lib/stores/environmentContext.js)
+/**!
+ * @brief Global selected environment context for navigation, safety cues, and environment-based filtering.
+ */
+
+// --- environmentContext:Store (frontend/src/lib/stores/environmentContext.js)
+/**!
+ * @brief Global selected environment context for navigation and safety cues.
+ */
+
+// --- HealthStore (frontend/src/lib/stores/health.js)
+/**!
+ * @brief Manage dashboard health summary state and failing counts for UI badges.
+ */
+
+// --- health_store:Store (frontend/src/lib/stores/health.js)
+/**!
+ * @brief Manage dashboard health summary state and failing counts for UI badges.
+ */
+
+// --- frontend/src/lib/stores/health.js::createHealthStore (frontend/src/lib/stores/health.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/health.js::refresh (frontend/src/lib/stores/health.js)
+/**!
+ */
+
+// --- MaintenanceStore (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ * @brief Svelte 5 (Runes) store for maintenance banner state. Auto-polls events every 30s via interval.
+ * @return {object} Maintenance store with runes state and methods.
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::createMaintenanceStore (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- MaintenanceStore.state (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- MaintenanceStore.methods (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadEvents (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadDashboardBanners (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::loadSettings (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::endEvent (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::endAllEvents (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::updateSettings (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::init (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::startPolling (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/maintenance.svelte.js::stopPolling (frontend/src/lib/stores/maintenance.svelte.js)
+/**!
+ */
+
+// --- SidebarStore (frontend/src/lib/stores/sidebar.js)
+/**!
+ * @brief Manage sidebar visibility, expansion state, active navigation item, and mobile overlay.
+ */
+
+// --- sidebar:Store (frontend/src/lib/stores/sidebar.js)
+/**!
+ * @brief Manage sidebar visibility and navigation state
+ * @invariant isExpanded state is always synced with localStorage
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::toggleSidebar (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::setActiveItem (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::setMobileOpen (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::closeMobile (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/sidebar.js::toggleMobileSidebar (frontend/src/lib/stores/sidebar.js)
+/**!
+ */
+
+// --- TaskDrawerStore (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ * @brief Manage Task Drawer visibility, active task binding, and resource-to-task mapping.
+ */
+
+// --- taskDrawer:Store (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ * @brief Manage Task Drawer visibility and resource-to-task mapping
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawerForTask (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::setTaskDrawerAutoOpenPreference (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::getTaskDrawerAutoOpenPreference (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawerForTaskIfPreferred (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::openDrawer (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::closeDrawer (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::updateResourceTask (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/taskDrawer.js::getTaskForResource (frontend/src/lib/stores/taskDrawer.js)
+/**!
+ */
+
+// --- TranslationRunStore (frontend/src/lib/stores/translationRun.js)
+/**!
+ * @brief Global store for active translation run progress — survives page navigation.
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::clearOnCompleteCallback (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::startTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::stopTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::resetTranslationRun (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::updateTranslationRunState (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- frontend/src/lib/stores/translationRun.js::pollStatus (frontend/src/lib/stores/translationRun.js)
+/**!
+ */
+
+// --- ToastsModule (frontend/src/lib/toasts.js)
+/**!
+ * @brief Manages toast notifications using a Svelte writable store with deduplication and auto-removal.
+ */
+
+// --- toasts_module:Module (frontend/src/lib/toasts.js)
+/**!
+ * @brief Manages toast notifications using a Svelte writable store.
+ */
+
+// --- toasts:Data (frontend/src/lib/toasts.js)
+/**!
+ * @brief Writable store containing the list of active toasts.
+ */
+
+// --- addToast:Function (frontend/src/lib/toasts.js)
+/**!
+ * @brief Adds a new toast message.
+ * @param duration (number) - Duration in ms before the toast is removed.
+ * @post New toast is added to the store and scheduled for removal.
+ * @pre message string is provided.
+ */
+
+// --- removeToast:Function (frontend/src/lib/toasts.js)
+/**!
+ * @brief Removes a toast message by ID.
+ * @param id (string) - The ID of the toast to remove.
+ * @post Toast is removed from the store.
+ * @pre id is provided.
+ */
+
+// --- Button (frontend/src/lib/ui/Button.svelte)
+/**!
+ * @brief Standardized button component with variants and loading states.
+ * @invariant Supports accessible labels and keyboard navigation.
+ */
+
+// --- Card (frontend/src/lib/ui/Card.svelte)
+/**!
+ * @brief Standardized container with padding and elevation.
+ */
+
+// --- Icon (frontend/src/lib/ui/Icon.svelte)
+/**!
+ * @brief Render the shared inline SVG icon set with consistent sizing and stroke props.
+ * @invariant Icon output remains aria-hidden because labels belong to the interactive parent.
+ */
+
+// --- Input (frontend/src/lib/ui/Input.svelte)
+/**!
+ * @brief Standardized text input component with label and error handling.
+ * @invariant Consistent spacing and focus states.
+ */
+
+// --- LanguageSwitcher (frontend/src/lib/ui/LanguageSwitcher.svelte)
+/**!
+ * @brief Dropdown component to switch between supported languages.
+ */
+
+// --- PageHeader (frontend/src/lib/ui/PageHeader.svelte)
+/**!
+ * @brief Standardized page header with title and action area.
+ */
+
+// --- Select (frontend/src/lib/ui/Select.svelte)
+/**!
+ * @brief Standardized dropdown selection component.
+ */
+
+// --- ui:Module (frontend/src/lib/ui/index.ts)
+/**!
+ * @brief Central export point for standardized UI components.
+ * @invariant All components exported here must follow Semantic Protocol.
+ */
+
+// --- UtilsModule (frontend/src/lib/utils.js)
+/**!
+ */
+
+// --- Utils:Module (frontend/src/lib/utils.js)
+/**!
+ * @brief General utility functions (class merging)
+ */
+
+// --- frontend/src/lib/utils.js::cn (frontend/src/lib/utils.js)
+/**!
+ */
+
+// --- DebounceModule (frontend/src/lib/utils/debounce.js)
+/**!
+ */
+
+// --- Debounce:Module (frontend/src/lib/utils/debounce.js)
+/**!
+ * @brief Debounce utility for limiting function execution rate
+ */
+
+// --- frontend/src/lib/utils/debounce.js::debounce (frontend/src/lib/utils/debounce.js)
+/**!
+ */
+
+// --- onMount:Function (frontend/src/pages/Dashboard.svelte)
+/**!
+ * @brief Fetch plugins when the component mounts.
+ * @post plugins store is populated with available tools.
+ * @pre Component is mounting.
+ */
+
+// --- selectPlugin:Function (frontend/src/pages/Dashboard.svelte)
+/**!
+ * @brief Selects a plugin to display its form.
+ * @param {Object} plugin - The plugin object to select.
+ * @post selectedPlugin store is updated.
+ * @pre plugin object is provided.
+ */
+
+// --- loadSettings:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Loads settings from the backend.
+ * @post settings object is populated with backend data.
+ * @pre Component mounted or refresh requested.
+ */
+
+// --- handleSaveGlobal:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Saves global settings to the backend.
+ * @post Backend global settings are updated.
+ * @pre settings.settings contains valid configuration.
+ */
+
+// --- handleAddOrUpdateEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Adds or updates an environment.
+ * @post Environment list is updated on backend and reloaded locally.
+ * @pre newEnv contains valid environment details.
+ */
+
+// --- handleDeleteEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Deletes an environment.
+ * @param {string} id - The ID of the environment to delete.
+ * @post Environment is removed from backend and list is reloaded.
+ * @pre id of environment to delete is provided.
+ */
+
+// --- handleTestEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Tests the connection to an environment.
+ * @param {string} id - The ID of the environment to test.
+ * @post Connection test result is displayed via toast.
+ * @pre Environment ID is valid.
+ */
+
+// --- editEnv:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Sets the form to edit an existing environment.
+ * @param {Object} env - The environment object to edit.
+ * @post newEnv is populated with env data and editingEnvId is set.
+ * @pre env object is provided.
+ */
+
+// --- resetEnvForm:Function (frontend/src/pages/Settings.svelte)
+/**!
+ * @brief Resets the environment form.
+ * @post newEnv is reset to initial state and editingEnvId is cleared.
+ * @pre None.
+ */
+
+// --- ErrorPage (frontend/src/routes/+error.svelte)
+/**!
+ * @brief Global error page displaying HTTP status code and error message with navigation back to dashboard.
+ */
+
+// --- RootLayout (frontend/src/routes/+layout.svelte)
+/**!
+ * @brief Root layout component providing global UI structure: Sidebar, TopNavbar, Footer, TaskDrawer, Toasts.
+ * @invariant Sidebar width adapts (ml-60 vs ml-16) based on sidebar expanded state.
+ */
+
+// --- RootLayoutConfig:Module (frontend/src/routes/+layout.ts)
+/**!
+ * @brief Root layout configuration (SPA mode)
+ */
+
+// --- HomePage (frontend/src/routes/+page.svelte)
+/**!
+ * @brief Redirect to preferred start page (dashboards/datasets/reports) based on profile settings, with safe fallback.
+ * @invariant Redirect target resolves to one of /dashboards, /datasets, /reports.
+ */
+
+// --- load:Function (frontend/src/routes/+page.ts)
+/**!
+ * @brief Loads initial plugin data for the dashboard.
+ * @post Returns an object with plugins or an error message.
+ * @pre None.
+ */
+
+// --- frontend/src/routes/+page.ts::load (frontend/src/routes/+page.ts)
+/**!
+ */
+
+// --- openCreateModal:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Initializes state for creating a new role.
+ * @post showModal is true, roleForm is reset.
+ * @pre None.
+ */
+
+// --- openEditModal:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Initializes state for editing an existing role.
+ * @post showModal is true, roleForm is populated.
+ * @pre role object is provided.
+ */
+
+// --- handleSaveRole:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Submits role data (create or update).
+ * @post Role is saved, modal closed, data reloaded.
+ * @pre roleForm contains valid data.
+ */
+
+// --- handleDeleteRole:Function (frontend/src/routes/admin/roles/+page.svelte)
+/**!
+ * @brief Deletes a role after confirmation.
+ * @post Role is deleted if confirmed, data reloaded.
+ * @pre role object is provided.
+ */
+
+// --- handleCreateMapping:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Submits a new AD Group to Role mapping to the backend.
+ * @post A new mapping is created in the database and the table is refreshed.
+ * @pre 'newMapping' object contains valid 'ad_group' and 'role_id'.
+ * @return {Promise}
+ */
+
+// --- loadLoggingConfig:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Fetches current logging configuration from the backend.
+ * @post loggingConfig variable is updated with backend data.
+ * @pre Component is mounted and user has active session.
+ * @return {Promise}
+ */
+
+// --- saveLoggingConfig:Function (frontend/src/routes/admin/settings/+page.svelte)
+/**!
+ * @brief Saves logging configuration to the backend.
+ * @post Configuration is saved and feedback is shown.
+ * @pre loggingConfig contains valid values.
+ * @return {Promise}
+ */
+
+// --- LLMReportPage (frontend/src/routes/admin/settings/llm/+page.svelte)
+/**!
+ * @brief Admin settings page for LLM provider configuration.
+ */
+
+// --- handleSaveUser:Function (frontend/src/routes/admin/users/+page.svelte)
+/**!
+ * @brief Submits user data to the backend (create or update).
+ * @post User created or updated, modal closed, data reloaded.
+ * @pre userForm must be valid.
+ */
+
+// --- handleDeleteUser:Function (frontend/src/routes/admin/users/+page.svelte)
+/**!
+ * @brief Deletes a user after confirmation.
+ * @param {Object} user - The user to delete.
+ * @post User deleted if confirmed, data reloaded.
+ * @pre user object must be valid.
+ */
+
+// --- DashboardHub.normalizeTaskStatus:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize raw task status to stable lowercase token for UI.
+ * @post returns null or normalized token without enum namespace.
+ * @pre status can be enum-like string or null.
+ */
+
+// --- DashboardHub.normalizeValidationStatus:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize validation status to pass/fail/warn/unknown.
+ * @post returns one of pass|fail|warn|unknown.
+ * @pre status can be any scalar.
+ */
+
+// --- DashboardHub.getValidationBadgeClass:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Map validation level to badge class tuple.
+ * @post returns deterministic tailwind class string.
+ * @pre level in pass|fail|warn|unknown.
+ */
+
+// --- DashboardHub.getValidationLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Map normalized validation level to compact UI label.
+ * @post returns uppercase status label.
+ * @pre level in pass|fail|warn|unknown.
+ */
+
+// --- DashboardHub.normalizeOwners:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Normalize owners payload to unique non-empty display labels.
+ * @post Returns owner labels preserving source order.
+ * @pre owners can be null, list of strings, or list of user objects.
+ */
+
+// --- DashboardHub.loadDashboards:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Load full dashboard dataset for current environment and hydrate grid projection.
+ * @post allDashboards, dashboards, pagination and selection state are synchronized.
+ * @pre selectedEnv is not null.
+ */
+
+// --- DashboardHub.handleTemporaryShowAll:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Temporarily disable profile-default dashboard filter for current page context.
+ * @post Next request is sent with override_show_all=true.
+ * @pre Dashboards list is loaded in dashboards_main context.
+ */
+
+// --- DashboardHub.handleRestoreProfileFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Re-enable persisted profile-default filtering after temporary override.
+ * @post Next request is sent with override_show_all=false.
+ * @pre Current page is in override mode.
+ */
+
+// --- DashboardHub.formatDate:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Convert ISO timestamp to locale date string.
+ * @post returns formatted date or "-".
+ * @pre value may be null or invalid date string.
+ */
+
+// --- DashboardHub.getGitSummaryLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute stable text label for git state column.
+ * @post returns localized summary string.
+ * @pre dashboard has git projection fields.
+ */
+
+// --- DashboardHub.getLlmSummaryLabel:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute normalized LLM validation summary label.
+ * @post returns UNKNOWN fallback for missing status.
+ * @pre dashboard may have null lastTask.
+ */
+
+// --- DashboardHub.getColumnCellValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Resolve comparable/filterable display value for any grid column.
+ * @post returns non-empty scalar display value.
+ * @pre column belongs to filterable column set.
+ */
+
+// --- DashboardHub.getFilterOptions:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Build unique sorted value list for a column filter dropdown.
+ * @post returns de-duplicated sorted options.
+ * @pre allDashboards is hydrated.
+ */
+
+// --- DashboardHub.getVisibleFilterOptions:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Apply in-dropdown search over full filter options.
+ * @post returns subset for current filter popover list.
+ * @pre columnFilterSearch contains search token for column.
+ */
+
+// --- DashboardHub.toggleFilterDropdown:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Toggle active column filter popover.
+ * @post openFilterColumn updated.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.toggleFilterValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Add/remove specific filter value and reapply projection.
+ * @post columnFilters updated and grid reprojected from page 1.
+ * @pre value comes from option list of the same column.
+ */
+
+// --- DashboardHub.clearColumnFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Reset selected values for one column.
+ * @post filter cleared and projection refreshed.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.selectAllColumnFilterValues:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Select all currently visible values in filter popover.
+ * @post column filter equals current visible option set.
+ * @pre visible options computed for current search token.
+ */
+
+// --- DashboardHub.updateColumnFilterSearch:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Update local search token for one filter popover.
+ * @post columnFilterSearch updated immutably.
+ * @pre value is text from input.
+ */
+
+// --- DashboardHub.hasColumnFilter:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Determine if column has active selected values.
+ * @post returns boolean activation marker.
+ * @pre column is valid filter key.
+ */
+
+// --- DashboardHub.doesDashboardPassColumnFilters:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Evaluate dashboard row against all active column filters.
+ * @post returns true only when row matches every active filter.
+ * @pre dashboard contains projected values for each filterable column.
+ */
+
+// --- DashboardHub.getSortValue:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Compute stable comparable sort key for chosen column.
+ * @post returns string/number key suitable for deterministic comparison.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.handleSort:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Toggle or switch sort order and reapply grid projection.
+ * @post sortColumn/sortDirection updated and page reset to 1.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.getSortIndicator:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Return visual indicator for active/inactive sort header.
+ * @post returns one of ↕ | ↑ | ↓.
+ * @pre column belongs to sortable set.
+ */
+
+// --- DashboardHub.applyGridTransforms:Function (frontend/src/routes/dashboards/+page.svelte)
+/**!
+ * @brief Apply search + column filters + sort + pagination to grid data.
+ * @post filteredDashboards/dashboards/total/totalPages are synchronized.
+ * @pre allDashboards is current source collection.
+ */
+
+// --- DashboardHeader (frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte)
+/**!
+ * @brief Top title area, breadcrumb, Git branch selector, and action buttons for dashboard detail.
+ */
+
+// --- DashboardProfileOverrideIntegrationTest:Module (frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js)
+/**!
+ * @brief Verifies temporary show-all override and restore-on-return behavior for profile-default dashboard filtering.
+ */
+
+// --- HealthCenterPage (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Main page for the Dashboard Health Center showing health matrix table with environment filtering.
+ */
+
+// --- loadData:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Load health summary rows and environment options for the current filter.
+ * @post `healthData` and `environments` reflect latest backend response.
+ * @pre Page is mounted or environment selection changed.
+ */
+
+// --- handleEnvChange:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Apply environment filter and trigger health summary reload.
+ * @post selectedEnvId is updated and new data load starts.
+ * @pre DOM change event carries target value.
+ */
+
+// --- handleDeleteReport:Function (frontend/src/routes/dashboards/health/+page.svelte)
+/**!
+ * @brief Delete one health report row with confirmation and optimistic button lock.
+ * @post Row is removed from backend and page data is reloaded on success.
+ * @pre item contains `record_id` from health summary payload.
+ */
+
+// --- HealthPageIntegrationTest:Module (frontend/src/routes/dashboards/health/__tests__/health_page.integration.test.js)
+/**!
+ * @brief Lock dashboard health page contract for slug navigation and report deletion.
+ */
+
+// --- DatasetHub (frontend/src/routes/datasets/+page.svelte)
+/**!
+ */
+
+// --- ColumnsTable (frontend/src/routes/datasets/ColumnsTable.svelte)
+/**!
+ * @brief Table of dataset columns with type chips, description, and inline-edit capability.
+ */
+
+// --- DatasetList (frontend/src/routes/datasets/DatasetList.svelte)
+/**!
+ * @brief Renders paginated dataset cards with mapping progress bars, checkboxes, and quick actions.
+ */
+
+// --- DatasetPreview (frontend/src/routes/datasets/DatasetPreview.svelte)
+/**!
+ * @brief Right panel showing dataset detail: header info, columns table, metrics table, linked dashboards. Presentational.
+ */
+
+// --- MetricsTable (frontend/src/routes/datasets/MetricsTable.svelte)
+/**!
+ * @brief Table of dataset metrics with expression, description, and inline-edit capability.
+ */
+
+// --- StatsBar (frontend/src/routes/datasets/StatsBar.svelte)
+/**!
+ * @brief Compact filter pills showing aggregate counts (All, Without mapping, Mapped, Linked).
+ */
+
+// --- DatasetReviewWorkspaceEntry (frontend/src/routes/datasets/review/+page.svelte)
+/**!
+ * @brief Entry route for Dataset Review Workspace — start a new resumable review session or navigate to existing sessions.
+ */
+
+// --- ReviewWorkspaceHeader (frontend/src/routes/datasets/review/ReviewWorkspaceHeader.svelte)
+/**!
+ * @brief Header section for the dataset review workspace with title, description, and status badges.
+ */
+
+// --- ReviewWorkspaceLeftSidebar (frontend/src/routes/datasets/review/ReviewWorkspaceLeftSidebar.svelte)
+/**!
+ * @brief Left sidebar for dataset review workspace: source info, import status, session summary, clarification focus, primary actions.
+ */
+
+// --- ReviewWorkspaceRightRail (frontend/src/routes/datasets/review/ReviewWorkspaceRightRail.svelte)
+/**!
+ * @brief Right rail for dataset review workspace: next action, blockers, health counts, exports, SQL preview, launch panel.
+ */
+
+// --- DatasetReviewWorkspace (frontend/src/routes/datasets/review/[id]/+page.svelte)
+/**!
+ * @brief Main dataset review workspace — thin shell delegating to extracted components.
+ * @deprecated N/A — active workspace page.
+ */
+
+// --- DatasetReviewEntryUxTests (frontend/src/routes/datasets/review/__tests__/dataset_review_entry.test.js)
+/**!
+ * @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+ */
+
+// --- DatasetReviewEntryUxPageTests (frontend/src/routes/datasets/review/__tests__/dataset_review_entry.ux.test.js)
+/**!
+ * @brief Verify dataset review entry route exposes resumable sessions alongside the new session intake flow.
+ */
+
+// --- ReviewWorkspaceHelpers (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ * @brief Shared helper functions for the dataset review workspace.
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildImportMilestones (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildWorkspaceLaunchBlockers (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantSeedPrompt (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::buildAssistantContextPrompt (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getWorkspaceStateLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getRecommendedActionLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::getPrimaryActionCtaLabel (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::mergeCollectionItem (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- frontend/src/routes/datasets/review/review-workspace-helpers.js::stringifyValue (frontend/src/routes/datasets/review/review-workspace-helpers.js)
+/**!
+ */
+
+// --- UseReviewSession (frontend/src/routes/datasets/review/useReviewSession.js)
+/**!
+ * @brief Composable for dataset review session state management — load, update, export, and clarify.
+ */
+
+// --- GitDashboardPage (frontend/src/routes/git/+page.svelte)
+/**!
+ * @brief Git integration page for selecting environments and managing dashboard repositories.
+ */
+
+// --- LoginPage (frontend/src/routes/login/+page.svelte)
+/**!
+ * @brief Provides the user interface for local (username/password) and ADFS SSO authentication.
+ * @invariant Shows both local login form and ADFS SSO button.
+ */
+
+// --- MaintenanceBannerPage (frontend/src/routes/maintenance/+page.svelte)
+/**!
+ * @brief Maintenance Banners management page. Composes SettingsPanel and EventsTable from store.
+ */
+
+// --- ReactiveDashboardFetch:Block (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Automatically fetch dashboards when the source environment is changed.
+ * @post fetchDashboards is called with the new sourceEnvId.
+ * @pre sourceEnvId is not empty.
+ */
+
+// --- handleMappingUpdate:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Saves a mapping to the backend.
+ * @post Mapping is saved and local mappings list is updated.
+ * @pre event.detail contains sourceUuid and targetUuid.
+ */
+
+// --- handleViewLogs:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Opens the log viewer for a specific task.
+ * @post logViewer state updated and showLogViewer set to true.
+ * @pre event.detail contains task object.
+ */
+
+// --- handlePasswordPrompt:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Reactive logic to show password prompt when a task is awaiting input.
+ * @post showPasswordPrompt set to true with request data.
+ * @pre selectedTask status is AWAITING_INPUT.
+ */
+
+// --- ReactivePasswordPrompt:Block (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Monitor selected task for input requests and trigger password prompt.
+ * @post showPasswordPrompt is set to true if input_request is database_password.
+ * @pre $selectedTask is not null and status is AWAITING_INPUT.
+ */
+
+// --- handleResumeMigration:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Resumes a migration task with provided passwords.
+ * @post resumeTask is called and showPasswordPrompt is hidden on success.
+ * @pre event.detail contains passwords.
+ */
+
+// --- startMigration:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Initiates the migration process by sending the selection to the backend.
+ * @post A migration task is created and selectedTask store is updated.
+ * @pre sourceEnvId and targetEnvId are set and different; at least one dashboard is selected.
+ */
+
+// --- startDryRun:Function (frontend/src/routes/migration/+page.svelte)
+/**!
+ * @brief Performs a dry-run migration to identify potential risks and changes.
+ * @post dryRunResult is populated with the pre-flight analysis.
+ * @pre source/target environments and selected dashboards are valid.
+ */
+
+// --- MigrationMappingsPage (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Render and orchestrate mapping management UI for source/target environments with backend persistence.
+ * @invariant Persisted mapping state in backend remains the source of truth for rendered mapping pairs.
+ * @post UI exposes deterministic Idle/Loading/Error/Success states for environment loading, database fetch, and mapping save.
+ * @pre Translation store and API client are available; route is mounted in authenticated UI shell.
+ */
+
+// --- MappingsPageScript:Block (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Define imports, state, and handlers that drive migration mappings page FSM.
+ */
+
+// --- Imports:Block (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ */
+
+// --- UiState:Store (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Maintain local page state for environments, fetched databases, mappings, suggestions, and UX messages.
+ */
+
+// --- belief_scope:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Frontend semantic scope wrapper for CRITICAL trace boundaries without changing business behavior.
+ * @post Executes run exactly once and returns/rejects with the same outcome.
+ * @pre scopeId is non-empty and run is callable.
+ */
+
+// --- fetchDatabases:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Fetch both environment database catalogs, existing mappings, and suggested matches.
+ * @post fetchingDbs=false and sourceDatabases/targetDatabases/mappings/suggestions updated or error set.
+ * @pre sourceEnvId and targetEnvId are both selected and non-empty.
+ */
+
+// --- handleUpdate:Function (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Persist a selected mapping pair and reconcile local mapping list by source database UUID.
+ * @post mapping persisted; local mappings replaced for same source UUID; success or error feedback shown.
+ * @pre event.detail includes sourceUuid/targetUuid and matching source/target database records exist.
+ */
+
+// --- MappingsPageTemplate (frontend/src/routes/migration/mappings/+page.svelte)
+/**!
+ * @brief Mapping page template with environment selectors, database mapping table, and action buttons.
+ */
+
+// --- ProfilePage (frontend/src/routes/profile/+page.svelte)
+/**!
+ * @brief User profile page for viewing and editing personal preferences and settings.
+ */
+
+// --- ProfileFixtures:Module (frontend/src/routes/profile/__tests__/fixtures/profile.fixtures.js)
+/**!
+ * @brief Shared deterministic fixture inputs for profile page integration tests.
+ * @invariant lookupFailedManualFallback.warning is a hardcoded English string; drift risk if i18n key profile.lookup_error changes without updating this fixture.
+ */
+
+// --- ProfilePreferencesIntegrationTest (frontend/src/routes/profile/__tests__/profile-preferences.integration.test.js)
+/**!
+ * @brief Verifies profile page loads preferences and saves them.
+ */
+
+// --- ProfileSettingsStateIntegrationTest (frontend/src/routes/profile/__tests__/profile-settings-state.integration.test.js)
+/**!
+ * @brief Verifies profile loads preferences, allows changes, and saves correctly.
+ */
+
+// --- UnifiedReportsPage (frontend/src/routes/reports/+page.svelte)
+/**!
+ * @brief Unified reports page with task-type and status filtering, list selection, detail panel, and resilient UX states for mixed task types.
+ */
+
+// --- ReportPageContractTest:Module (frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js)
+/**!
+ * @brief Protect the LLM report page from self-triggering screenshot load effects.
+ */
+
+// --- llm_report_screenshot_effect_contract:Function (frontend/src/routes/reports/llm/[taskId]/report_page.contract.test.js)
+/**!
+ * @brief Ensure screenshot loading stays untracked from blob-url mutation state.
+ * @post Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.
+ * @pre Report page source exists.
+ */
+
+// --- SettingsPage (frontend/src/routes/settings/+page.svelte)
+/**!
+ * @brief Consolidated Settings Page shell — thin layout that delegates each tab to its own component.
+ * @deprecated N/A
+ * @post Page exposes consolidated settings tabs; each tab manages its own state.
+ * @pre Route is loaded in the authenticated UI shell.
+ */
+
+// --- frontend/src/routes/settings/+page.ts::load (frontend/src/routes/settings/+page.ts)
+/**!
+ */
+
+// --- FeaturesSettings (frontend/src/routes/settings/FeaturesSettings.svelte)
+/**!
+ * @brief Feature flags configuration tab: enable/disable top-level application features.
+ * @post User can toggle feature flags.
+ * @pre settings object with features config is provided.
+ */
+
+// --- LlmSettings (frontend/src/routes/settings/LlmSettings.svelte)
+/**!
+ * @brief LLM configuration tab: providers, bindings, prompts for chatbot and validation.
+ * @post User can configure LLM provider bindings and prompts.
+ * @pre settings object with llm config and llm_providers list is provided.
+ */
+
+// --- LoggingSettings (frontend/src/routes/settings/LoggingSettings.svelte)
+/**!
+ * @brief Logging configuration tab: log level, task log level, belief state toggle.
+ * @post User can adjust logging levels and toggle belief state.
+ * @pre settings object with logging config is provided.
+ */
+
+// --- MigrationMappingsTable (frontend/src/routes/settings/MigrationMappingsTable.svelte)
+/**!
+ * @brief Mappings data table with search, filtering, and pagination for migration sync resources. Isolated from the main MigrationSettings to keep each module < 400 lines.
+ * @post User can search, filter by environment/type, and paginate through resource mappings.
+ * @pre API client initialized, refreshKey provided by parent.
+ */
+
+// --- MigrationSettings (frontend/src/routes/settings/MigrationSettings.svelte)
+/**!
+ * @brief Migration sync configuration tab: cron schedule, sync now, mappings table with filtering and pagination.
+ * @post User can configure sync schedule, trigger sync, and browse resource mappings.
+ * @pre API client initialized.
+ */
+
+// --- StorageSettings (frontend/src/routes/settings/StorageSettings.svelte)
+/**!
+ * @brief Storage configuration tab: root path, backup path, repo path.
+ * @post User can view and edit storage paths.
+ * @pre settings object with storage config is provided.
+ */
+
+// --- SystemSettings (frontend/src/routes/settings/SystemSettings.svelte)
+/**!
+ * @brief System settings tab: timezone configuration and API key management.
+ * @post User can select the application timezone and manage API keys.
+ * @pre settings object is provided with app_timezone field.
+ */
+
+// --- SettingsPageUxTest:Module (frontend/src/routes/settings/__tests__/settings_page.ux.test.js)
+/**!
+ * @brief Test UX states and transitions
+ */
+
+// --- AutomationPage (frontend/src/routes/settings/automation/+page.svelte)
+/**!
+ * @brief Settings page for managing validation policies.
+ */
+
+// --- loadConfigs:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Fetches existing git configurations.
+ * @post configs state is populated.
+ * @pre Component is mounted.
+ */
+
+// --- handleTest:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Tests connection to a git server with current form data.
+ * @post testing state is managed; toast shown with result.
+ * @pre newConfig contains valid provider, url, and pat.
+ */
+
+// --- handleSave:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Saves a new git configuration.
+ * @post New config is saved to DB and added to configs list.
+ * @pre newConfig is valid and tested.
+ */
+
+// --- handleEdit:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Populates the form with an existing config to edit.
+ * @param {Object} config - Configuration object to edit.
+ * @post Form is populated and isEditing state is set.
+ */
+
+// --- resetForm:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Resets the configuration form.
+ */
+
+// --- loadGiteaRepos:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Loads repositories from selected Gitea config.
+ * @post giteaRepos state updated.
+ * @pre selectedGiteaConfigId is set.
+ */
+
+// --- handleCreateGiteaRepo:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Creates new repository on selected Gitea server.
+ * @post Repository created and repos list reloaded.
+ * @pre selectedGiteaConfigId and newGiteaRepo.name are set.
+ */
+
+// --- handleDeleteGiteaRepo:Function (frontend/src/routes/settings/git/+page.svelte)
+/**!
+ * @brief Deletes repository from selected Gitea server.
+ * @post Repository deleted and repos list reloaded.
+ * @pre selectedGiteaConfigId is set.
+ */
+
+// --- GitSettingsPageUxTest:Module (frontend/src/routes/settings/git/__tests__/git_settings_page.ux.test.js)
+/**!
+ * @brief Test UX states and transitions for the Git Settings page
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::readTabFromUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::writeTabToUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeTab (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeLlmSettings (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::isDashboardValidationBindingValid (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::getProviderById (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::normalizeSupersetBaseUrl (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- frontend/src/routes/settings/settings-utils.js::resolveEnvStage (frontend/src/routes/settings/settings-utils.js)
+/**!
+ */
+
+// --- StorageIndexPage (frontend/src/routes/storage/+page.svelte)
+/**!
+ * @brief Redirect to the backups page as the default storage view.
+ * @invariant Always redirects to /storage/backups.
+ */
+
+// --- BackupsRedirectPage (frontend/src/routes/storage/backups/+page.svelte)
+/**!
+ * @brief Temporary switch to legacy storage browser for backup UX validation.
+ * @invariant Always redirects to /tools/storage.
+ */
+
+// --- fetchEnvironments:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Fetches the list of available environments.
+ * @post environments array is populated, selectedEnvId is set to first env if available.
+ * @pre None.
+ */
+
+// --- fetchDashboards:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Fetches dashboards for a specific environment.
+ * @post dashboards array is populated with metadata for the selected environment.
+ * @pre envId is a valid environment ID.
+ */
+
+// --- filterDashboardsWithRepositories:Function (frontend/src/routes/storage/repos/+page.svelte)
+/**!
+ * @brief Keep only dashboards that already have initialized Git repositories.
+ * @post Returns dashboards with status != NO_REPO.
+ * @pre dashboards list is loaded for selected environment.
+ */
+
+// --- BackupsPage (frontend/src/routes/tools/backups/+page.svelte)
+/**!
+ * @brief Entry point for the Backup Management interface.
+ */
+
+// --- DebugToolPage (frontend/src/routes/tools/debug/+page.svelte)
+/**!
+ * @brief Page for system diagnostics and debugging.
+ */
+
+// --- MapperToolPage (frontend/src/routes/tools/mapper/+page.svelte)
+/**!
+ * @brief Page for the dataset column mapper tool.
+ */
+
+// --- loadFiles:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Fetches the list of files from the server.
+ * @post Updates the `files` array with the latest data.
+ * @pre currentPath is a valid storage path or empty for root.
+ */
+
+// --- resolveStorageQueryFromPath:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Splits UI path into storage API category and category-local subpath.
+ * @post Returns {category, subpath} compatible with /api/storage/files.
+ * @pre uiPath may be empty or start with backups/repositorys.
+ */
+
+// --- handleDelete:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Handles the file deletion process.
+ * @param {CustomEvent} event - The delete event containing category and path.
+ * @post File is deleted and file list is refreshed.
+ * @pre The event contains valid category and path.
+ */
+
+// --- handleNavigate:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Updates the current path and reloads files when navigating into a directory.
+ * @param {CustomEvent} event - The navigation event containing the new path.
+ * @post currentPath is updated and files are reloaded.
+ * @pre The event contains a valid path string.
+ */
+
+// --- navigateUp:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Navigates one level up in the directory structure.
+ * @post currentPath is moved up one directory level.
+ * @pre currentPath is not root.
+ */
+
+// --- updateUploadCategory:Function (frontend/src/routes/tools/storage/+page.svelte)
+/**!
+ * @brief Keeps upload category aligned with the currently viewed top-level folder.
+ * @post uploadCategory is either backups or repositorys.
+ * @pre currentPath can be empty or a slash-delimited path.
+ */
+
+// --- TranslateJobList (frontend/src/routes/translate/+page.svelte)
+/**!
+ */
+
+// --- TranslationJobConfig (frontend/src/routes/translate/[id]/+page.svelte)
+/**!
+ * @brief Translation job configuration page - orchestrates form state, datasource loading, LLM settings, run/schedule tabs.
+ * @deprecated N/A — active page.
+ */
+
+// --- DictionariesPage (frontend/src/routes/translate/dictionaries/+page.svelte)
+/**!
+ */
+
+// --- DictionaryDetailPage (frontend/src/routes/translate/dictionaries/[id]/+page.svelte)
+/**!
+ */
+
+// --- TranslateHistoryPage (frontend/src/routes/translate/history/+page.svelte)
+/**!
+ */
+
+// --- ValidationTaskList (frontend/src/routes/validation/+page.svelte)
+/**!
+ * @brief Validation task list page with status filter, task cards, and create/duplicate/delete actions.
+ * @param {string} status
+ */
+
+// --- ValidationTaskConfig (frontend/src/routes/validation/[id]/+page.svelte)
+/**!
+ * @brief Validation task configuration page with Config and History tabs. Handles new and edit modes.
+ */
+
+// --- ValidationHistory (frontend/src/routes/validation/history/+page.svelte)
+/**!
+ * @brief Validation run history page with filters, metrics summary, and run cards.
+ */
+
+// --- GitServiceContractTests (frontend/src/services/__tests__/gitService.test.js)
+/**!
+ * @brief API client tests ensuring correct endpoints are called per contract for Git service operations.
+ */
+
+// --- gitServiceContractTests:Module (frontend/src/services/__tests__/gitService.test.js)
+/**!
+ * @brief API client tests ensuring correct endpoints are called per contract
+ * @post Returns promotion metadata
+ * @pre Repo initialized
+ */
+
+// --- AdminService (frontend/src/services/adminService.js)
+/**!
+ * @brief Service for Admin-related API calls including User and Role management, AD group mappings, and logging configuration.
+ */
+
+// --- adminService:Module (frontend/src/services/adminService.js)
+/**!
+ * @brief Service for Admin-related API calls (User and Role management).
+ * @invariant All requests must include valid Admin JWT token (handled by api client).
+ */
+
+// --- getUsers:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all registered users from the backend.
+ * @post Returns an array of user objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getUsers (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of user objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates a new local user.
+ * @param {Object} userData - User details (username, email, password, roles, is_active).
+ * @post New user record created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createUser (frontend/src/services/adminService.js)
+/**!
+ * @post New user record created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- getRoles:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all available system roles.
+ * @post Returns an array of role objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getRoles (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of role objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- getADGroupMappings:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches mappings between AD groups and local roles.
+ * @post Returns an array of AD group mapping objects.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getADGroupMappings (frontend/src/services/adminService.js)
+/**!
+ * @post Returns an array of AD group mapping objects.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createADGroupMapping:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates or updates an AD group to Role mapping.
+ * @param {Object} mappingData - Mapping details (ad_group, role_id).
+ * @post New or updated mapping created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createADGroupMapping (frontend/src/services/adminService.js)
+/**!
+ * @post New or updated mapping created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- updateUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates an existing user.
+ * @param {Object} userData - Updated user data.
+ * @post User record updated in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateUser (frontend/src/services/adminService.js)
+/**!
+ * @post User record updated in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- deleteUser:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Deletes a user.
+ * @param {string} userId - Target user ID.
+ * @post User record removed from auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::deleteUser (frontend/src/services/adminService.js)
+/**!
+ * @post User record removed from auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- createRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Creates a new role.
+ * @param {Object} roleData - Role details (name, description, permissions).
+ * @post New role created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::createRole (frontend/src/services/adminService.js)
+/**!
+ * @post New role created in auth.db.
+ * @pre User must be authenticated with Admin privileges.
+ */
+
+// --- updateRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates an existing role.
+ * @param {Object} roleData - Updated role data.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateRole (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- deleteRole:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Deletes a role.
+ * @param {string} roleId - Target role ID.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::deleteRole (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- getPermissions:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches all available permissions.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::getPermissions (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- getLoggingConfig:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Fetches current logging configuration.
+ * @return {Promise} - Logging config with level, task_log_level, enable_belief_state.
+ */
+
+// --- frontend/src/services/adminService.js::getLoggingConfig (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- updateLoggingConfig:Function (frontend/src/services/adminService.js)
+/**!
+ * @brief Updates logging configuration.
+ * @param {Object} configData - Logging config (level, task_log_level, enable_belief_state).
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/adminService.js::updateLoggingConfig (frontend/src/services/adminService.js)
+/**!
+ */
+
+// --- GitUtils (frontend/src/services/git-utils.js)
+/**!
+ * @brief Shared utility functions extracted from GitManager.svelte.
+ */
+
+// --- frontend/src/services/git-utils.js::normalizeEnvStage (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::stageBadgeClass (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolveCurrentEnvironmentId (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::applyGitflowStageDefaults (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::isNumericDashboardRef (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::getSelectedConfig (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolveDefaultConfig (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::resolvePushProviderLabel (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::extractHttpHost (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::buildSuggestedRepoName (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::tryParseJsonObject (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- frontend/src/services/git-utils.js::extractUnfinishedMergeContext (frontend/src/services/git-utils.js)
+/**!
+ */
+
+// --- StorageService (frontend/src/services/storageService.js)
+/**!
+ * @brief Frontend API client for file storage management including list, upload, download, and delete operations.
+ */
+
+// --- storageService:Module (frontend/src/services/storageService.js)
+/**!
+ * @brief Frontend API client for file storage management.
+ */
+
+// --- getStorageAuthHeaders:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Returns headers with Authorization for storage API calls.
+ * @note Unlike api.js getAuthHeaders, this doesn't set Content-Type
+ * @return {Object} Headers object with Authorization if token exists.
+ */
+
+// --- frontend/src/services/storageService.js::getStorageAuthHeaders (frontend/src/services/storageService.js)
+/**!
+ */
+
+// --- encodeStoragePath:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Encodes a storage-relative path preserving slash separators.
+ * @param {string} path - Relative storage path.
+ * @return {string} Encoded path safe for URL segments.
+ */
+
+// --- frontend/src/services/storageService.js::encodeStoragePath (frontend/src/services/storageService.js)
+/**!
+ */
+
+// --- listFiles:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Fetches the list of files for a given category and subpath.
+ * @param {string} [path] - Optional subpath filter.
+ * @post Returns a promise resolving to an array of StoredFile objects.
+ * @pre category and path should be valid strings if provided.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::listFiles (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a promise resolving to an array of StoredFile objects.
+ * @pre category and path should be valid strings if provided.
+ */
+
+// --- uploadFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Uploads a file to the storage system.
+ * @param {string} [path] - Target subpath.
+ * @post Returns a promise resolving to the metadata of the uploaded file.
+ * @pre file must be a valid File object; category must be specified.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::uploadFile (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a promise resolving to the metadata of the uploaded file.
+ * @pre file must be a valid File object; category must be specified.
+ */
+
+// --- deleteFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Deletes a file or directory from storage.
+ * @param {string} path - Relative path of the item.
+ * @post The specified file or directory is removed from storage.
+ * @pre category and path must identify an existing file or directory.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::deleteFile (frontend/src/services/storageService.js)
+/**!
+ * @post The specified file or directory is removed from storage.
+ * @pre category and path must identify an existing file or directory.
+ */
+
+// --- downloadFileUrl:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Returns the URL for downloading a file.
+ * @note Downloads use browser navigation, so auth is handled via cookies
+ * @param {string} path - Relative path of the file.
+ * @post Returns a valid API URL for file download.
+ * @pre category and path must identify an existing file.
+ * @return {string}
+ */
+
+// --- frontend/src/services/storageService.js::downloadFileUrl (frontend/src/services/storageService.js)
+/**!
+ * @post Returns a valid API URL for file download.
+ * @pre category and path must identify an existing file.
+ */
+
+// --- downloadFile:Function (frontend/src/services/storageService.js)
+/**!
+ * @brief Downloads a file using authenticated fetch and saves it in browser.
+ * @param {string} [filename] - Optional preferred filename.
+ * @post Browser download is triggered or an Error is thrown.
+ * @pre category/path identify an existing file and user has READ permission.
+ * @return {Promise}
+ */
+
+// --- frontend/src/services/storageService.js::downloadFile (frontend/src/services/storageService.js)
+/**!
+ * @post Browser download is triggered or an Error is thrown.
+ * @pre category/path identify an existing file and user has READ permission.
+ */
+
+// --- TaskService (frontend/src/services/taskService.js)
+/**!
+ * @brief Service for Task Management API interactions: listing, fetching details, resuming, resolving, and clearing tasks.
+ */
+
+// --- getTasks:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch a list of tasks with pagination and optional status filter.
+ * @post Returns a promise resolving to a list of tasks.
+ * @pre limit and offset are numbers.
+ */
+
+// --- frontend/src/services/taskService.js::getTasks (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- getTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch details for a specific task.
+ * @post Returns a promise resolving to task details.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::getTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- getTaskLogs:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Fetch logs for a specific task.
+ * @post Returns a promise resolving to a list of log entries.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::getTaskLogs (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- resumeTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Resume a task that is awaiting input (e.g., passwords).
+ * @post Returns a promise resolving to the updated task object.
+ * @pre taskId and passwords must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::resumeTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- resolveTask:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Resolve a task that is awaiting mapping.
+ * @post Returns a promise resolving to the updated task object.
+ * @pre taskId and resolutionParams must be provided.
+ */
+
+// --- frontend/src/services/taskService.js::resolveTask (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- clearTasks:Function (frontend/src/services/taskService.js)
+/**!
+ * @brief Clear tasks based on status.
+ * @post Returns a promise that resolves when tasks are cleared.
+ * @pre status is a string or null.
+ */
+
+// --- frontend/src/services/taskService.js::clearTasks (frontend/src/services/taskService.js)
+/**!
+ */
+
+// --- ToolsService (frontend/src/services/toolsService.js)
+/**!
+ * @brief Service for generic Task API communication used by Tools — run tasks and poll status.
+ */
+
+// --- runTask:Function (frontend/src/services/toolsService.js)
+/**!
+ * @brief Start a new task for a given plugin.
+ * @post Returns a promise resolving to the task instance.
+ * @pre pluginId and params must be provided.
+ */
+
+// --- frontend/src/services/toolsService.js::runTask (frontend/src/services/toolsService.js)
+/**!
+ */
+
+// --- getTaskStatus:Function (frontend/src/services/toolsService.js)
+/**!
+ * @brief Fetch details for a specific task (to poll status or get result).
+ * @post Returns a promise resolving to task details.
+ * @pre taskId must be provided.
+ */
+
+// --- frontend/src/services/toolsService.js::getTaskStatus (frontend/src/services/toolsService.js)
+/**!
+ */
+
+// --- BackupTypes (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- frontend/src/types/backup.ts::Backup (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- BackupTypes:Module (frontend/src/types/backup.ts)
+/**!
+ */
+
+// --- DashboardTypes (frontend/src/types/dashboard.ts)
+/**!
+ */
+
+// --- DashboardTypes:Module (frontend/src/types/dashboard.ts)
+/**!
+ * @brief TypeScript interfaces for Dashboard entities
+ */
+
+// --- frontend/src/types/dashboard.ts::DashboardMetadata (frontend/src/types/dashboard.ts)
+/**!
+ */
+
+// --- MaintenanceStoreTests (frontend/tests/maintenance-store.test.ts)
+/**!
+ * @brief Unit tests for MaintenanceStore runes-based store.
+ */
+
+// --- MaintenanceComponentTests (frontend/tests/maintenance.test.ts)
+/**!
+ * @brief Component tests for MaintenanceEventsTable and DashboardMaintenanceBadge.
+ */
+
+// --- MergeSpec (merge_spec.py)
+/**!
+ */
+
+// --- merge_spec (merge_spec.py)
+/**!
+ */
+
+// --- BuildOfflineDockerBundle (scripts/build_offline_docker_bundle.sh)
+/**!
+ * @brief Thin wrapper — delegates to ./build.sh bundle (.tar.xz output)
+ */
+
+// --- venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp::ThreadState (venv/lib/python3.13/site-packages/greenlet/TThreadState.hpp)
+/**!
+ */
+
+// --- venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp::PyFatalError (venv/lib/python3.13/site-packages/greenlet/greenlet_exceptions.hpp)
+/**!
+ */
+
diff --git a/feature-request-ext-handling.md b/feature-request-ext-handling.md
new file mode 100644
index 00000000..a65155a4
--- /dev/null
+++ b/feature-request-ext-handling.md
@@ -0,0 +1,89 @@
+# Feature Request: Handle `[EXT:*]` targets in Axiom validator
+
+## Проблема
+
+Сейчас Axiom-валидатор проверяет `@RELATION PREDICATE -> [Target]` на существование контракта с ID `Target`. Для кастомных контрактов это верно. Но для `[EXT:*]` (external references) это generates false `unresolved_relation`.
+
+**Пример бага:**
+```python
+# @RELATION DEPENDS_ON -> [EXT:Python:json]
+# @RELATION DEPENDS_ON -> [EXT:Library:pydantic]
+# @RELATION DEPENDS_ON -> [EXT:frontend:authStore]
+```
+
+Валидатор: «ищу контракт `EXT:Python:json` — не нашёл → unresolved_relation».
+
+## Временный костыль
+
+Агент создал `backend/src/schemas/_external_stubs.py` — **~250 пустышек-контрактов**:
+```python
+# #region EXT:Library:pydantic [C:1] [TYPE External]
+# @BRIEF External library stub — no code
+# #endregion EXT:Library:pydantic
+```
+
+**Проблемы костыля:**
+1. 250 мусорных контрактов в индексе (шум в графе, раздувает DuckDB)
+2. Нужно поддерживать вручную — каждый новый EXT требует новой пустышки
+3. Ломает семантику: `EXT:` означает «external, контракт не нужен»
+
+## Правильный фикс (Rust-код)
+
+В валидаторе `unresolved_relation` нужно добавить проверку: **если target начинается с `EXT:` — пропустить unresolved check**.
+
+### Suggestion
+
+```rust
+// Сейчас:
+fn check_resolved(target_id: &str, contracts: &ContractIndex) -> bool {
+ contracts.contains(target_id) // требует контракт для любого ID
+}
+
+// Должно быть:
+fn check_resolved(target_id: &str, contracts: &ContractIndex) -> bool {
+ if target_id.starts_with("EXT:") {
+ return true; // external reference — контракт не нужен
+ }
+ contracts.contains(target_id)
+}
+```
+
+### Ожидаемый эффект
+
+- `@RELATION CALLS -> [EXT:Python:json]` → not checked → **0 warnings**
+- `@RELATION DEPENDS_ON -> [EXT:Library:pydantic]` → not checked → **0 warnings**
+- `@RELATION BINDS_TO -> [EXT:frontend:authStore]` → not checked → **0 warnings**
+- Можно полностью удалить `_external_stubs.py` → -250 шумовых контрактов
+
+### Альтернатива: registry approach
+
+Если нужна валидация формата EXT, можно сделать registry разрешённых неймспейсов:
+
+```yaml
+# axiom_config.yaml
+external_namespaces:
+ - EXT:Python # Python stdlib
+ - EXT:Library # External PyPI/npm libraries
+ - EXT:frontend # Frontend stores/components
+ - EXT:path # File system paths
+ - EXT:code # Code expressions
+ - EXT:method # Method references
+ - EXT:docker # Docker/shell scripts
+ - EXT:internal # Internal module references
+```
+
+Тогда валидатор проверяет не наличие контракта, а формат: `^EXT:\w+:\S+$`.
+
+## Что делать с существующим stubs-файлом
+
+После фикса в Rust:
+```bash
+# 1. Удалить файл пустышек
+rm backend/src/schemas/_external_stubs.py
+
+# 2. Перестроить индекс
+axiom_semantic_index rebuild rebuild_mode="full" use_duckdb=true
+
+# 3. Аудит должен показать 0
+axiom_semantic_validation audit_contracts
+```
diff --git a/frontend/e2e/tests/enterprise-clean-setup.e2e.js b/frontend/e2e/tests/enterprise-clean-setup.e2e.js
index c12c45b7..2d747caf 100644
--- a/frontend/e2e/tests/enterprise-clean-setup.e2e.js
+++ b/frontend/e2e/tests/enterprise-clean-setup.e2e.js
@@ -4,7 +4,7 @@
// @@REJECTED Using waitForSelector('text=...') fails for locale-sensitive text. getByLabel() with connections.* keys fails when i18n namespace missing. Using page.goto() with authPage fixture causes page reload issues
// Validates: bundle deployment, PostgreSQL fresh DB, initial admin bootstrap, environment creation wizard.
-// @RELATION BINDS_TO -> [[EXT:list:StartupEnvironmentWizard_LoginPage_EnvironmentsTab]]
+// @RELATION BINDS_TO -> [StartupEnvironmentWizard]
// @RELATION DEPENDS_ON -> [ApiHelper]
// @UX_STATE WizardIntro -> Wizard explains setup purpose with "Start setup" button.
// @UX_STATE WizardForm -> Form collects environment ID, name, URL, username, password, stage.
diff --git a/frontend/e2e/tests/git.e2e.js b/frontend/e2e/tests/git.e2e.js
index 74ebd07d..adfe6cbd 100644
--- a/frontend/e2e/tests/git.e2e.js
+++ b/frontend/e2e/tests/git.e2e.js
@@ -1,6 +1,6 @@
// #region GitE2E [C:3] [TYPE Test] [SEMANTICS e2e, git, integration, config]
// @BRIEF E2E tests for Git integration — config CRUD, connection test.
-// @RELATION BINDS_TO -> [[EXT:list:GitDashboardPage_GitConfigRoutes]]
+// @RELATION BINDS_TO -> [GitSettingsPage]
// @UX_STATE ConfigCreated -> Git server appears in configured list.
// @UX_STATE ConnectionTested -> Success/failure toast feedback.
diff --git a/frontend/e2e/tests/live-project-check.e2e.js b/frontend/e2e/tests/live-project-check.e2e.js
index 7685db5b..0dc2a4dc 100644
--- a/frontend/e2e/tests/live-project-check.e2e.js
+++ b/frontend/e2e/tests/live-project-check.e2e.js
@@ -1,7 +1,7 @@
// #region LiveProjectCheckE2E [C:4] [TYPE Test] [SEMANTICS e2e, live-project, verification, dashboard, llm, settings]
// @BRIEF Stage 2: E2E test for live project verification — validates dashboard LLM analysis,
// settings modification, and overall project health after ./run.sh startup.
-// @RELATION BINDS_TO -> [[EXT:list:DashboardHub_LLM_SettingsPage]]
+// @RELATION BINDS_TO -> [DashboardHub]
// @RELATION DEPENDS_ON -> [ApiHelper]
// @UX_STATE DashboardsLoaded -> Dashboard hub with environment context, dashboard cards visible.
// @UX_STATE LLMAnalysis -> LLM analysis triggered and report generated for a dashboard.
diff --git a/frontend/e2e/tests/migration.e2e.js b/frontend/e2e/tests/migration.e2e.js
index 115f2b0d..bccfd48f 100644
--- a/frontend/e2e/tests/migration.e2e.js
+++ b/frontend/e2e/tests/migration.e2e.js
@@ -1,6 +1,6 @@
// #region MigrationE2E [C:3] [TYPE Test] [SEMANTICS e2e, migration, sync, datasets]
// @BRIEF E2E tests for dataset/environment migration and sync.
-// @RELATION BINDS_TO -> [[EXT:list:MigrationApi_SettingsPage]]
+// @RELATION BINDS_TO -> [MigrationApi]
// @UX_STATE SyncTriggered -> Sync-now request accepted.
// @UX_STATE MappingsLoaded -> Synchronized resources table populated.
diff --git a/frontend/e2e/tests/smoke.e2e.js b/frontend/e2e/tests/smoke.e2e.js
index 8ef1bbb4..9c961c5d 100644
--- a/frontend/e2e/tests/smoke.e2e.js
+++ b/frontend/e2e/tests/smoke.e2e.js
@@ -1,6 +1,6 @@
// #region SmokeE2E [C:4] [TYPE Test] [SEMANTICS e2e, smoke, golden-path, full-stack]
// @BRIEF Golden-path smoke test: login → settings → translate → git → verify.
-// @RELATION BINDS_TO -> [[EXT:list:LoginPage_SettingsPage_TranslateJob_GitConfig]]
+// @RELATION BINDS_TO -> [E2E.Smoke]
// @UX_STATE FullCycle -> All key user journeys executed sequentially.
// @RATIONALE Single sequential test verifies the entire stack without per-test setup overhead.
// Runs in ~30s when backend is warm. Mirrors the manual E2E check.
diff --git a/frontend/e2e/tests/translation.e2e.js b/frontend/e2e/tests/translation.e2e.js
index 9f05c1f4..703be3c1 100644
--- a/frontend/e2e/tests/translation.e2e.js
+++ b/frontend/e2e/tests/translation.e2e.js
@@ -1,6 +1,6 @@
// #region TranslationE2E [C:3] [TYPE Test] [SEMANTICS e2e, translate, job, preview, run]
// @BRIEF E2E tests for the translation job lifecycle: create → preview → accept → run.
-// @RELATION BINDS_TO -> [[EXT:list:TranslatePage_TranslateJobRoutes]]
+// @RELATION BINDS_TO -> [TranslatePage]
// @UX_STATE JobCreated -> Job appears in list with DRAFT status.
// @UX_STATE PreviewCreated -> Preview session with sample rows visible.
// @UX_STATE JobRunning -> Run object created with PENDING status.
diff --git a/frontend/playwright.config.js b/frontend/playwright.config.js
index b48a69fc..fcce5e3e 100644
--- a/frontend/playwright.config.js
+++ b/frontend/playwright.config.js
@@ -1,6 +1,6 @@
// #region PlaywrightConfig [C:3] [TYPE Config] [SEMANTICS e2e, playwright, test, config]
// @BRIEF Playwright E2E test configuration for ss-tools frontend.
-// @RELATION DEPENDS_ON -> [[EXT:frontend:EnvConfig]]
+// @RELATION DEPENDS_ON -> [EXT:frontend:EnvConfig]]
// @INVARIANT All E2E tests run against a fully deployed stack (DB + backend + frontend).
// @UX_STATE ConfigLoaded -> Browser contexts are created with predefined env settings.
diff --git a/frontend/src/components/PasswordPrompt.svelte b/frontend/src/components/PasswordPrompt.svelte
index d61b82b0..7b079ce8 100644
--- a/frontend/src/components/PasswordPrompt.svelte
+++ b/frontend/src/components/PasswordPrompt.svelte
@@ -5,7 +5,7 @@
@SEMANTICS: password, prompt, modal, input, security
@PURPOSE: A modal component to prompt the user for database passwords when a migration task is paused.
@LAYER UI
-@RELATION USES -> [EXT:path:frontend/src/lib/api.js (inferred)]
+@RELATION USES -> [ApiModule]
@RELATION BINDS_TO -> [EXT:frontend:onresume]
@RELATION BINDS_TO -> [EXT:frontend:oncancel]
-->
diff --git a/frontend/src/components/TaskHistory.svelte b/frontend/src/components/TaskHistory.svelte
index cbd04975..c08f5ea4 100644
--- a/frontend/src/components/TaskHistory.svelte
+++ b/frontend/src/components/TaskHistory.svelte
@@ -6,7 +6,7 @@
@PURPOSE: Displays a list of recent tasks with their status and allows selecting them for viewing logs.
@LAYER UI
@RELATION USES -> [EXT:frontend:stores]
-@RELATION USES -> [EXT:path:frontend/src/lib/api.js (inferred)]
+@RELATION USES -> [ApiModule]
-->