semantics: complete DEF-to-region migration, fix regressions

- Convert legacy [DEF🆔Type] anchors to #region/#endregion across 329 files
- Reinstate _normalize_timestamp_value in sql_generator.py
- Fix MarkerLogger→logger migration in events.py (molecular CoT markers)
- Fix dataset_review orchestrator dependencies (_build_execution_snapshot)
- Fix config_manager stale-record deletion (moved to save path only)
- Add 77 missing [/DEF:] closers in 5 unbalanced test files
- Update assistant_chat.integration.test.js for #region format
- Apply molecular-cot-logging markers (REASON/REFLECT/EXPLORE) via logger.* methods
This commit is contained in:
2026-05-12 23:54:55 +03:00
parent fe8978f716
commit 306c5ae742
331 changed files with 9630 additions and 10312 deletions

View File

@@ -1,7 +1,7 @@
# #region CleanReleaseCliScript [C:3] [TYPE Module] [SEMANTICS cli, clean-release, candidate, artifacts, manifest]
# @BRIEF Provide headless CLI commands for candidate registration, artifact import and manifest build.
# @LAYER Scripts
# @RELATION CALLS -> [ComplianceOrchestrator]
# @LAYER: Scripts
# @RELATION CALLS -> ComplianceOrchestrator
from __future__ import annotations
@@ -102,8 +102,8 @@ def build_parser() -> argparse.ArgumentParser:
# #region run_candidate_register [TYPE Function]
# @BRIEF Register candidate in repository via CLI command.
# @PRE Candidate ID must be unique.
# @POST Candidate is persisted in DRAFT status.
# @PRE: Candidate ID must be unique.
# @POST: Candidate is persisted in DRAFT status.
def run_candidate_register(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -131,8 +131,8 @@ def run_candidate_register(args: argparse.Namespace) -> int:
# #region run_artifact_import [TYPE Function]
# @BRIEF Import single artifact for existing candidate.
# @PRE Candidate must exist.
# @POST Artifact is persisted for candidate.
# @PRE: Candidate must exist.
# @POST: Artifact is persisted for candidate.
def run_artifact_import(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -164,8 +164,8 @@ def run_artifact_import(args: argparse.Namespace) -> int:
# #region run_manifest_build [TYPE Function]
# @BRIEF Build immutable manifest snapshot for candidate.
# @PRE Candidate must exist.
# @POST New manifest version is persisted.
# @PRE: Candidate must exist.
# @POST: New manifest version is persisted.
def run_manifest_build(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
from ..services.clean_release.manifest_service import build_manifest_snapshot
@@ -198,8 +198,8 @@ def run_manifest_build(args: argparse.Namespace) -> int:
# #region run_compliance_run [TYPE Function]
# @BRIEF Execute compliance run for candidate with optional manifest fallback.
# @PRE Candidate exists and trusted snapshots are configured.
# @POST Returns run payload and exit code 0 on success.
# @PRE: Candidate exists and trusted snapshots are configured.
# @POST: Returns run payload and exit code 0 on success.
def run_compliance_run(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository, get_config_manager
@@ -237,8 +237,8 @@ def run_compliance_run(args: argparse.Namespace) -> int:
# #region run_compliance_status [TYPE Function]
# @BRIEF Read run status by run id.
# @PRE Run exists.
# @POST Returns run status payload.
# @PRE: Run exists.
# @POST: Returns run status payload.
def run_compliance_status(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -269,8 +269,8 @@ def run_compliance_status(args: argparse.Namespace) -> int:
# #region _to_payload [TYPE Function]
# @BRIEF Serialize domain models for CLI JSON output across SQLAlchemy/Pydantic variants.
# @PRE value is serializable model or primitive object.
# @POST Returns dictionary payload without mutating value.
# @PRE: value is serializable model or primitive object.
# @POST: Returns dictionary payload without mutating value.
def _to_payload(value: Any) -> Dict[str, Any]:
def _normalize(raw: Any) -> Any:
if isinstance(raw, datetime):
@@ -299,8 +299,8 @@ def _to_payload(value: Any) -> Dict[str, Any]:
# #region run_compliance_report [TYPE Function]
# @BRIEF Read immutable report by run id.
# @PRE Run and report exist.
# @POST Returns report payload.
# @PRE: Run and report exist.
# @POST: Returns report payload.
def run_compliance_report(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -326,8 +326,8 @@ def run_compliance_report(args: argparse.Namespace) -> int:
# #region run_compliance_violations [TYPE Function]
# @BRIEF Read run violations by run id.
# @PRE Run exists.
# @POST Returns violations payload.
# @PRE: Run exists.
# @POST: Returns violations payload.
def run_compliance_violations(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -351,8 +351,8 @@ def run_compliance_violations(args: argparse.Namespace) -> int:
# #region run_approve [TYPE Function]
# @BRIEF Approve candidate based on immutable PASSED report.
# @PRE Candidate and report exist; report is PASSED.
# @POST Persists APPROVED decision and returns success payload.
# @PRE: Candidate and report exist; report is PASSED.
# @POST: Persists APPROVED decision and returns success payload.
def run_approve(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -382,8 +382,8 @@ def run_approve(args: argparse.Namespace) -> int:
# #region run_reject [TYPE Function]
# @BRIEF Reject candidate without mutating compliance evidence.
# @PRE Candidate and report exist.
# @POST Persists REJECTED decision and returns success payload.
# @PRE: Candidate and report exist.
# @POST: Persists REJECTED decision and returns success payload.
def run_reject(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -413,8 +413,8 @@ def run_reject(args: argparse.Namespace) -> int:
# #region run_publish [TYPE Function]
# @BRIEF Publish approved candidate to target channel.
# @PRE Candidate is approved and report belongs to candidate.
# @POST Appends ACTIVE publication record and returns payload.
# @PRE: Candidate is approved and report belongs to candidate.
# @POST: Appends ACTIVE publication record and returns payload.
def run_publish(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository
@@ -441,8 +441,8 @@ def run_publish(args: argparse.Namespace) -> int:
# #region run_revoke [TYPE Function]
# @BRIEF Revoke active publication record.
# @PRE Publication id exists and is ACTIVE.
# @POST Publication record status becomes REVOKED.
# @PRE: Publication id exists and is ACTIVE.
# @POST: Publication record status becomes REVOKED.
def run_revoke(args: argparse.Namespace) -> int:
from ..dependencies import get_clean_release_repository

View File

@@ -1,9 +1,9 @@
# #region CleanReleaseTuiScript [C:3] [TYPE Module] [SEMANTICS clean-release, tui, ncurses, interactive-validator]
# @BRIEF Interactive terminal interface for Enterprise Clean Release compliance validation.
# @LAYER UI
# @INVARIANT TUI refuses startup in non-TTY environments; headless flow is CLI/API only.
# @LAYER: UI
# @RELATION DEPENDS_ON -> [ComplianceExecutionService]
# @RELATION DEPENDS_ON -> [CleanReleaseRepository]
# @INVARIANT: TUI refuses startup in non-TTY environments; headless flow is CLI/API only.
import curses
import json
@@ -46,8 +46,8 @@ from src.services.clean_release.repository import CleanReleaseRepository
# #region TuiFacadeAdapter [TYPE Class]
# @BRIEF Thin TUI adapter that routes business mutations through application services.
# @PRE repository contains candidate and trusted policy/registry snapshots for execution.
# @POST Business actions return service results/errors without direct TUI-owned mutations.
# @PRE: repository contains candidate and trusted policy/registry snapshots for execution.
# @POST: Business actions return service results/errors without direct TUI-owned mutations.
class TuiFacadeAdapter:
def __init__(self, repository: CleanReleaseRepository):
self.repository = repository
@@ -506,10 +506,10 @@ class CleanReleaseTUI:
self.stdscr.addstr(max_y - 1, 0, footer_text[:max_x])
self.stdscr.attroff(curses.color_pair(1))
# #region run_checks [TYPE Function]
# @BRIEF Execute compliance run via facade adapter and update UI state.
# @PRE Candidate and policy snapshots are present in repository.
# @POST UI reflects final run/report/violation state from service result.
# [DEF:run_checks:Function]
# @PURPOSE: Execute compliance run via facade adapter and update UI state.
# @PRE: Candidate and policy snapshots are present in repository.
# @POST: UI reflects final run/report/violation state from service result.
def run_checks(self):
self.status = "RUNNING"
self.report_id = None
@@ -550,7 +550,7 @@ class CleanReleaseTUI:
self.refresh_overview()
self.refresh_screen()
# #endregion run_checks
# [/DEF:run_checks:Function]
def build_manifest(self):
try:

View File

@@ -1,14 +1,13 @@
# #region CreateAdminScript [C:3] [TYPE Module] [SEMANTICS admin, setup, user, auth, cli]
#
# @BRIEF CLI tool for creating the initial admin user.
# @LAYER Scripts
# @INVARIANT Admin user must have the "Admin" role.
# @LAYER: Scripts
# @RELATION USES -> [AuthSecurityModule]
# @RELATION USES -> [DatabaseModule]
# @RELATION USES -> [AuthModels]
#
#
# @INVARIANT: Admin user must have the "Admin" role.
# [SECTION: IMPORTS]
import sys
import argparse
from pathlib import Path
@@ -20,17 +19,13 @@ from src.core.database import AuthSessionLocal, init_db
from src.core.auth.security import get_password_hash
from src.models.auth import User, Role
from src.core.logger import logger, belief_scope
# [/SECTION]
# #region create_admin [TYPE Function]
# @BRIEF Creates an admin user and necessary roles/permissions.
# @PRE username and password provided via CLI.
# @POST Admin user exists in auth.db.
# @PRE: username and password provided via CLI.
# @POST: Admin user exists in auth.db.
#
# @PARAM: username (str) - Admin username.
# @PARAM: password (str) - Admin password.
# @PARAM: email (str | None) - Optional admin email.
def create_admin(username, password, email=None):
with belief_scope("create_admin"):
db = AuthSessionLocal()

View File

@@ -1,14 +1,13 @@
# #region InitAuthDbScript [C:2] [TYPE Module] [SEMANTICS setup, database, auth, migration]
#
# @BRIEF Initializes the auth database and creates the necessary tables.
# @LAYER Scripts
# @INVARIANT Safe to run multiple times (idempotent).
# @RELATION CALLS -> [init_db]
# @RELATION CALLS -> [ensure_encryption_key]
# @RELATION CALLS -> [seed_permissions]
#
# @LAYER: Scripts
# @RELATION CALLS -> init_db
# @RELATION CALLS -> ensure_encryption_key
# @RELATION CALLS -> seed_permissions
#
# @INVARIANT: Safe to run multiple times (idempotent).
# [SECTION: IMPORTS]
import sys
from pathlib import Path
@@ -19,15 +18,14 @@ from src.core.database import init_db
from src.core.encryption_key import ensure_encryption_key
from src.core.logger import logger, belief_scope
from src.scripts.seed_permissions import seed_permissions
# [/SECTION]
# #region run_init [C:3] [TYPE Function]
# @BRIEF Main entry point for the initialization script.
# @POST auth.db is initialized with the correct schema and seeded permissions.
# @RELATION CALLS -> [ensure_encryption_key]
# @RELATION CALLS -> [init_db]
# @RELATION CALLS -> [seed_permissions]
# @POST: auth.db is initialized with the correct schema and seeded permissions.
# @RELATION CALLS -> ensure_encryption_key
# @RELATION CALLS -> init_db
# @RELATION CALLS -> seed_permissions
def run_init():
with belief_scope("init_auth_db"):
logger.info("Initializing authentication database...")

View File

@@ -1,16 +1,15 @@
# #region MigrateSqliteToPostgresScript [C:3] [TYPE Module] [SEMANTICS migration, sqlite, postgresql, config, task_logs, task_records]
#
# @BRIEF Migrates legacy config and task history from SQLite/file storage to PostgreSQL.
# @LAYER Scripts
# @INVARIANT Script is idempotent for task_records and app_configurations.
# @RELATION READS_FROM -> [backend/tasks.db]
# @RELATION READS_FROM -> [backend/config.json]
# @RELATION WRITES_TO -> [postgresql.task_records]
# @RELATION WRITES_TO -> [postgresql.task_logs]
# @RELATION WRITES_TO -> [postgresql.app_configurations]
#
# @LAYER: Scripts
# @RELATION READS_FROM -> backend/tasks.db
# @RELATION READS_FROM -> backend/config.json
# @RELATION WRITES_TO -> postgresql.task_records
# @RELATION WRITES_TO -> postgresql.task_logs
# @RELATION WRITES_TO -> postgresql.app_configurations
#
# @INVARIANT: Script is idempotent for task_records and app_configurations.
# [SECTION: IMPORTS]
import argparse
import json
import os
@@ -21,11 +20,7 @@ from typing import Any, Dict, Iterable, Optional
from sqlalchemy import create_engine, text
from sqlalchemy.exc import SQLAlchemyError
from src.core.logger import belief_scope
from src.core.cot_logger import MarkerLogger
log = MarkerLogger("MigrateSqliteToPostgres")
# [/SECTION]
from src.core.logger import belief_scope, logger
# #region Constants [TYPE Section]
@@ -41,8 +36,8 @@ DEFAULT_TARGET_URL = os.getenv(
# #region _json_load_if_needed [C:3] [TYPE Function]
# @BRIEF Parses JSON-like values from SQLite TEXT/JSON columns to Python objects.
# @PRE value is scalar JSON/text/list/dict or None.
# @POST Returns normalized Python object or original scalar value.
# @PRE: value is scalar JSON/text/list/dict or None.
# @POST: Returns normalized Python object or original scalar value.
def _json_load_if_needed(value: Any) -> Any:
with belief_scope("_json_load_if_needed"):
if value is None:
@@ -169,7 +164,9 @@ def _ensure_target_schema(engine) -> None:
def _migrate_config(engine, legacy_config_path: Optional[Path]) -> int:
with belief_scope("_migrate_config"):
if legacy_config_path is None:
log.reason("No legacy config.json found, skipping migration")
logger.info(
"[_migrate_config][Action] No legacy config.json found, skipping"
)
return 0
payload = json.loads(legacy_config_path.read_text(encoding="utf-8"))
@@ -330,7 +327,9 @@ def run_migration(
sqlite_path: Path, target_url: str, legacy_config_path: Optional[Path]
) -> Dict[str, int]:
with belief_scope("run_migration"):
log.reason("Starting migration from SQLite to PostgreSQL", payload={"sqlite_path": str(sqlite_path), "target_url": target_url})
logger.info(
"[run_migration][Entry] sqlite=%s target=%s", sqlite_path, target_url
)
if not sqlite_path.exists():
raise FileNotFoundError(f"SQLite source not found: {sqlite_path}")

View File

@@ -1,15 +1,14 @@
# #region SeedPermissionsScript [C:3] [TYPE Module] [SEMANTICS setup, database, auth, permissions, seeding]
#
# @BRIEF Populates the auth database with initial system permissions.
# @LAYER Scripts
# @INVARIANT Safe to run multiple times (idempotent).
# @RELATION DEPENDS_ON -> [AuthSessionLocal]
# @RELATION DEPENDS_ON -> [Permission]
# @RELATION DEPENDS_ON -> [Role]
# @RELATION DEPENDS_ON -> [AuthRepository]
#
# @LAYER: Scripts
# @RELATION DEPENDS_ON -> AuthSessionLocal
# @RELATION DEPENDS_ON -> Permission
# @RELATION DEPENDS_ON -> Role
# @RELATION DEPENDS_ON -> AuthRepository
#
# @INVARIANT: Safe to run multiple times (idempotent).
# [SECTION: IMPORTS]
import sys
from pathlib import Path
@@ -20,11 +19,10 @@ from src.core.database import AuthSessionLocal
from src.models.auth import Permission, Role
from src.core.auth.repository import AuthRepository
from src.core.logger import logger, belief_scope
# [/SECTION]
# #region INITIAL_PERMISSIONS [C:3] [TYPE Constant]
# @BRIEF Canonical bootstrap permission tuples seeded into auth storage.
# @RELATION DEPENDS_ON -> [SeedPermissionsScript]
# @RELATION DEPENDS_ON -> SeedPermissionsScript
INITIAL_PERMISSIONS = [
# Admin Permissions
{"resource": "admin:users", "action": "READ"},
@@ -61,12 +59,12 @@ INITIAL_PERMISSIONS = [
# #region seed_permissions [C:3] [TYPE Function]
# @BRIEF Inserts missing permissions into the database.
# @POST All INITIAL_PERMISSIONS exist in the DB.
# @RELATION DEPENDS_ON -> [AuthSessionLocal]
# @RELATION DEPENDS_ON -> [Permission]
# @RELATION DEPENDS_ON -> [Role]
# @RELATION DEPENDS_ON -> [AuthRepository]
# @RELATION DEPENDS_ON -> [INITIAL_PERMISSIONS]
# @POST: All INITIAL_PERMISSIONS exist in the DB.
# @RELATION DEPENDS_ON -> AuthSessionLocal
# @RELATION DEPENDS_ON -> Permission
# @RELATION DEPENDS_ON -> Role
# @RELATION DEPENDS_ON -> AuthRepository
# @RELATION DEPENDS_ON -> INITIAL_PERMISSIONS
def seed_permissions():
with belief_scope("seed_permissions"):
db = AuthSessionLocal()

View File

@@ -1,12 +1,11 @@
# #region SeedSupersetLoadTestScript [C:3] [TYPE Module] [SEMANTICS superset, load-test, charts, dashboards, seed, stress]
#
# @BRIEF Creates randomized load-test data in Superset by cloning chart configurations and creating dashboards in target environments.
# @LAYER Scripts
# @INVARIANT Created chart and dashboard names are globally unique for one script run.
# @LAYER: Scripts
# @RELATION USES -> [ConfigManager]
# @RELATION USES -> [SupersetClient]
#
# @INVARIANT: Created chart and dashboard names are globally unique for one script run.
# [SECTION: IMPORTS]
import argparse
import json
import random
@@ -19,18 +18,14 @@ sys.path.append(str(Path(__file__).parent.parent.parent))
from src.core.config_manager import ConfigManager
from src.core.config_models import Environment
from src.core.logger import belief_scope
from src.core.cot_logger import MarkerLogger
from src.core.logger import belief_scope, logger
from src.core.superset_client import SupersetClient
log = MarkerLogger("SeedSupersetLoadTest")
# [/SECTION]
# #region _parse_args [TYPE Function]
# @BRIEF Parses CLI arguments for load-test data generation.
# @PRE Script is called from CLI.
# @POST Returns validated argument namespace.
# @PRE: Script is called from CLI.
# @POST: Returns validated argument namespace.
def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Seed Superset with load-test charts and dashboards"
@@ -73,8 +68,8 @@ def _parse_args() -> argparse.Namespace:
# #region _extract_result_payload [TYPE Function]
# @BRIEF Normalizes Superset API payloads that may be wrapped in `result`.
# @PRE payload is a JSON-decoded API response.
# @POST Returns the unwrapped object when present.
# @PRE: payload is a JSON-decoded API response.
# @POST: Returns the unwrapped object when present.
def _extract_result_payload(payload: Dict) -> Dict:
result = payload.get("result")
if isinstance(result, dict):
@@ -87,8 +82,8 @@ def _extract_result_payload(payload: Dict) -> Dict:
# #region _extract_created_id [TYPE Function]
# @BRIEF Extracts object ID from create/update API response.
# @PRE payload is a JSON-decoded API response.
# @POST Returns integer object ID or None if missing.
# @PRE: payload is a JSON-decoded API response.
# @POST: Returns integer object ID or None if missing.
def _extract_created_id(payload: Dict) -> Optional[int]:
direct_id = payload.get("id")
if isinstance(direct_id, int):
@@ -104,8 +99,8 @@ def _extract_created_id(payload: Dict) -> Optional[int]:
# #region _generate_unique_name [TYPE Function]
# @BRIEF Generates globally unique random names for charts/dashboards.
# @PRE used_names is mutable set for collision tracking.
# @POST Returns a unique string and stores it in used_names.
# @PRE: used_names is mutable set for collision tracking.
# @POST: Returns a unique string and stores it in used_names.
def _generate_unique_name(prefix: str, used_names: set[str], rng: random.Random) -> str:
adjectives = [
"amber",
@@ -144,8 +139,8 @@ def _generate_unique_name(prefix: str, used_names: set[str], rng: random.Random)
# #region _resolve_target_envs [TYPE Function]
# @BRIEF Resolves requested environment IDs from configuration.
# @PRE env_ids is non-empty.
# @POST Returns mapping env_id -> configured environment object.
# @PRE: env_ids is non-empty.
# @POST: Returns mapping env_id -> configured environment object.
def _resolve_target_envs(env_ids: List[str]) -> Dict[str, Environment]:
config_manager = ConfigManager()
configured = {env.id: env for env in config_manager.get_environments()}
@@ -162,7 +157,9 @@ def _resolve_target_envs(env_ids: List[str]) -> Dict[str, Environment]:
env = Environment(**row)
configured[env.id] = env
except Exception as exc:
log.explore("Failed loading environments from config", payload={"config_path": str(config_path)}, error=str(exc))
logger.warning(
f"[REFLECT] Failed loading environments from {config_path}: {exc}"
)
for env_id in env_ids:
env = configured.get(env_id)
@@ -178,8 +175,8 @@ def _resolve_target_envs(env_ids: List[str]) -> Dict[str, Environment]:
# #region _build_chart_template_pool [TYPE Function]
# @BRIEF Builds a pool of source chart templates to clone in one environment.
# @PRE Client is authenticated.
# @POST Returns non-empty list of chart payload templates.
# @PRE: Client is authenticated.
# @POST: Returns non-empty list of chart payload templates.
def _build_chart_template_pool(
client: SupersetClient, pool_size: int, rng: random.Random
) -> List[Dict]:
@@ -253,9 +250,9 @@ def _build_chart_template_pool(
# #region seed_superset_load_data [TYPE Function]
# @BRIEF Creates dashboards and cloned charts for load testing across target environments.
# @PRE Target environments must be reachable and authenticated.
# @POST Returns execution statistics dictionary.
# @SIDE_EFFECT Creates objects in Superset environments.
# @PRE: Target environments must be reachable and authenticated.
# @POST: Returns execution statistics dictionary.
# @SIDE_EFFECT: Creates objects in Superset environments.
def seed_superset_load_data(args: argparse.Namespace) -> Dict:
rng = random.Random(args.seed)
env_map = _resolve_target_envs(args.envs)
@@ -274,7 +271,9 @@ def seed_superset_load_data(args: argparse.Namespace) -> Dict:
templates_by_env[env_id] = _build_chart_template_pool(
client, args.template_pool_size, rng
)
log.reason("Loaded chart templates for environment", payload={"env_id": env_id, "template_count": len(templates_by_env[env_id])})
logger.info(
f"[REASON] Environment {env_id}: loaded {len(templates_by_env[env_id])} chart templates"
)
errors = 0
env_ids = list(env_map.keys())
@@ -286,7 +285,9 @@ def seed_superset_load_data(args: argparse.Namespace) -> Dict:
dashboard_title = _generate_unique_name("lt_dash", used_dashboard_names, rng)
if args.dry_run:
log.reflect("Dry-run dashboard create", payload={"env_id": env_id, "title": dashboard_title})
logger.info(
f"[REFLECT] Dry-run dashboard create: env={env_id}, title={dashboard_title}"
)
continue
try:
@@ -300,7 +301,7 @@ def seed_superset_load_data(args: argparse.Namespace) -> Dict:
created_dashboards[env_id].append(dashboard_id)
except Exception as exc:
errors += 1
log.explore("Failed creating dashboard", payload={"env_id": env_id}, error=str(exc))
logger.error(f"[EXPLORE] Failed creating dashboard in {env_id}: {exc}")
if errors >= args.max_errors:
raise RuntimeError(
f"Stopping due to max errors reached ({errors})"
@@ -350,10 +351,10 @@ def seed_superset_load_data(args: argparse.Namespace) -> Dict:
created_charts[env_id].append(chart_id)
if (index + 1) % 500 == 0:
log.reason(f"Created {index + 1}/{args.charts} charts")
logger.info(f"[REASON] Created {index + 1}/{args.charts} charts")
except Exception as exc:
errors += 1
log.explore("Failed creating chart", payload={"env_id": env_id}, error=str(exc))
logger.error(f"[EXPLORE] Failed creating chart in {env_id}: {exc}")
if errors >= args.max_errors:
raise RuntimeError(
f"Stopping due to max errors reached ({errors})"
@@ -374,13 +375,15 @@ def seed_superset_load_data(args: argparse.Namespace) -> Dict:
# #region main [TYPE Function]
# @BRIEF CLI entrypoint for Superset load-test data seeding.
# @PRE Command line arguments are valid.
# @POST Prints summary and exits with non-zero status on failure.
# @PRE: Command line arguments are valid.
# @POST: Prints summary and exits with non-zero status on failure.
def main() -> None:
with belief_scope("seed_superset_load_test.main"):
args = _parse_args()
result = seed_superset_load_data(args)
log.reflect("Seed load test complete", payload={"summary": result})
logger.info(
f"[COHERENCE:OK] Result summary: {json.dumps(result, ensure_ascii=True)}"
)
# #endregion main