Files
resolutionflow/backend/app/schemas/flowpilot_analytics.py
chihlasm a567d6d245 feat(analytics): add PSA activity logging and enhanced PSA metrics endpoint
- Log `note_posted` and `time_entry_posted` activities to `psa_activity_logs`
  after each successful PSA push in `psa_documentation_service.py`; errors
  are caught and logged without blocking the main push flow
- Add `PsaFunnel`, `PsaDailyTrend`, and `EnhancedPsaMetrics` Pydantic schemas
- Add `GET /analytics/flowpilot/psa-metrics?period=30d` endpoint (team_admin,
  rate-limited 15/min) returning time entry totals, push funnel
  (sessions → linked → doc pushed → time entry logged), and daily trend

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 00:11:07 +00:00

127 lines
2.9 KiB
Python

"""Pydantic schemas for FlowPilot analytics dashboard."""
from __future__ import annotations
from typing import Optional, Any
from datetime import datetime
from pydantic import BaseModel
class MTTRDataPoint(BaseModel):
date: str
mttr_minutes: float
session_count: int
class DomainBreakdown(BaseModel):
domain: str
total: int
resolved: int
escalated: int
resolution_rate: float
class ConfidenceBreakdown(BaseModel):
guided_sessions: int
guided_resolution_rate: float
exploring_sessions: int
exploring_resolution_rate: float
discovery_sessions: int
discovery_resolution_rate: float
class DomainCoverage(BaseModel):
domain: str
flow_count: int
session_count: int
guided_rate: float
class KnowledgeCoverage(BaseModel):
total_flows: int
ai_generated_flows: int
total_proposals_pending: int
proposals_approved_this_period: int
proposals_rejected_this_period: int
coverage_by_domain: list[DomainCoverage] = []
class PsaMetrics(BaseModel):
ticket_link_rate: float
auto_push_success_rate: float
auto_push_retry_success_rate: float
total_time_entries_logged: int
total_hours_logged: float
class CoverageDomainRow(BaseModel):
domain: str
flow_count: int
session_count: int
resolution_rate: float
escalation_rate: float
guided_rate: float
avg_resolution_minutes: float | None = None
class CoverageResponse(BaseModel):
domains: list[CoverageDomainRow]
unmapped_session_count: int
total_domains: int
class FlowQualityRow(BaseModel):
flow_id: str
name: str
tree_type: str
usage_count: int
success_rate: float | None = None
last_matched_at: datetime | None = None
avg_confidence: float | None = None
quality_score: float
class FlowQualityResponse(BaseModel):
flows: list[FlowQualityRow]
top_performers: list[FlowQualityRow]
needs_attention: list[FlowQualityRow]
class PsaFunnel(BaseModel):
total_sessions: int
linked_to_ticket: int
doc_pushed: int
time_entry_logged: int
class PsaDailyTrend(BaseModel):
date: str
entries: int
hours: float
class EnhancedPsaMetrics(BaseModel):
total_time_entries: int
total_hours_logged: float
avg_hours_per_session: float
push_funnel: PsaFunnel
daily_trend: list[PsaDailyTrend]
class FlowPilotDashboard(BaseModel):
period: str
total_sessions: int
resolved_sessions: int
escalated_sessions: int
abandoned_sessions: int
resolution_rate: float
avg_steps_to_resolution: float
avg_session_duration_minutes: float
avg_rating: float | None = None
mttr_minutes: float | None = None
mttr_trend: list[MTTRDataPoint] = []
sessions_by_domain: list[DomainBreakdown] = []
confidence_breakdown: ConfidenceBreakdown
knowledge_coverage: KnowledgeCoverage
psa_metrics: PsaMetrics | None = None