fix: harden Task 2 schema quality boundaries

This commit is contained in:
2026-08-11 06:09:07 +02:00
parent d5f752dd7b
commit 9e2c2b37b3
3 changed files with 183 additions and 64 deletions
+34 -17
View File
@@ -1,6 +1,7 @@
# ruff: noqa: BLE001
import logging
from collections.abc import Mapping
from pathlib import Path
from typing import TypedDict
from typing import Literal, TypedDict
import typer
@@ -15,6 +16,7 @@ from tht.ports.vector import VectorWriteRecord
from tht.vectorstore.store import SyncStats, content_hash
vector_app = typer.Typer(help="Indice semantico Qdrant (derivato, rigenerabile)")
logger = logging.getLogger(__name__)
def make_embedder(embeddings_cfg):
@@ -80,10 +82,19 @@ def sync_canonical_records(collection, records, *, store, embedder):
return stats
def _print_stats(stats) -> None:
def _print_stats(stats: SyncStats | Mapping[str, int]) -> None:
if isinstance(stats, SyncStats):
counts = {
"added": stats.added,
"updated": stats.updated,
"deleted": stats.deleted,
"unchanged": stats.unchanged,
}
else:
counts = stats
typer.secho(
f"OK: {stats.added} nuovi, {stats.updated} aggiornati, "
f"{stats.deleted} rimossi, {stats.unchanged} invariati",
f"OK: {counts['added']} nuovi, {counts['updated']} aggiornati, "
f"{counts['deleted']} rimossi, {counts['unchanged']} invariati",
fg=typer.colors.GREEN,
)
@@ -138,8 +149,8 @@ class IndexCounts(TypedDict):
class IndexSchemaResult(TypedDict):
status: str
code: str
status: Literal["succeeded", "failed"]
code: Literal["ok"]
counts: IndexCounts
@@ -158,26 +169,31 @@ def _vector_write_or_error(cfg) -> None:
raise _MachineVectorError("vector_write_not_allowed")
def index_schema_data(config: Path) -> IndexSchemaResult:
def index_schema_data(
config: Path, *, suppress_legacy_warning: bool = False
) -> IndexSchemaResult:
"""Synchronize schema records and return a bounded machine result."""
from tht.cli.schema_cmd import _machine_config
from tht.cli.schema_cmd import _load_schema_config
from tht.config import ConfigError
from tht.mschema.models import Annotations, PhysicalSchema
from tht.vectorstore.records import schema_records
try:
cfg = _machine_config(config)
except Exception:
# Keep this helper free of Typer rendering while preserving a stable code.
cfg = _load_schema_config(config, suppress_legacy_warning=suppress_legacy_warning)
except ConfigError:
raise _MachineVectorError("invalid_configuration") from None
_vector_write_or_error(cfg)
_vector_cfg_or_error(cfg)
phys_file = physical_path(cfg)
if not phys_file.exists():
raise _MachineVectorError("physical_schema_missing")
import yaml
from pydantic import ValidationError
try:
physical = PhysicalSchema.from_yaml(phys_file)
annotations = Annotations.from_yaml(annotations_path(cfg))
except Exception:
except (OSError, UnicodeError, TypeError, ValueError, yaml.YAMLError, ValidationError):
raise _MachineVectorError("schema_artifacts_invalid") from None
records = schema_records(physical, annotations)
from tht.adapters.factory import build_vector_store
@@ -210,23 +226,24 @@ def index_schema_cmd(
if json_output:
try:
payload = index_schema_data(config)
payload = index_schema_data(config, suppress_legacy_warning=True)
except _MachineVectorError as error:
typer.echo(json.dumps({"status": "failed", "code": error.code}, sort_keys=True, separators=(",", ":")))
raise typer.Exit(code=1) from None
except Exception:
except Exception: # noqa: BLE001 - JSON CLI boundary
typer.echo(json.dumps({"status": "failed", "code": "schema_index_failed"}, sort_keys=True, separators=(",", ":")))
raise typer.Exit(code=1) from None
typer.echo(json.dumps(payload, sort_keys=True, separators=(",", ":")))
return
try:
payload = index_schema_data(config)
payload = index_schema_data(config, suppress_legacy_warning=False)
except _MachineVectorError as error:
_render_index_schema_error(error, config)
except Exception:
logger.exception("Schema indexing failed")
typer.secho("ERRORE: impossibile indicizzare lo schema.", fg=typer.colors.RED, err=True)
raise typer.Exit(code=1) from None
_print_stats(type("Stats", (), payload["counts"])())
_print_stats(payload["counts"])
def _render_index_schema_error(error: _MachineVectorError, config: Path) -> None: