Cuts release 0.20.0. ## Highlights - X-Request-ID header on every response + sanitized to [A-Za-z0-9_-] (CRLF log-forging mitigation) - Error pages (HTML + JSON 500) surface request_id for support tickets - Dev debug toolbar gated by DEBUG=1 — fastapi-debug-toolbar with custom DuckDBPanel - Centralized app.logging_config.setup_logging() replaces 23 scattered basicConfig calls - Telegram bot drops bot.log file — stdout only (BREAKING) ## Devin findings addressed - BUG_0001: .env.template no longer claims FastAPI debug=True - BUG_0002: subprocess extractor logs INFO to stderr again - ANALYSIS_0003: _wants_html no longer matches Accept: */* (curl gets JSON as before) - BUG on b1c6ee9: HTML 500 page no longer leaks str(exc) in production - BUG on b13d2fe: 2 CLAUDE.md compliance flags (transform.py + ws_gateway) accepted as scope-limited logging refactor — follow-up to update CLAUDE.md if needed See CHANGELOG [0.20.0] for full notes.
41 lines
1.1 KiB
Python
41 lines
1.1 KiB
Python
"""Migrate metric YAML files to DuckDB metric_definitions table.
|
|
|
|
Usage:
|
|
python scripts/migrate_metrics_to_duckdb.py [--metrics-dir docs/metrics]
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from app.logging_config import setup_logging
|
|
|
|
setup_logging(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Migrate metric YAMLs to DuckDB")
|
|
parser.add_argument("--metrics-dir", default="docs/metrics", help="Path to metrics directory")
|
|
args = parser.parse_args()
|
|
|
|
metrics_dir = Path(args.metrics_dir)
|
|
if not metrics_dir.is_dir():
|
|
logger.error("Metrics directory not found: %s", metrics_dir)
|
|
sys.exit(1)
|
|
|
|
from src.db import get_system_db
|
|
from src.repositories.metrics import MetricRepository
|
|
|
|
conn = get_system_db()
|
|
try:
|
|
repo = MetricRepository(conn)
|
|
count = repo.import_from_yaml(metrics_dir)
|
|
logger.info("Imported %d metrics from %s", count, metrics_dir)
|
|
finally:
|
|
conn.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|