평가 및 화면 구조 정리

This commit is contained in:
Yun Chan 2026-06-28 21:46:22 +09:00
parent 1248ae8ca4
commit 391639c1de
44 changed files with 5816 additions and 4501 deletions

View file

@ -21,6 +21,9 @@ from .services import session_metrics
from .store import InProcSession, TurnRecord
StageLabel = Literal["라포", "탐색", "개입", "정리"]
WorksheetSpeaker = Literal["learner", "client"]
WorksheetItemSpec = tuple[str, str, list[str], WorksheetSpeaker | None]
WorksheetSectionSpec = tuple[str, str, list[WorksheetItemSpec]]
LEARNER_VISIBLE_AI_ROLE = "counselor"
_PHASE_KEY_BY_LABEL = {
@ -259,6 +262,68 @@ class ReviewCaseWorksheetSaveRequest(BaseModel):
limitations: list[str] = Field(default_factory=list)
CASE_WORKSHEET_SECTION_SPECS: list[WorksheetSectionSpec] = [
(
"exploration_11",
"탐색 11항목",
[
("presenting_complaint", "주호소", ["힘들", "문제", "걱정", "불안", "우울", "스트레스", "관계"], "client"),
("trigger_context", "계기·상황", ["언제", "상황", "최근", "계기", ""], "client"),
("emotion", "정서", ["불안", "우울", "", "슬프", "답답", "무섭", "외롭", "걱정"], "client"),
("cognition", "생각", ["생각", "느낌", "해야", "", "실패", "의미"], "client"),
("behavior", "행동", ["피하", "", "", "", "", "연락", "공부", ""], "client"),
("body", "신체·수면", ["", "식욕", "", "두통", "심장", "", "피곤"], "client"),
("relationship", "관계", ["친구", "가족", "부모", "엄마", "아빠", "교수", "사람", "관계"], "client"),
("resources", "자원", ["도움", "지지", "친구", "상담", "선생님", "가족"], "client"),
("risk", "위험 신호", ["", "자살", "해치", "사라지고", "끝내", "위험"], "client"),
("motivation", "변화동기", ["", "바라", "변화", "해보고", ""], None),
("first_goal", "상담 목표 초안", ["목표", "계획", "다음", "해볼", "원하"], "learner"),
],
),
(
"five_domains",
"호소 5영역",
[
("domain_emotion", "정서", ["불안", "우울", "", "슬프", "답답", "외롭"], "client"),
("domain_cognition", "인지", ["생각", "걱정", "실패", "", "의미"], "client"),
("domain_behavior", "행동", ["피하", "연락", "공부", "", ""], "client"),
("domain_relationship", "대인관계", ["친구", "가족", "사람", "관계", "부모"], "client"),
("domain_body", "신체", ["", "식욕", "", "두통", "피곤", ""], "client"),
],
),
(
"cognitive_triad_emotions",
"인지삼제·1/2차 감정",
[
("triad_self", "자기", ["나는", "내가", "나 자신", "스스로"], "client"),
("triad_world", "타인·세계", ["사람", "세상", "학교", "가족", "친구"], "client"),
("triad_future", "미래", ["앞으로", "미래", "계속", "나중"], "client"),
("primary_emotion", "1차 감정", ["불안", "슬프", "무섭", "외롭", "걱정"], "client"),
("secondary_emotion", "2차 감정", ["", "짜증", "수치", "죄책", "부끄"], "client"),
],
),
(
"protective_barrier_quadrants",
"보호·방해 4사분면",
[
("internal_protective", "내적 보호요인", ["해보고", "버텼", "노력", "", "견뎠"], None),
("internal_barrier", "내적 방해요인", ["", "두려", "불안", "회피", "걱정"], "client"),
("external_protective", "외적 보호요인", ["친구", "가족", "상담", "교수", "도움"], "client"),
("external_barrier", "외적 방해요인", ["갈등", "압박", "비난", "스트레스", "혼자"], "client"),
],
),
(
"biopsychosocial_goals",
"생물·심리·사회 목표",
[
("bio_goal", "생물", ["", "식사", "운동", "", "피곤"], "client"),
("psy_goal", "심리", ["생각", "감정", "불안", "연습", "조절"], None),
("social_goal", "사회", ["관계", "대화", "연락", "도움", "친구"], None),
],
),
]
class SessionTeacherReviewStatus(BaseModel):
status: Literal["pending", "viewed", "closed"] = "pending"
note: str = ""
@ -824,7 +889,7 @@ def _worksheet_item(
def _worksheet_section(
key: str,
title: str,
specs: list[tuple[str, str, list[str], Literal["learner", "client"] | None]],
specs: list[WorksheetItemSpec],
turns: list[ReviewTurn],
fallback_client: ReviewTurn | None,
fallback_learner: ReviewTurn | None,
@ -845,6 +910,13 @@ def _worksheet_section(
return ReviewWorksheetSection(key=key, title=title, items=items)
def case_worksheet_template_item_keys() -> dict[str, set[str]]:
return {
section_key: {item_key for item_key, _, _, _ in item_specs}
for section_key, _, item_specs in CASE_WORKSHEET_SECTION_SPECS
}
def case_worksheet_from_turns(turns: list[ReviewTurn]) -> ReviewCaseWorksheet:
if not turns:
return ReviewCaseWorksheet(
@ -855,68 +927,6 @@ def case_worksheet_from_turns(turns: list[ReviewTurn]) -> ReviewCaseWorksheet:
fallback_client = next((turn for turn in turns if turn.speaker == "client"), None)
fallback_learner = next((turn for turn in turns if turn.speaker == "learner"), None)
section_specs: list[
tuple[str, str, list[tuple[str, str, list[str], Literal["learner", "client"] | None]]]
] = [
(
"exploration_11",
"탐색 11항목",
[
("presenting_complaint", "주호소", ["힘들", "문제", "걱정", "불안", "우울", "스트레스", "관계"], "client"),
("trigger_context", "계기·상황", ["언제", "상황", "최근", "계기", ""], "client"),
("emotion", "정서", ["불안", "우울", "", "슬프", "답답", "무섭", "외롭", "걱정"], "client"),
("cognition", "생각", ["생각", "느낌", "해야", "", "실패", "의미"], "client"),
("behavior", "행동", ["피하", "", "", "", "", "연락", "공부", ""], "client"),
("body", "신체·수면", ["", "식욕", "", "두통", "심장", "", "피곤"], "client"),
("relationship", "관계", ["친구", "가족", "부모", "엄마", "아빠", "교수", "사람", "관계"], "client"),
("resources", "자원", ["도움", "지지", "친구", "상담", "선생님", "가족"], "client"),
("risk", "위험 신호", ["", "자살", "해치", "사라지고", "끝내", "위험"], "client"),
("motivation", "변화동기", ["", "바라", "변화", "해보고", ""], None),
("first_goal", "상담 목표 초안", ["목표", "계획", "다음", "해볼", "원하"], "learner"),
],
),
(
"five_domains",
"호소 5영역",
[
("domain_emotion", "정서", ["불안", "우울", "", "슬프", "답답", "외롭"], "client"),
("domain_cognition", "인지", ["생각", "걱정", "실패", "", "의미"], "client"),
("domain_behavior", "행동", ["피하", "연락", "공부", "", ""], "client"),
("domain_relationship", "대인관계", ["친구", "가족", "사람", "관계", "부모"], "client"),
("domain_body", "신체", ["", "식욕", "", "두통", "피곤", ""], "client"),
],
),
(
"cognitive_triad_emotions",
"인지삼제·1/2차 감정",
[
("triad_self", "자기", ["나는", "내가", "나 자신", "스스로"], "client"),
("triad_world", "타인·세계", ["사람", "세상", "학교", "가족", "친구"], "client"),
("triad_future", "미래", ["앞으로", "미래", "계속", "나중"], "client"),
("primary_emotion", "1차 감정", ["불안", "슬프", "무섭", "외롭", "걱정"], "client"),
("secondary_emotion", "2차 감정", ["", "짜증", "수치", "죄책", "부끄"], "client"),
],
),
(
"protective_barrier_quadrants",
"보호·방해 4사분면",
[
("internal_protective", "내적 보호요인", ["해보고", "버텼", "노력", "", "견뎠"], None),
("internal_barrier", "내적 방해요인", ["", "두려", "불안", "회피", "걱정"], "client"),
("external_protective", "외적 보호요인", ["친구", "가족", "상담", "교수", "도움"], "client"),
("external_barrier", "외적 방해요인", ["갈등", "압박", "비난", "스트레스", "혼자"], "client"),
],
),
(
"biopsychosocial_goals",
"생물·심리·사회 목표",
[
("bio_goal", "생물", ["", "식사", "운동", "", "피곤"], "client"),
("psy_goal", "심리", ["생각", "감정", "불안", "연습", "조절"], None),
("social_goal", "사회", ["관계", "대화", "연락", "도움", "친구"], None),
],
),
]
sections = [
_worksheet_section(
@ -927,7 +937,7 @@ def case_worksheet_from_turns(turns: list[ReviewTurn]) -> ReviewCaseWorksheet:
fallback_client,
fallback_learner,
)
for key, title, specs in section_specs
for key, title, specs in CASE_WORKSHEET_SECTION_SPECS
]
return ReviewCaseWorksheet(
status="draft_from_transcript",