Datavision / backend /api /v1 /endpoints /onboarding.py
DataVision CI/CD Bot
release: clean production build for HuggingFace Space
ee7d7b9
Raw
History Blame Contribute Delete
6.63 kB
# Onboarding API - Company Profile Setup
"""
API endpoints for company profile onboarding.
Enables users to configure their company context for intelligent responses.
"""
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field
from typing import Dict, List, Optional
from datetime import datetime
from core.company_profile import (
CompanyProfile,
get_company_profile,
save_company_profile,
delete_company_profile,
get_company_benchmarks,
INDUSTRY_BENCHMARKS,
Industry,
)
router = APIRouter(prefix="/onboarding", tags=["onboarding"])
# ============================================================================
# REQUEST/RESPONSE MODELS
# ============================================================================
class CompanyProfileRequest(BaseModel):
"""Request model for creating/updating company profile"""
company_name: str = Field(..., min_length=1, max_length=200)
industry: str = Field(default="other", description="Industry type for benchmarking")
fiscal_year_end_month: int = Field(default=12, ge=1, le=12)
currency: str = Field(default="USD", max_length=3)
currency_symbol: str = Field(default="$", max_length=5)
timezone: str = Field(default="UTC")
# Optional customizations
kpi_definitions: Optional[Dict[str, str]] = None
terminology: Optional[Dict[str, str]] = None
benchmarks: Optional[Dict[str, float]] = None
branding: Optional[Dict[str, str]] = None
class CompanyProfileResponse(BaseModel):
"""Response model for company profile"""
workspace_id: str
company_name: str
industry: str
fiscal_year_end_month: int
currency: str
currency_symbol: str
timezone: str
kpi_definitions: Dict[str, str]
terminology: Dict[str, str]
benchmarks: Dict[str, float]
branding: Dict[str, str]
created_at: str
updated_at: str
# Computed fields
industry_benchmarks: Dict[str, float]
class IndustryOption(BaseModel):
"""Industry option for dropdown"""
value: str
label: str
benchmarks: Dict[str, float]
# ============================================================================
# ENDPOINTS
# ============================================================================
@router.get("/industries", response_model=List[IndustryOption])
async def get_industries():
"""Get list of available industries with their benchmarks"""
industries = []
for industry in Industry:
benchmarks = INDUSTRY_BENCHMARKS.get(industry, {})
industries.append(IndustryOption(
value=industry.value,
label=industry.value.replace("_", " ").title(),
benchmarks={k: float(v) for k, v in benchmarks.items()}
))
return industries
@router.get("/company-profile/{workspace_id}", response_model=CompanyProfileResponse)
async def get_profile(workspace_id: str):
"""Get company profile for a workspace"""
profile = get_company_profile(workspace_id)
if not profile:
raise HTTPException(status_code=404, detail="Company profile not found")
return CompanyProfileResponse(
workspace_id=profile.workspace_id,
company_name=profile.company_name,
industry=profile.industry,
fiscal_year_end_month=profile.fiscal_year_end_month,
currency=profile.currency,
currency_symbol=profile.currency_symbol,
timezone=profile.timezone,
kpi_definitions=profile.kpi_definitions,
terminology=profile.terminology,
benchmarks=profile.benchmarks,
branding=profile.branding,
created_at=profile.created_at,
updated_at=profile.updated_at,
industry_benchmarks=profile.get_industry_benchmarks(),
)
@router.post("/company-profile/{workspace_id}", response_model=CompanyProfileResponse)
async def create_profile(workspace_id: str, request: CompanyProfileRequest):
"""Create or update company profile for a workspace"""
# Build profile from request
profile = CompanyProfile(
workspace_id=workspace_id,
company_name=request.company_name,
industry=request.industry.lower(),
fiscal_year_end_month=request.fiscal_year_end_month,
currency=request.currency.upper(),
currency_symbol=request.currency_symbol,
timezone=request.timezone,
)
# Apply optional customizations
if request.kpi_definitions:
profile.kpi_definitions.update(request.kpi_definitions)
if request.terminology:
profile.terminology.update(request.terminology)
if request.benchmarks:
profile.benchmarks.update(request.benchmarks)
if request.branding:
profile.branding.update(request.branding)
# Save to database
success = save_company_profile(profile)
if not success:
raise HTTPException(status_code=500, detail="Failed to save company profile")
# Return the saved profile
return CompanyProfileResponse(
workspace_id=profile.workspace_id,
company_name=profile.company_name,
industry=profile.industry,
fiscal_year_end_month=profile.fiscal_year_end_month,
currency=profile.currency,
currency_symbol=profile.currency_symbol,
timezone=profile.timezone,
kpi_definitions=profile.kpi_definitions,
terminology=profile.terminology,
benchmarks=profile.benchmarks,
branding=profile.branding,
created_at=profile.created_at,
updated_at=profile.updated_at,
industry_benchmarks=profile.get_industry_benchmarks(),
)
@router.put("/company-profile/{workspace_id}", response_model=CompanyProfileResponse)
async def update_profile(workspace_id: str, request: CompanyProfileRequest):
"""Update existing company profile"""
# Same as create - upsert behavior
return await create_profile(workspace_id, request)
@router.delete("/company-profile/{workspace_id}")
async def remove_profile(workspace_id: str):
"""Delete company profile"""
success = delete_company_profile(workspace_id)
if not success:
raise HTTPException(status_code=500, detail="Failed to delete company profile")
return {"message": "Company profile deleted successfully"}
@router.get("/company-profile/{workspace_id}/benchmarks")
async def get_workspace_benchmarks(workspace_id: str):
"""Get benchmarks for a workspace (industry defaults + custom overrides)"""
benchmarks = get_company_benchmarks(workspace_id)
return {
"workspace_id": workspace_id,
"benchmarks": benchmarks,
}