This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
HealthSync AI 기본 데이터 모델
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from typing import Optional, Generic, TypeVar, List
|
||||
from enum import Enum
|
||||
|
||||
# Generic 타입 정의
|
||||
T = TypeVar('T')
|
||||
|
||||
class BaseResponse(BaseModel, Generic[T]):
|
||||
"""기본 응답 모델"""
|
||||
success: bool = Field(default=True, description="요청 성공 여부")
|
||||
message: str = Field(default="", description="응답 메시지")
|
||||
data: Optional[T] = Field(default=None, description="응답 데이터")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="응답 시간")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat()
|
||||
}
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
"""에러 응답 모델"""
|
||||
success: bool = Field(default=False, description="요청 성공 여부")
|
||||
error_code: str = Field(..., description="에러 코드")
|
||||
message: str = Field(..., description="에러 메시지")
|
||||
details: Optional[dict] = Field(default=None, description="에러 상세 정보")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="에러 발생 시간")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat()
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# app/models/chat_message.py
|
||||
"""
|
||||
HealthSync AI 채팅 메시지 모델
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
|
||||
class MessageType(str, Enum):
|
||||
"""메시지 타입"""
|
||||
CONSULTATION = "consultation" # 상담
|
||||
CELEBRATION = "celebration" # 축하
|
||||
ENCOURAGEMENT = "encouragement" # 독려
|
||||
|
||||
class ChatMessage(BaseModel):
|
||||
"""채팅 메시지 모델"""
|
||||
message_id: Optional[int] = Field(None, description="메시지 ID")
|
||||
member_serial_number: int = Field(..., description="회원 일련번호")
|
||||
message_type: str = Field(..., max_length=20, description="메시지 타입")
|
||||
message_content: Optional[str] = Field(None, description="메시지 내용")
|
||||
response_content: Optional[str] = Field(None, description="AI 응답 내용")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat()
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
HealthSync AI 공통 모델 (Common Service)
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from typing import Optional, Dict, Any, List
|
||||
from enum import Enum
|
||||
|
||||
class EventType(str, Enum):
|
||||
"""이벤트 타입"""
|
||||
USER_REGISTERED = "user_registered"
|
||||
HEALTH_DATA_SYNCED = "health_data_synced"
|
||||
GOAL_SETUP = "goal_setup"
|
||||
MISSION_COMPLETED = "mission_completed"
|
||||
AI_ANALYSIS_COMPLETED = "ai_analysis_completed"
|
||||
NOTIFICATION_SENT = "notification_sent"
|
||||
|
||||
class EventStore(BaseModel):
|
||||
"""이벤트 저장소"""
|
||||
event_id: int = Field(..., description="이벤트 ID")
|
||||
aggregate_id: str = Field(..., max_length=36, description="집계 ID")
|
||||
event_type: str = Field(..., max_length=100, description="이벤트 타입")
|
||||
event_data: Optional[str] = Field(None, description="이벤트 데이터")
|
||||
member_serial_number: Optional[int] = Field(None, description="회원 일련번호")
|
||||
service_name: Optional[str] = Field(None, max_length=50, description="서비스명")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class SystemConfig(BaseModel):
|
||||
"""시스템 설정"""
|
||||
config_id: int = Field(..., description="설정 ID")
|
||||
config_key: str = Field(..., max_length=200, description="설정 키")
|
||||
config_value: Optional[str] = Field(None, description="설정 값")
|
||||
description: Optional[str] = Field(None, max_length=500, description="설명")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class APIResponse(BaseModel):
|
||||
"""표준 API 응답"""
|
||||
success: bool = Field(True, description="성공 여부")
|
||||
message: str = Field(..., description="응답 메시지")
|
||||
data: Optional[Dict[str, Any]] = Field(None, description="응답 데이터")
|
||||
timestamp: datetime = Field(default_factory=datetime.now, description="응답 시각")
|
||||
|
||||
class Config:
|
||||
json_encoders = {
|
||||
datetime: lambda v: v.isoformat()
|
||||
}
|
||||
|
||||
class PaginatedResponse(BaseModel):
|
||||
"""페이지네이션 응답"""
|
||||
items: List[Any] = Field(..., description="아이템 목록")
|
||||
total: int = Field(..., description="전체 수")
|
||||
page: int = Field(..., description="현재 페이지")
|
||||
size: int = Field(..., description="페이지 크기")
|
||||
pages: int = Field(..., description="전체 페이지 수")
|
||||
has_next: bool = Field(..., description="다음 페이지 존재 여부")
|
||||
has_prev: bool = Field(..., description="이전 페이지 존재 여부")
|
||||
@@ -0,0 +1,113 @@
|
||||
"""
|
||||
HealthSync AI 목표 관리 관련 모델 (Goal Service)
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime, date
|
||||
from typing import Optional, List, Dict, Any
|
||||
from enum import Enum
|
||||
|
||||
class MissionStatus(str, Enum):
|
||||
"""미션 상태"""
|
||||
ACTIVE = "active"
|
||||
COMPLETED = "completed"
|
||||
PAUSED = "paused"
|
||||
CANCELLED = "cancelled"
|
||||
|
||||
class GoalType(str, Enum):
|
||||
"""목표 타입"""
|
||||
DAILY = "daily"
|
||||
WEEKLY = "weekly"
|
||||
MONTHLY = "monthly"
|
||||
|
||||
class DifficultyLevel(str, Enum):
|
||||
"""난이도 레벨"""
|
||||
BEGINNER = "beginner"
|
||||
INTERMEDIATE = "intermediate"
|
||||
ADVANCED = "advanced"
|
||||
|
||||
class MissionCategory(str, Enum):
|
||||
"""미션 카테고리"""
|
||||
EXERCISE = "exercise"
|
||||
NUTRITION = "nutrition"
|
||||
MENTAL_HEALTH = "mental_health"
|
||||
HYDRATION = "hydration"
|
||||
SLEEP = "sleep"
|
||||
STRESS_MANAGEMENT = "stress_management"
|
||||
|
||||
class UserMissionGoal(BaseModel):
|
||||
"""사용자 미션 목표"""
|
||||
mission_id: int = Field(..., description="미션 ID")
|
||||
member_serial_number: int = Field(..., description="회원 일련번호")
|
||||
performance_date: date = Field(..., description="수행 날짜")
|
||||
mission_name: str = Field(..., max_length=100, description="미션명")
|
||||
mission_description: Optional[str] = Field(None, max_length=200, description="미션 설명")
|
||||
daily_target_count: int = Field(..., description="일일 목표 횟수")
|
||||
is_active: bool = Field(True, description="활성 상태")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class MissionCompletionHistory(BaseModel):
|
||||
"""미션 완료 이력"""
|
||||
completion_id: int = Field(..., description="완료 ID")
|
||||
mission_id: int = Field(..., description="미션 ID")
|
||||
member_serial_number: int = Field(..., description="회원 일련번호")
|
||||
completion_date: date = Field(..., description="완료 날짜")
|
||||
daily_target_count: int = Field(..., description="일일 목표 횟수")
|
||||
daily_completed_count: int = Field(..., description="일일 완료 횟수")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class MissionSelectionRequest(BaseModel):
|
||||
"""미션 선택 요청"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
selected_mission_ids: List[str] = Field(..., description="선택된 미션 ID 목록")
|
||||
|
||||
class GoalSetupResponse(BaseModel):
|
||||
"""목표 설정 응답"""
|
||||
goal_id: str = Field(..., description="목표 ID")
|
||||
selected_missions: List[Dict[str, Any]] = Field(..., description="선택된 미션 목록")
|
||||
message: str = Field(..., description="응답 메시지")
|
||||
setup_completed_at: datetime = Field(..., description="설정 완료 일시")
|
||||
|
||||
class ActiveMissionsResponse(BaseModel):
|
||||
"""활성 미션 응답"""
|
||||
daily_missions: List[Dict[str, Any]] = Field(..., description="일일 미션 목록")
|
||||
total_missions: int = Field(..., description="전체 미션 수")
|
||||
today_completed_count: int = Field(..., description="오늘 완료 수")
|
||||
completion_rate: float = Field(..., description="완료율")
|
||||
|
||||
class MissionCompleteRequest(BaseModel):
|
||||
"""미션 완료 요청"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
completed: bool = Field(..., description="완료 여부")
|
||||
completed_at: datetime = Field(..., description="완료 일시")
|
||||
notes: Optional[str] = Field(None, description="메모")
|
||||
|
||||
class MissionCompleteResponse(BaseModel):
|
||||
"""미션 완료 응답"""
|
||||
message: str = Field(..., description="응답 메시지")
|
||||
status: str = Field(..., description="상태")
|
||||
achievement_message: str = Field(..., description="성취 메시지")
|
||||
new_streak_days: int = Field(..., description="새로운 연속 달성 일수")
|
||||
total_completed_count: int = Field(..., description="전체 완료 수")
|
||||
earned_points: int = Field(..., description="획득 포인트")
|
||||
|
||||
class MissionHistoryResponse(BaseModel):
|
||||
"""미션 이력 응답"""
|
||||
total_achievement_rate: float = Field(..., description="전체 달성률")
|
||||
period_achievement_rate: float = Field(..., description="기간 달성률")
|
||||
best_streak: int = Field(..., description="최고 연속 달성")
|
||||
mission_stats: List[Dict[str, Any]] = Field(..., description="미션별 통계")
|
||||
chart_data: Optional[Dict[str, Any]] = Field(None, description="차트 데이터")
|
||||
period: Dict[str, str] = Field(..., description="조회 기간")
|
||||
insights: List[str] = Field(..., description="인사이트")
|
||||
|
||||
class MissionResetRequest(BaseModel):
|
||||
"""미션 재설정 요청"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
reason: str = Field(..., description="재설정 사유")
|
||||
current_mission_ids: List[str] = Field(..., description="현재 미션 ID 목록")
|
||||
|
||||
class MissionResetResponse(BaseModel):
|
||||
"""미션 재설정 응답"""
|
||||
message: str = Field(..., description="응답 메시지")
|
||||
new_recommendations: List[Dict[str, Any]] = Field(..., description="새로운 추천 미션")
|
||||
reset_completed_at: datetime = Field(..., description="재설정 완료 일시")
|
||||
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
HealthSync AI 건강 관련 모델 (Health Service)
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime, date
|
||||
from typing import Optional, List, Dict, Any
|
||||
from enum import Enum
|
||||
from decimal import Decimal
|
||||
|
||||
class RiskLevel(str, Enum):
|
||||
"""위험도 레벨"""
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
CRITICAL = "critical"
|
||||
|
||||
class RangeStatus(str, Enum):
|
||||
"""정상치 범위 상태"""
|
||||
NORMAL = "normal"
|
||||
WARNING = "warning"
|
||||
DANGER = "danger"
|
||||
|
||||
class UploadStatus(str, Enum):
|
||||
"""업로드 상태"""
|
||||
PENDING = "pending"
|
||||
SUCCESS = "success"
|
||||
FAILED = "failed"
|
||||
|
||||
class HealthCheckupRaw(BaseModel):
|
||||
"""건강검진 원천 데이터"""
|
||||
raw_id: int = Field(..., description="원본 ID")
|
||||
reference_year: int = Field(..., description="기준 년도")
|
||||
birth_date: date = Field(..., description="생년월일")
|
||||
name: str = Field(..., max_length=50, description="이름")
|
||||
region_code: Optional[int] = Field(None, description="지역 코드")
|
||||
gender_code: Optional[int] = Field(None, description="성별 코드")
|
||||
age: Optional[int] = Field(None, description="나이")
|
||||
height: Optional[int] = Field(None, description="신장(cm)")
|
||||
weight: Optional[int] = Field(None, description="체중(kg)")
|
||||
waist_circumference: Optional[int] = Field(None, description="허리둘레(cm)")
|
||||
visual_acuity_left: Optional[Decimal] = Field(None, description="좌측 시력")
|
||||
visual_acuity_right: Optional[Decimal] = Field(None, description="우측 시력")
|
||||
hearing_left: Optional[int] = Field(None, description="좌측 청력")
|
||||
hearing_right: Optional[int] = Field(None, description="우측 청력")
|
||||
systolic_bp: Optional[int] = Field(None, description="수축기 혈압")
|
||||
diastolic_bp: Optional[int] = Field(None, description="이완기 혈압")
|
||||
fasting_glucose: Optional[int] = Field(None, description="공복혈당")
|
||||
total_cholesterol: Optional[int] = Field(None, description="총 콜레스테롤")
|
||||
triglyceride: Optional[int] = Field(None, description="중성지방")
|
||||
hdl_cholesterol: Optional[int] = Field(None, description="HDL 콜레스테롤")
|
||||
ldl_cholesterol: Optional[int] = Field(None, description="LDL 콜레스테롤")
|
||||
hemoglobin: Optional[Decimal] = Field(None, description="혈색소")
|
||||
urine_protein: Optional[int] = Field(None, description="요단백")
|
||||
serum_creatinine: Optional[Decimal] = Field(None, description="혈청크레아티닌")
|
||||
ast: Optional[int] = Field(None, description="AST")
|
||||
alt: Optional[int] = Field(None, description="ALT")
|
||||
gamma_gtp: Optional[int] = Field(None, description="감마지티피")
|
||||
smoking_status: Optional[int] = Field(None, description="흡연 상태")
|
||||
drinking_status: Optional[int] = Field(None, description="음주 상태")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class HealthCheckup(BaseModel):
|
||||
"""처리된 건강검진 데이터"""
|
||||
checkup_id: int = Field(..., description="건강검진 ID")
|
||||
member_serial_number: int = Field(..., description="회원 일련번호")
|
||||
raw_id: int = Field(..., description="원본 데이터 ID")
|
||||
reference_year: int = Field(..., description="기준 년도")
|
||||
age: Optional[int] = Field(None, description="나이")
|
||||
height: Optional[int] = Field(None, description="신장(cm)")
|
||||
weight: Optional[int] = Field(None, description="체중(kg)")
|
||||
bmi: Optional[Decimal] = Field(None, description="BMI")
|
||||
waist_circumference: Optional[int] = Field(None, description="허리둘레(cm)")
|
||||
visual_acuity_left: Optional[Decimal] = Field(None, description="좌측 시력")
|
||||
visual_acuity_right: Optional[Decimal] = Field(None, description="우측 시력")
|
||||
hearing_left: Optional[int] = Field(None, description="좌측 청력")
|
||||
hearing_right: Optional[int] = Field(None, description="우측 청력")
|
||||
systolic_bp: Optional[int] = Field(None, description="수축기 혈압")
|
||||
diastolic_bp: Optional[int] = Field(None, description="이완기 혈압")
|
||||
fasting_glucose: Optional[int] = Field(None, description="공복혈당")
|
||||
total_cholesterol: Optional[int] = Field(None, description="총 콜레스테롤")
|
||||
triglyceride: Optional[int] = Field(None, description="중성지방")
|
||||
hdl_cholesterol: Optional[int] = Field(None, description="HDL 콜레스테롤")
|
||||
ldl_cholesterol: Optional[int] = Field(None, description="LDL 콜레스테롤")
|
||||
hemoglobin: Optional[Decimal] = Field(None, description="혈색소")
|
||||
urine_protein: Optional[int] = Field(None, description="요단백")
|
||||
serum_creatinine: Optional[Decimal] = Field(None, description="혈청크레아티닌")
|
||||
ast: Optional[int] = Field(None, description="AST")
|
||||
alt: Optional[int] = Field(None, description="ALT")
|
||||
gamma_gtp: Optional[int] = Field(None, description="감마지티피")
|
||||
smoking_status: Optional[int] = Field(None, description="흡연 상태")
|
||||
drinking_status: Optional[int] = Field(None, description="음주 상태")
|
||||
processed_at: Optional[datetime] = Field(None, description="처리일시")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class HealthNormalRange(BaseModel):
|
||||
"""건강 정상치 기준"""
|
||||
range_id: int = Field(..., description="범위 ID")
|
||||
health_item_code: Optional[str] = Field(None, max_length=25, description="건강항목 코드")
|
||||
health_item_name: Optional[str] = Field(None, max_length=30, description="건강항목명")
|
||||
gender_code: Optional[int] = Field(None, description="성별 코드 (0:공통, 1:남성, 2:여성)")
|
||||
unit: Optional[str] = Field(None, max_length=10, description="단위")
|
||||
normal_range: Optional[str] = Field(None, max_length=15, description="정상 범위")
|
||||
warning_range: Optional[str] = Field(None, max_length=15, description="주의 범위")
|
||||
danger_range: Optional[str] = Field(None, max_length=15, description="위험 범위")
|
||||
note: Optional[str] = Field(None, max_length=50, description="비고")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class HealthSyncResponse(BaseModel):
|
||||
"""건강검진 연동 응답"""
|
||||
sync_status: str = Field(..., description="동기화 상태")
|
||||
message: str = Field(..., description="응답 메시지")
|
||||
is_ready_for_analysis: bool = Field(..., description="분석 준비 여부")
|
||||
synced_at: datetime = Field(..., description="동기화 일시")
|
||||
|
||||
class HealthHistoryResponse(BaseModel):
|
||||
"""건강검진 이력 응답"""
|
||||
user_info: Dict[str, Any] = Field(..., description="사용자 정보")
|
||||
checkup_records: List[Dict[str, Any]] = Field(..., description="건강검진 기록")
|
||||
chart_data: Optional[Dict[str, Any]] = Field(None, description="차트 데이터")
|
||||
normal_range_reference: Optional[Dict[str, Any]] = Field(None, description="정상치 기준")
|
||||
|
||||
class CheckupFileRequest(BaseModel):
|
||||
"""건강검진 파일 업로드 요청"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
file_name: str = Field(..., description="파일명")
|
||||
file_type: str = Field(..., description="파일 형식")
|
||||
file_content: str = Field(..., description="파일 내용")
|
||||
|
||||
class FileUploadResponse(BaseModel):
|
||||
"""파일 업로드 응답"""
|
||||
file_id: str = Field(..., description="파일 ID")
|
||||
upload_url: str = Field(..., description="업로드 URL")
|
||||
status: str = Field(..., description="업로드 상태")
|
||||
message: str = Field(..., description="응답 메시지")
|
||||
@@ -0,0 +1,142 @@
|
||||
"""
|
||||
HealthSync AI 지능형 서비스 관련 모델 (Intelligence Service)
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
from typing import Optional, List, Dict, Any
|
||||
from enum import Enum
|
||||
|
||||
class MessageRole(str, Enum):
|
||||
"""메시지 역할"""
|
||||
USER = "user"
|
||||
ASSISTANT = "assistant"
|
||||
SYSTEM = "system"
|
||||
|
||||
class MessageType(str, Enum):
|
||||
"""메시지 타입"""
|
||||
QUESTION = "question"
|
||||
ANSWER = "answer"
|
||||
NOTIFICATION = "notification"
|
||||
CELEBRATION = "celebration"
|
||||
ENCOURAGEMENT = "encouragement"
|
||||
|
||||
class SenderType(str, Enum):
|
||||
"""발신자 타입"""
|
||||
USER = "user"
|
||||
AI = "ai"
|
||||
SYSTEM = "system"
|
||||
|
||||
class NotificationType(str, Enum):
|
||||
"""알림 타입"""
|
||||
DAILY_ENCOURAGEMENT = "daily_encouragement"
|
||||
WEEKLY_SUMMARY = "weekly_summary"
|
||||
MILESTONE_CELEBRATION = "milestone_celebration"
|
||||
HEALTH_REMINDER = "health_reminder"
|
||||
MISSION_REMINDER = "mission_reminder"
|
||||
|
||||
class EncouragementLevel(str, Enum):
|
||||
"""격려 레벨"""
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
INTENSIVE = "intensive"
|
||||
|
||||
class ChatMessage(BaseModel):
|
||||
"""채팅 메시지"""
|
||||
message_id: int = Field(..., description="메시지 ID")
|
||||
member_serial_number: int = Field(..., description="회원 일련번호")
|
||||
message_type: str = Field(..., max_length=20, description="메시지 타입")
|
||||
message_content: Optional[str] = Field(None, description="메시지 내용")
|
||||
response_content: Optional[str] = Field(None, description="응답 내용")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
|
||||
class HealthDiagnosisResponse(BaseModel):
|
||||
"""건강 진단 응답"""
|
||||
three_sentence_summary: List[str] = Field(..., description="3줄 요약")
|
||||
health_score: int = Field(..., description="건강 점수")
|
||||
risk_level: str = Field(..., description="위험 레벨")
|
||||
occupation_considerations: str = Field(..., description="직업별 고려사항")
|
||||
analysis_timestamp: datetime = Field(..., description="분석 시각")
|
||||
confidence_score: float = Field(..., description="신뢰도 점수")
|
||||
|
||||
class RecommendedMission(BaseModel):
|
||||
"""추천 미션"""
|
||||
mission_id: str = Field(..., description="미션 ID")
|
||||
title: str = Field(..., description="미션 제목")
|
||||
description: str = Field(..., description="미션 설명")
|
||||
category: str = Field(..., description="미션 카테고리")
|
||||
difficulty: str = Field(..., description="난이도")
|
||||
health_benefit: str = Field(..., description="건강상 이점")
|
||||
occupation_relevance: str = Field(..., description="직업 연관성")
|
||||
estimated_time_minutes: int = Field(..., description="예상 소요 시간(분)")
|
||||
|
||||
class MissionRecommendationResponse(BaseModel):
|
||||
"""미션 추천 응답"""
|
||||
missions: List[RecommendedMission] = Field(..., description="추천 미션 목록")
|
||||
recommendation_reason: str = Field(..., description="추천 사유")
|
||||
total_recommended: int = Field(..., description="전체 추천 수")
|
||||
|
||||
class ChatRequest(BaseModel):
|
||||
"""채팅 요청"""
|
||||
message: str = Field(..., min_length=1, max_length=500, description="메시지 내용")
|
||||
session_id: str = Field(..., description="세션 ID")
|
||||
context: Optional[str] = Field(None, description="컨텍스트")
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
|
||||
class ChatResponse(BaseModel):
|
||||
"""채팅 응답"""
|
||||
response: str = Field(..., description="AI 응답")
|
||||
session_id: str = Field(..., description="세션 ID")
|
||||
timestamp: datetime = Field(..., description="응답 시각")
|
||||
suggested_questions: List[str] = Field(..., description="추천 질문")
|
||||
response_type: str = Field(..., description="응답 타입")
|
||||
|
||||
class ChatHistoryResponse(BaseModel):
|
||||
"""채팅 이력 응답"""
|
||||
session_id: str = Field(..., description="세션 ID")
|
||||
messages: List[Dict[str, Any]] = Field(..., description="메시지 목록")
|
||||
total_message_count: int = Field(..., description="전체 메시지 수")
|
||||
cache_expiration: Optional[str] = Field(None, description="캐시 만료 시간")
|
||||
|
||||
class CelebrationRequest(BaseModel):
|
||||
"""축하 메시지 요청"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
mission_id: str = Field(..., description="미션 ID")
|
||||
achievement_type: str = Field(..., description="성취 타입")
|
||||
consecutive_days: int = Field(..., description="연속 달성 일수")
|
||||
total_achievements: int = Field(..., description="전체 성취 수")
|
||||
|
||||
class CelebrationResponse(BaseModel):
|
||||
"""축하 메시지 응답"""
|
||||
congrats_message: str = Field(..., description="축하 메시지")
|
||||
achievement_badge: str = Field(..., description="성취 배지")
|
||||
health_benefit: str = Field(..., description="건강상 이점")
|
||||
next_milestone: str = Field(..., description="다음 마일스톤")
|
||||
encouragement_level: str = Field(..., description="격려 레벨")
|
||||
visual_effect: str = Field(..., description="시각 효과")
|
||||
|
||||
class EncouragementRequest(BaseModel):
|
||||
"""독려 메시지 요청"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
missions_status: List[Dict[str, Any]] = Field(..., description="미션 상태 목록")
|
||||
|
||||
class EncouragementResponse(BaseModel):
|
||||
"""독려 메시지 응답"""
|
||||
message: str = Field(..., description="독려 메시지")
|
||||
motivation_type: str = Field(..., description="동기부여 타입")
|
||||
timing: str = Field(..., description="타이밍")
|
||||
personalized_tip: str = Field(..., description="개인화된 팁")
|
||||
priority: str = Field(..., description="우선순위")
|
||||
|
||||
class BatchNotificationRequest(BaseModel):
|
||||
"""배치 알림 요청"""
|
||||
trigger_time: datetime = Field(..., description="트리거 시간")
|
||||
target_users: List[str] = Field(..., description="대상 사용자 목록")
|
||||
notification_type: str = Field(..., description="알림 타입")
|
||||
|
||||
class BatchNotificationResponse(BaseModel):
|
||||
"""배치 알림 응답"""
|
||||
processed_count: int = Field(..., description="처리된 수")
|
||||
success_count: int = Field(..., description="성공 수")
|
||||
failed_count: int = Field(..., description="실패 수")
|
||||
next_scheduled_time: Optional[datetime] = Field(None, description="다음 예약 시간")
|
||||
@@ -0,0 +1,59 @@
|
||||
"""
|
||||
HealthSync AI 사용자 관련 모델 (User Service)
|
||||
"""
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime, date
|
||||
from typing import Optional
|
||||
from enum import Enum
|
||||
|
||||
class UserStatus(str, Enum):
|
||||
"""사용자 상태"""
|
||||
ACTIVE = "active"
|
||||
INACTIVE = "inactive"
|
||||
SUSPENDED = "suspended"
|
||||
|
||||
class OccupationType(BaseModel):
|
||||
"""직업 유형 모델"""
|
||||
occupation_code: str = Field(..., max_length=20, description="직업 코드")
|
||||
occupation_name: str = Field(..., max_length=100, description="직업명")
|
||||
category: Optional[str] = Field(None, max_length=50, description="직업 카테고리")
|
||||
|
||||
class User(BaseModel):
|
||||
"""사용자 기본 모델"""
|
||||
member_serial_number: int = Field(..., description="회원 일련번호")
|
||||
google_id: str = Field(..., max_length=255, description="구글 ID")
|
||||
name: str = Field(..., max_length=100, description="사용자 이름")
|
||||
birth_date: date = Field(..., description="생년월일")
|
||||
occupation: Optional[str] = Field(None, max_length=50, description="직업")
|
||||
created_at: datetime = Field(default_factory=datetime.now, description="생성일시")
|
||||
updated_at: datetime = Field(default_factory=datetime.now, description="수정일시")
|
||||
last_login_at: Optional[datetime] = Field(None, description="마지막 로그인")
|
||||
|
||||
class UserRegistrationRequest(BaseModel):
|
||||
"""사용자 등록 요청"""
|
||||
name: str = Field(..., min_length=1, max_length=100, description="사용자 이름")
|
||||
birth_date: date = Field(..., description="생년월일")
|
||||
occupation: Optional[str] = Field(None, max_length=50, description="직업")
|
||||
|
||||
class UserRegistrationResponse(BaseModel):
|
||||
"""사용자 등록 응답"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
message: str = Field(..., description="등록 결과 메시지")
|
||||
status: str = Field(..., description="등록 상태")
|
||||
|
||||
class UserProfileResponse(BaseModel):
|
||||
"""사용자 프로필 응답"""
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
name: str = Field(..., description="사용자 이름")
|
||||
age: int = Field(..., description="나이")
|
||||
occupation: Optional[str] = Field(None, description="직업")
|
||||
registered_at: datetime = Field(..., description="등록일시")
|
||||
last_login_at: Optional[datetime] = Field(None, description="마지막 로그인")
|
||||
|
||||
class LoginResponse(BaseModel):
|
||||
"""로그인 응답"""
|
||||
access_token: str = Field(..., description="액세스 토큰")
|
||||
refresh_token: str = Field(..., description="리프레시 토큰")
|
||||
is_new_user: bool = Field(..., description="신규 사용자 여부")
|
||||
user_id: int = Field(..., description="사용자 ID")
|
||||
expires_in: int = Field(..., description="토큰 만료 시간(초)")
|
||||
Reference in New Issue
Block a user