-- AI Ticket Analyzer — Phase 2 schema additions.
-- See docs/ticket-analyzer-phase2-spec.md for the full spec.
--
-- This migration adds:
--   1. analyzer_stage_executions — per-stage I/O for every pipeline run.
--      Replaces analyzer_analyses.model_traces (kept for back-compat for now).
--   2. Three columns on analyzer_analyses:
--        source_snapshot           — Stage 0 preprocessed events at analysis time
--        aggregate_fingerprint     — Stage 6 structured fingerprint (added in phase-2.4)
--        fingerprint_generated_at  — when Stage 6 succeeded (null until then)
--
-- Phase 2.6 will add analyzer_aggregate_reports + a column + check constraint
-- on analyzer_stage_executions linking stage rows to aggregate report runs.

CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- =============================================================================
-- analyzer_stage_executions
-- One row per pipeline-stage attempt. Even failed attempts insert a row.
-- =============================================================================
CREATE TABLE IF NOT EXISTS analyzer_stage_executions (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  analysis_id     UUID NOT NULL REFERENCES analyzer_analyses(id) ON DELETE CASCADE,
  stage           TEXT NOT NULL
                    CHECK (stage IN ('preprocess','triage','itglue','analyze','deep_review','fingerprint')),
  stage_order     INT NOT NULL,
  model_id        TEXT,
  input_payload   JSONB NOT NULL,
  output_payload  JSONB NOT NULL,
  input_tokens    INT,
  output_tokens   INT,
  latency_ms      INT,
  started_at      TIMESTAMPTZ NOT NULL,
  completed_at    TIMESTAMPTZ NOT NULL,
  error_message   TEXT
);

CREATE INDEX IF NOT EXISTS idx_analyzer_stage_executions_analysis_order
  ON analyzer_stage_executions (analysis_id, stage_order);

CREATE INDEX IF NOT EXISTS idx_analyzer_stage_executions_stage
  ON analyzer_stage_executions (stage);

COMMENT ON TABLE analyzer_stage_executions IS
  'Per-stage I/O for analyzer pipeline runs. One row per stage attempt, including failures. '
  'Replaces the analyzer_analyses.model_traces JSONB blob (kept for back-compat).';

COMMENT ON COLUMN analyzer_stage_executions.input_payload IS
  'Exactly what was sent to the stage. For LLM stages: the system+user prompt payload.';
COMMENT ON COLUMN analyzer_stage_executions.output_payload IS
  'Exactly what came back, pre-merge. For itglue: the redacted docs array. For deep_review: '
  'the full Opus response including opus_notes (was previously dropped at merge time).';

-- =============================================================================
-- analyzer_analyses — three new nullable columns.
-- =============================================================================
ALTER TABLE analyzer_analyses
  ADD COLUMN IF NOT EXISTS source_snapshot          JSONB,
  ADD COLUMN IF NOT EXISTS aggregate_fingerprint    JSONB,
  ADD COLUMN IF NOT EXISTS fingerprint_generated_at TIMESTAMPTZ;

COMMENT ON COLUMN analyzer_analyses.source_snapshot IS
  'Stage 0 preprocessed event list at analysis time. Stored canonically so re-analysis or '
  'aggregate analysis sees consistent input even if the live ticket data changes upstream.';
COMMENT ON COLUMN analyzer_analyses.aggregate_fingerprint IS
  'Stage 6 structured fingerprint (categorization, gaps, recurrence signals) used by '
  'aggregate cross-ticket reports. Null until Stage 6 succeeds.';
COMMENT ON COLUMN analyzer_analyses.fingerprint_generated_at IS
  'Timestamp when aggregate_fingerprint was written. Null when fingerprint stage skipped or failed.';
COMMENT ON COLUMN analyzer_analyses.model_traces IS
  'LEGACY (phase 1). Superseded by analyzer_stage_executions. Will be dropped once aggregate '
  'analysis is live and stage_executions has full coverage.';

CREATE INDEX IF NOT EXISTS idx_analyzer_analyses_fingerprint_present
  ON analyzer_analyses (id)
  WHERE aggregate_fingerprint IS NOT NULL;
