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>
This commit is contained in:
@@ -14,6 +14,7 @@ from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.ai_session import AISession
|
||||
from app.models.psa_activity_log import PsaActivityLog
|
||||
from app.models.psa_connection import PsaConnection
|
||||
from app.models.psa_member_mapping import PsaMemberMapping
|
||||
from app.models.psa_post_log import PsaPostLog
|
||||
@@ -303,6 +304,7 @@ async def push_documentation(
|
||||
)
|
||||
|
||||
# Create time entry if member mapping exists
|
||||
time_entry_hours: Optional[float] = None
|
||||
if member_mapping and session.resolved_at and session.created_at:
|
||||
try:
|
||||
delta = session.resolved_at - session.created_at
|
||||
@@ -316,10 +318,38 @@ async def push_documentation(
|
||||
hours=rounded_hours,
|
||||
notes=f"FlowPilot session: {session.problem_summary or 'Troubleshooting'}",
|
||||
)
|
||||
time_entry_hours = rounded_hours
|
||||
except Exception as e:
|
||||
logger.warning("Failed to create time entry for session %s: %s", session.id, e)
|
||||
# Don't fail the note push just because time entry failed
|
||||
|
||||
# Log PSA activity — note posted
|
||||
try:
|
||||
note_activity = PsaActivityLog(
|
||||
account_id=session.account_id,
|
||||
session_id=session.id,
|
||||
activity_type="note_posted",
|
||||
hours_logged=None,
|
||||
psa_ticket_id=session.psa_ticket_id,
|
||||
)
|
||||
db.add(note_activity)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to log PSA note activity for session %s: %s", session.id, e)
|
||||
|
||||
# Log time entry activity if one was created
|
||||
if time_entry_hours is not None:
|
||||
try:
|
||||
time_activity = PsaActivityLog(
|
||||
account_id=session.account_id,
|
||||
session_id=session.id,
|
||||
activity_type="time_entry_posted",
|
||||
hours_logged=time_entry_hours,
|
||||
psa_ticket_id=session.psa_ticket_id,
|
||||
)
|
||||
db.add(time_activity)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to log PSA time entry activity for session %s: %s", session.id, e)
|
||||
|
||||
# Log success
|
||||
log_entry = PsaPostLog(
|
||||
id=uuid.uuid4(),
|
||||
|
||||
Reference in New Issue
Block a user