feat(ai): add tenant-safe hierarchical expense learning
This commit is contained in:
@@ -5,7 +5,7 @@ from typing import Annotated
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.api.deps import get_current_user, get_db
|
||||
from app.api.deps import CurrentUserContext, get_current_user, get_db
|
||||
from app.schemas.common import ErrorResponse
|
||||
from app.schemas.risk_observation import (
|
||||
RiskObservationDashboardRead,
|
||||
@@ -16,8 +16,9 @@ from app.schemas.risk_observation import (
|
||||
)
|
||||
from app.services.risk_observations import RiskObservationService
|
||||
|
||||
router = APIRouter(prefix="/risk-observations", dependencies=[Depends(get_current_user)])
|
||||
router = APIRouter(prefix="/risk-observations")
|
||||
DbSession = Annotated[Session, Depends(get_db)]
|
||||
CurrentUser = Annotated[CurrentUserContext, Depends(get_current_user)]
|
||||
|
||||
|
||||
@router.get(
|
||||
@@ -28,6 +29,7 @@ DbSession = Annotated[Session, Depends(get_db)]
|
||||
)
|
||||
def list_risk_observations(
|
||||
db: DbSession,
|
||||
current_user: CurrentUser,
|
||||
claim_id: Annotated[str | None, Query(max_length=80)] = None,
|
||||
run_id: Annotated[str | None, Query(max_length=80)] = None,
|
||||
execution_log_id: Annotated[str | None, Query(max_length=80)] = None,
|
||||
@@ -42,6 +44,7 @@ def list_risk_observations(
|
||||
offset: Annotated[int, Query(ge=0)] = 0,
|
||||
) -> RiskObservationListRead:
|
||||
items, total = RiskObservationService(db).list_observations(
|
||||
tenant_id=current_user.tenant_id,
|
||||
claim_id=claim_id,
|
||||
run_id=run_id,
|
||||
execution_log_id=execution_log_id,
|
||||
@@ -63,10 +66,12 @@ def list_risk_observations(
|
||||
)
|
||||
def summarize_risk_observations(
|
||||
db: DbSession,
|
||||
current_user: CurrentUser,
|
||||
window_days: Annotated[int, Query(ge=1, le=365)] = 30,
|
||||
limit: Annotated[int, Query(ge=1, le=2000)] = 500,
|
||||
) -> RiskObservationDashboardRead:
|
||||
return RiskObservationService(db).summarize_dashboard(
|
||||
tenant_id=current_user.tenant_id,
|
||||
window_days=window_days,
|
||||
limit=limit,
|
||||
)
|
||||
@@ -78,8 +83,15 @@ def summarize_risk_observations(
|
||||
summary="查询单据风险观察",
|
||||
description="按报销单 ID 返回该单据关联的风险观察,供单据详情证据链使用。",
|
||||
)
|
||||
def list_claim_risk_observations(claim_id: str, db: DbSession) -> list[RiskObservationRead]:
|
||||
return RiskObservationService(db).list_claim_observations(claim_id)
|
||||
def list_claim_risk_observations(
|
||||
claim_id: str,
|
||||
db: DbSession,
|
||||
current_user: CurrentUser,
|
||||
) -> list[RiskObservationRead]:
|
||||
return RiskObservationService(db).list_claim_observations(
|
||||
claim_id,
|
||||
tenant_id=current_user.tenant_id,
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
@@ -91,8 +103,12 @@ def list_claim_risk_observations(claim_id: str, db: DbSession) -> list[RiskObser
|
||||
def list_execution_log_risk_observations(
|
||||
execution_log_id: str,
|
||||
db: DbSession,
|
||||
current_user: CurrentUser,
|
||||
) -> list[RiskObservationRead]:
|
||||
return RiskObservationService(db).list_execution_log_observations(execution_log_id)
|
||||
return RiskObservationService(db).list_execution_log_observations(
|
||||
execution_log_id,
|
||||
tenant_id=current_user.tenant_id,
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
@@ -110,8 +126,12 @@ def list_execution_log_risk_observations(
|
||||
def get_risk_observation(
|
||||
observation_key_or_id: str,
|
||||
db: DbSession,
|
||||
current_user: CurrentUser,
|
||||
) -> RiskObservationRead:
|
||||
observation = RiskObservationService(db).get_observation(observation_key_or_id)
|
||||
observation = RiskObservationService(db).get_observation(
|
||||
observation_key_or_id,
|
||||
tenant_id=current_user.tenant_id,
|
||||
)
|
||||
if observation is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -136,9 +156,15 @@ def create_risk_observation_feedback(
|
||||
observation_key_or_id: str,
|
||||
payload: RiskObservationFeedbackCreate,
|
||||
db: DbSession,
|
||||
current_user: CurrentUser,
|
||||
) -> RiskObservationFeedbackRead:
|
||||
try:
|
||||
return RiskObservationService(db).create_feedback(observation_key_or_id, payload)
|
||||
return RiskObservationService(db).create_feedback(
|
||||
observation_key_or_id,
|
||||
payload,
|
||||
tenant_id=current_user.tenant_id,
|
||||
actor=current_user.name or current_user.username,
|
||||
)
|
||||
except LookupError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
|
||||
Reference in New Issue
Block a user