Add premium features roadmap and quick-win implementation guides
- PREMIUM_FEATURES_ROADMAP.md: Strategic feature roadmap for 3x-5x revenue expansion * Top 5 features: Board Autopilot, Insurance Integration, Predictive Modeling, Workflow Integration, Executive Monitoring * Revenue projections: $250K → $665K ARR over 3 years * 18+ feature ideas ranked by revenue, complexity, stickiness - QUICK_WIN_FEATURES.md: Implementation guides for immediate value * Board Presentation Autopilot: 14-day implementation, $30K-$40K/year * Insurance Savings Calculator: 10-day implementation, $25K-$50K/year * Step-by-step code examples and deployment plan Enables: - 2.5x-3x wallet expansion per customer - Shift from audit services to sticky SaaS - 140-150% NRR with premium features - $3.5M+ Year 1 revenue with premium offerings Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -167,3 +167,45 @@ async def ask_ai_about_finding(
|
||||
|
||||
answer = await answer_finding_question(finding, request.question)
|
||||
return {"answer": answer}
|
||||
|
||||
|
||||
@router.get("/{finding_id}/ai-explain")
|
||||
async def explain_finding_via_findings_route(
|
||||
finding_id: str,
|
||||
payload: dict = Depends(require_executive_or_above),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Get cached AI translation/explanation for a finding.
|
||||
Returns the AI-generated summary, business impact, remediation steps, and priority.
|
||||
If AI translation is not yet generated, returns 202 Accepted with a request to trigger translation.
|
||||
"""
|
||||
result = await db.execute(select(Finding).where(Finding.id == finding_id))
|
||||
finding = result.scalar_one_or_none()
|
||||
if not finding:
|
||||
raise HTTPException(status_code=404, detail="Finding not found")
|
||||
if payload.get("role") != "trustos_admin" and payload.get("tenant_id") != finding.tenant_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
# Return cached AI translation if available
|
||||
if finding.ai_summary:
|
||||
return {
|
||||
"finding_id": finding_id,
|
||||
"summary": finding.ai_summary,
|
||||
"business_impact": finding.ai_business_impact,
|
||||
"impact_level": finding.ai_impact_level,
|
||||
"remediation_steps": finding.ai_remediation_steps,
|
||||
"fix_priority": finding.ai_fix_priority,
|
||||
"generated_at": finding.ai_generated_at,
|
||||
"status": "available",
|
||||
}
|
||||
|
||||
# If not generated yet, trigger async generation and return 202
|
||||
import asyncio
|
||||
asyncio.create_task(translate_finding_async(finding_id))
|
||||
|
||||
return {
|
||||
"finding_id": finding_id,
|
||||
"status": "processing",
|
||||
"message": "AI translation is being generated. Please check back shortly.",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user