123 lines
4.3 KiB
Python
123 lines
4.3 KiB
Python
from datetime import datetime, timedelta
|
|
from typing import Optional
|
|
|
|
from db.db import get_db
|
|
from db.models import InvestorInsightCache, InvestorTable, ProjectTable
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from schemas.insight_schema import InsightResponse
|
|
from services.compatibility_score import (
|
|
calculate_project_investor_compatibility,
|
|
generate_compatibility_explanation,
|
|
)
|
|
from services.insight import QueryProcessor
|
|
from sqlalchemy.orm import Session
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get(
|
|
"/insights/{investor_id}", response_model=InsightResponse, tags=["Insights"]
|
|
)
|
|
async def get_insights(
|
|
investor_id: int, project_id: Optional[int] = None, db: Session = Depends(get_db)
|
|
):
|
|
"""
|
|
Get investor insights including investment pattern analysis, market position,
|
|
and optionally compatibility score with a project.
|
|
|
|
Args:
|
|
investor_id: The ID of the investor to analyze
|
|
project_id: Optional project ID to calculate compatibility score
|
|
|
|
Returns:
|
|
InsightResponse with investment_pattern_analysis, market_position,
|
|
and compatibility_score (if project_id provided)
|
|
"""
|
|
# Get investor from database
|
|
investor = db.query(InvestorTable).filter(InvestorTable.id == investor_id).first()
|
|
if not investor:
|
|
raise HTTPException(
|
|
status_code=404, detail=f"Investor with id {investor_id} not found"
|
|
)
|
|
|
|
# Check if we have cached insights
|
|
cached_insights = (
|
|
db.query(InvestorInsightCache)
|
|
.filter(InvestorInsightCache.investor_id == investor_id)
|
|
.first()
|
|
)
|
|
|
|
# Determine if cache needs refresh (older than 1 month)
|
|
needs_refresh = True
|
|
if cached_insights:
|
|
# Calculate if cache is older than 1 month
|
|
cache_age = (
|
|
datetime.now(cached_insights.last_refreshed.tzinfo)
|
|
- cached_insights.last_refreshed
|
|
)
|
|
needs_refresh = cache_age > timedelta(days=30)
|
|
|
|
# Fetch new insights if needed
|
|
if needs_refresh:
|
|
# Initialize the query processor for insights
|
|
query_processor = QueryProcessor()
|
|
|
|
# Get investment pattern analysis and market position using web search
|
|
insights = await query_processor.get_investor_insights(
|
|
investor_name=investor.name,
|
|
investor_website=investor.website,
|
|
investor_description=investor.description,
|
|
investor_headquarters=investor.headquarters,
|
|
investment_thesis=investor.investment_thesis,
|
|
portfolio_highlights=investor.portfolio_highlights,
|
|
)
|
|
|
|
# Update or create cache entry
|
|
if cached_insights:
|
|
# Update existing cache
|
|
cached_insights.investment_pattern_analysis = insights[
|
|
"investment_pattern_analysis"
|
|
]
|
|
cached_insights.market_position = insights["market_position"]
|
|
cached_insights.last_refreshed = datetime.now(
|
|
cached_insights.last_refreshed.tzinfo
|
|
)
|
|
else:
|
|
# Create new cache entry
|
|
cached_insights = InvestorInsightCache(
|
|
investor_id=investor_id,
|
|
investment_pattern_analysis=insights["investment_pattern_analysis"],
|
|
market_position=insights["market_position"],
|
|
)
|
|
db.add(cached_insights)
|
|
|
|
db.commit()
|
|
db.refresh(cached_insights)
|
|
|
|
# Calculate compatibility score if project_id is provided
|
|
compatibility_score = None
|
|
if project_id:
|
|
project = db.query(ProjectTable).filter(ProjectTable.id == project_id).first()
|
|
if not project:
|
|
raise HTTPException(
|
|
status_code=404, detail=f"Project with id {project_id} not found"
|
|
)
|
|
|
|
# Calculate the compatibility score
|
|
score = calculate_project_investor_compatibility(
|
|
project, investor, use_funds=True
|
|
)
|
|
|
|
# Generate detailed explanation
|
|
compatibility_score = generate_compatibility_explanation(
|
|
project, investor, score, use_funds=True
|
|
)
|
|
else:
|
|
compatibility_score = "Select a project to see compatibility analysis"
|
|
|
|
return InsightResponse(
|
|
investment_pattern_analysis=cached_insights.investment_pattern_analysis,
|
|
market_position=cached_insights.market_position,
|
|
compatibility_score=compatibility_score,
|
|
)
|