from datetime import datetime from enum import Enum from typing import List, Optional from pydantic import BaseModel class InvestmentStage(str, Enum): SEED = "SEED" SERIES_A = "SERIES_A" SERIES_B = "SERIES_B" SERIES_C = "SERIES_C" GROWTH = "GROWTH" LATE_STAGE = "LATE_STAGE" class SectorSchema(BaseModel): id: int name: str class Config: from_attributes = True class InvestmentStageSchema(BaseModel): id: int name: str class Config: from_attributes = True class InvestorMemberSchema(BaseModel): id: int name: str role: str | None email: str | None class Config: from_attributes = True class FundSchema(BaseModel): id: int fund_name: str | None fund_size: int | None # Changed to int for numerical filtering fund_size_source_url: str | None check_size_lower: int | None # NEW: Lower bound of check size range check_size_upper: int | None # NEW: Upper bound of check size range source_url: str | None source_provider: str | None geographic_focus: str | None # Changed from List[str] to string investment_stages: List[InvestmentStageSchema] | None # Changed to relationship sectors: List[SectorSchema] | None # Changed to relationship created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class Config: from_attributes = True class CompanyMemberSchema(BaseModel): id: int name: Optional[str] linkedin: Optional[str] role: Optional[str] company_id: int class Config: from_attributes = True class CompanySchema(BaseModel): id: int name: str industry: str | None location: str | None description: Optional[str] founded_year: Optional[int] website: Optional[str] created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class Config: from_attributes = True class InvestorSchema(BaseModel): id: int name: str description: Optional[str] aum: int | None check_size_lower: int | None check_size_upper: int | None geographic_focus: str | None stage_focus: InvestmentStage number_of_investments: int | None created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class Config: from_attributes = True class InvestorData(BaseModel): """Comprehensive investor data schema - used for individual investor requests""" investor: InvestorSchema portfolio_companies: List[CompanySchema] team_members: List[InvestorMemberSchema] sectors: List[SectorSchema] funds: List[FundSchema] class Config: from_attributes = True class InvestorFundData(BaseModel): """Investor-Fund combined data - used for list/filter requests Each row represents one investor-fund combination. An investor with 3 funds will appear as 3 separate entries. """ # Investor fields investor_id: int investor_name: str investor_description: Optional[str] investor_website: Optional[str] investor_headquarters: Optional[str] aum: int | None aum_as_of_date: str | None aum_source_url: str | None investment_thesis: List[str] | None portfolio_highlights: List[str] | None number_of_investments: int | None # Fund fields fund_id: int | None fund_name: str | None fund_size: int | None # Changed to int for numerical filtering fund_size_source_url: str | None check_size_lower: int | None # NEW: Lower bound of check size range check_size_upper: int | None # NEW: Upper bound of check size range geographic_focus: str | None # Changed from List[str] to string fund_investment_stages: ( List[InvestmentStageSchema] | None ) # Changed to relationship fund_sectors: List[SectorSchema] | None # Changed to relationship # Related data portfolio_companies: List[CompanySchema] team_members: List[InvestorMemberSchema] sectors: List[SectorSchema] class Config: from_attributes = True class CompanyData(BaseModel): # Renamed from CompaniesData for consistency company: CompanySchema sectors: List[SectorSchema] members: List[CompanyMemberSchema] investors: List[InvestorSchema] class Config: from_attributes = True class InvestorList(BaseModel): investors: List[InvestorData] class InvestorFundList(BaseModel): """List of investor-fund combinations""" investor_funds: List[InvestorFundData]