64 lines
2.2 KiB
Python
64 lines
2.2 KiB
Python
"""风评域仓储:风评记录 + 客户画像(画像主键为 customer_id)。"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import date
|
|
|
|
from sqlalchemy import select
|
|
|
|
from model.fin_customer_profile import FinCustomerProfile
|
|
from model.fin_risk_assessment import FinRiskAssessment
|
|
from repositories.base import BaseRepository
|
|
|
|
|
|
class RiskAssessmentRepo(BaseRepository):
|
|
model = FinRiskAssessment
|
|
|
|
async def get_current_by_customer(self, customer_id: int) -> FinRiskAssessment | None:
|
|
"""Return the latest currently valid risk assessment for a customer."""
|
|
return await self.db.scalar(
|
|
select(FinRiskAssessment)
|
|
.where(
|
|
FinRiskAssessment.customer_id == customer_id,
|
|
FinRiskAssessment.valid_until >= date.today(),
|
|
)
|
|
.order_by(
|
|
FinRiskAssessment.assessment_date.desc(),
|
|
FinRiskAssessment.id.desc(),
|
|
)
|
|
.limit(1)
|
|
)
|
|
|
|
|
|
class CustomerProfileRepo(BaseRepository):
|
|
"""客户画像仓储。注意:主键是 customer_id 而非 id,不适用基类 get(pk)。"""
|
|
|
|
model = FinCustomerProfile
|
|
|
|
async def get_by_customer(self, customer_id: int) -> FinCustomerProfile | None:
|
|
return await self.db.scalar(
|
|
select(FinCustomerProfile).where(
|
|
FinCustomerProfile.customer_id == customer_id
|
|
)
|
|
)
|
|
|
|
async def upsert_risk(
|
|
self, customer_id: int, risk_level: str, risk_score: int
|
|
) -> FinCustomerProfile:
|
|
"""回写风险等级与评分:无画像则初始化,有则更新并递增画像版本号。"""
|
|
profile = await self.get_by_customer(customer_id)
|
|
if profile is None:
|
|
profile = FinCustomerProfile(
|
|
customer_id=customer_id,
|
|
risk_level=risk_level,
|
|
risk_score=risk_score,
|
|
profile_version=1,
|
|
)
|
|
self.db.add(profile)
|
|
else:
|
|
profile.risk_level = risk_level
|
|
profile.risk_score = risk_score
|
|
profile.profile_version = (profile.profile_version or 0) + 1
|
|
await self.db.commit()
|
|
await self.db.refresh(profile)
|
|
return profile
|