# Changelog

All notable changes to this project will be documented in this file.

This project adheres to [Semantic Versioning](https://semver.org/).

## [2.0.0] - 2026-03-21

### Added
- **QueryTurbo**: SQL compilation cache with three-phase trust lifecycle
  (UNTRUSTED → TRUSTED → POISONED). On cache miss, compiles and caches.
  On untrusted hit, validates cached SQL against fresh `as_sql()` output
  and promotes to TRUSTED after `VALIDATION_THRESHOLD` (default 3)
  successful validations. On trusted hit, skips `as_sql()` entirely and
  extracts params directly from the Query tree via `turbo/params.py`.
  On mismatch, poisons the entry for the lifetime of the process (persists across cache clears triggered by migrations).
- **True SQL Compilation Skipping**: `turbo/params.py` extracts params
  from the Django Query tree without calling `as_sql()`. Uses
  `lookup.as_sql(compiler, connection)` per WHERE node for exact param
  transformations (handles `__contains` wrapping, `__isnull` discarding,
  etc.) at a fraction of the cost of full SQL compilation.
- **Prepared Statement Bridge**: Multi-database prepared statement support.
  Automatic protocol-level preparation on PostgreSQL + psycopg3 after a
  configurable hit-count threshold. Oracle implicit cursor caching. Graceful
  fallback (TypeError → permanent disable) on unsupported backends.
- **AST SerializerMethodField Analyzer**: Static analysis of DRF `get_<field>`
  methods using `ast.parse()` to detect hidden N+1 queries at serialization
  time. Detects four patterns: related manager access, Model.objects calls,
  deep attribute chains, and for-loop queryset iteration.
- **Per-File Analysis**: `--file` and `--module` flags on `check_queries`
  and `diagnose_project` commands for focused diagnosis via substring matching.
- **Benchmark Dashboard**: `query_doctor_report` management command generates
  standalone HTML report with Chart.js graphs showing cache hit rates, top
  optimized queries, and prepared statement statistics.
- **GitHub Actions CI Integration**: `ci.github` module with
  `format_github_annotations()` for inline PR diff annotations,
  `generate_pr_comment()` for Markdown PR summaries, and
  `write_json_report()` for CI consumption. Example workflow in
  `examples/github-actions/query-doctor.yml`.
- **Baseline Snapshots**: `baseline.py` with `BaselineSnapshot` class for
  saving/loading issue snapshots. SHA-256 hashing ignores line numbers for
  stable identity across code movement. `--save-baseline`, `--baseline`,
  and `--fail-on-regression` flags on `check_queries` and `diagnose_project`.
- **Smart Prescription Grouping**: `grouping.py` with `group_prescriptions()`
  supporting `file_analyzer`, `root_cause`, and `view` strategies. `--group`
  flag on `check_queries` and `diagnose_project`. Console reporter supports
  grouped output mode.
- **Async-Safe Context Managers**: `turbo_enabled()` / `turbo_disabled()`
  now use `contextvars.ContextVar` instead of `threading.local()`, making
  them safe for ASGI deployments with concurrent coroutines.
- **`check_serializers` command**: Dedicated management command for AST-based
  DRF serializer analysis with `--app`, `--file`, `--format`, and `--fail-on`
  flags.
- **Post-migrate cache invalidation**: Automatic cache clear on Django
  `post_migrate` signal to prevent stale SQL after schema changes.
- **Fingerprint collision detection**: Cache hit path validates SQL matches
  and poisons mismatched entries permanently.
- **`__in` lookup length in fingerprint**: Different `__in` list sizes
  produce different fingerprints, preventing SQL/param count mismatch.
- **`select_for_update` in fingerprint**: Queries with `FOR UPDATE`,
  `NOWAIT`, and `SKIP LOCKED` produce distinct fingerprints.
- **Annotation source field fingerprinting**: Annotations with the same
  name but different field targets produce different fingerprints.

### Changed
- Minimum Python version remains 3.10
- All existing v1.x APIs remain backward compatible
- Version bumped to 2.0.0
- Context managers switched from `threading.local()` to `contextvars.ContextVar`
- Cache entries now track `validated_count`, `trusted`, `poisoned` state
- New config key: `VALIDATION_THRESHOLD` (default 3) controls trust promotion

## [1.0.3] - 2026-03-18

### Fixed
- Missing Index analyzer now recommends `Meta.indexes` with `models.Index()` instead of `db_index=True`, following Django's official recommendation since 4.2 (fixes #1)
- Auto-fix for missing indexes now generates `Meta.indexes` suggestion instead of `db_index=True`
- `_field_is_indexed` now checks `Meta.constraints` for `UniqueConstraint` (modern Django 4.2+ pattern) in addition to `unique_together`

### Changed
- Full audit of all prescription texts across all 7 analyzers to align with Django 4.2–6.0 best practices
- Fat SELECT prescriptions now mention `.values()`/`.values_list()` as alternatives when model instances aren't needed
- N+1 prescriptions for `prefetch_related` now mention `Prefetch()` objects for advanced filtering scenarios
- QuerySet evaluation prescriptions now mention `.iterator()` for large querysets to reduce memory usage
- Updated docs, README, and all affected tests to reflect new recommendation text

## [1.0.2] - 2026-03-16

### Fixed
- Fixed SVG terminal renders not displaying on GitHub (switched to absolute URLs)
- Removed Google Fonts @import from SVGs blocked by GitHub CSP

## [1.0.1] - 2026-03-15

### Changed
- Added SVG terminal renders to README for visual feature showcase
- Added Django 6.0 mention in README requirements
- Cleaned up committed __pycache__ artifacts
- Updated .gitignore with additional exclusions

## [1.0.0] - 2026-03-13

### Added

#### Core Pipeline
- Query interception via `connection.execute_wrapper()` — works without `DEBUG=True`
- SQL fingerprinting with normalization and SHA-256 hashing
- Source code mapping with file:line references via stack trace analysis
- Django middleware with zero-config setup (one line in `MIDDLEWARE`)
- `diagnose_queries()` context manager for targeted analysis
- `@diagnose` and `@query_budget` decorators
- Full configuration system via `QUERY_DOCTOR` Django settings

#### Analyzers
- **N+1 Detection** — fingerprint-based grouping with FK pattern matching
- **Duplicate Query Detection** — exact and near-duplicate identification
- **Missing Index Detection** — WHERE/ORDER BY columns without indexes
- **Fat SELECT Detection** — flags `SELECT *` when fewer columns suffice
- **QuerySet Evaluation** — suggests `.count()`, `.exists()`, `.first()` alternatives
- **DRF Serializer N+1** — detects missing prefetch in DRF views

#### Reporters
- **Console** — Rich terminal output with fallback to plain text
- **JSON** — structured output for CI/CD pipelines
- **Log** — Python logging integration
- **HTML** — standalone dashboard report
- **OpenTelemetry** — span and event export for observability stacks

#### Ecosystem
- Celery task support via `@diagnose_task` decorator
- Async Django/ASGI middleware support
- Custom analyzer plugin API via Python entry points
- Pytest plugin with `query_doctor` fixture
- `check_queries` management command for CI analysis
- `query_budget` management command for budget enforcement

#### Project-Wide Diagnosis
- **diagnose_project** management command — crawls all project URLs and generates app-wise health report
- Standalone HTML report with health scores, sortable app scoreboard, and per-URL prescription detail
- JSON report output for CI integration
- Admin dashboard integration showing latest project scan results

#### Auto-Fix & CI
- **Auto-Fix Mode** — `fix_queries` management command applies diagnosed fixes with dry-run default and .bak backups
- **Diff-Aware CI** — `--diff` flag for `check_queries` to analyze only files changed vs a git ref
- **.queryignore** — project-level file to suppress known false positives by SQL pattern, file, callsite, or issue type

#### Monitoring
- **Admin Dashboard** — staff-only in-memory dashboard showing recent query diagnosis reports
- **Query Complexity Scorer** — regex-based SQL complexity analysis flagging excessive JOINs, subqueries, and OR chains

#### Developer Experience
- Every prescription includes severity, description, file:line, and exact code fix
- Zero required dependencies beyond Django
- Optional extras: Rich, Celery, OpenTelemetry
- Full type annotations with `py.typed` (PEP 561)
- CI matrix: Python 3.10-3.13 x Django 4.2-6.0
