# backend/app/seed_calendar.py — cal-data.js 이식 import json from sqlmodel import Session from .models import Calendar, CalEvent, FocusBlock, Meeting, MeetingAction, MeetPhase # ---- 캘린더 카테고리 (cal-data.js: cals) ---- CALS = [ ("work", "업무", "blue", True, 0), ("meeting", "미팅", "amber", True, 1), ("personal", "개인", "violet", True, 2), ("team", "팀", "green", True, 3), ("health", "건강", "coral", True, 4), ] # ---- 이벤트 (cal-data.js: events) — (id, day, start, end, title, cal, loc, note, soon, people) ---- EVENTS = [ ("e1", 7, "10:00", "11:00", "모닝 러닝 5km", "health", "한강공원", "", False, ""), ("e2", 7, "15:00", "16:30", "독서모임 — 몰입", "personal", "북카페", "", False, ""), ("e3", 8, "09:30", "09:45", "팀 데일리 스탠드업", "team", "Zoom", "", False, ""), ("e4", 8, "11:00", "11:45", "디자인 리뷰 — 온보딩 플로우", "work", "회의실 B", "", False, ""), ("e5", 8, "13:00", "13:30", "점심 — 현우님", "personal", "1층 식당", "", False, ""), ( "e6", 8, "14:00", "15:00", "분기 전략 미팅", "meeting", "대회의실", "지난 회의 액션 4/5 완료 · 리텐션 +6%p · 예산 재배분 안건", True, "대표님, 재무팀장, 나 외 3명", ), ("e7", 8, "16:30", "17:00", "1:1 — 민서님", "team", "라운지", "", False, ""), ("e8", 8, "20:00", "20:30", "스트레칭 & 명상", "health", "", "", False, ""), ("e9", 9, "10:00", "11:30", "사용자 인터뷰 ×2", "work", "리서치룸", "", False, ""), ("e10", 9, "14:00", "15:00", "온보딩 와이어프레임 싱크", "work", "Figma", "", False, ""), ("e11", 9, "18:00", "19:00", "PT 트레이닝", "health", "피트니스", "", False, ""), ("e12", 10, "09:30", "09:45", "팀 데일리 스탠드업", "team", "Zoom", "", False, ""), ("e13", 10, "11:00", "12:00", "예산 재배분 검토", "meeting", "회의실 A", "", False, ""), ( "e14", 10, "15:00", "16:00", "분기 리포트 작성 블록", "work", "", "딥 워크 — 방해 금지", False, "", ), ("e15", 11, "10:00", "11:00", "OKR 중간 점검", "meeting", "대회의실", "", False, ""), ("e16", 11, "13:30", "14:30", "음성 인터페이스 톤 워크숍", "work", "회의실 C", "", False, ""), ("e17", 11, "19:30", "21:00", "저녁 — 가족 모임", "personal", "본가", "", False, ""), ("e18", 12, "09:30", "09:45", "팀 데일리 스탠드업", "team", "Zoom", "", False, ""), ("e19", 12, "11:00", "12:00", "스프린트 리뷰 & 회고", "team", "대회의실", "", False, ""), ("e20", 12, "14:00", "15:30", "신규 입사자 온보딩 세션", "work", "교육장", "", False, ""), ("e21", 12, "16:00", "16:30", "치과 예약", "health", "강남 치과", "", False, ""), ("e22", 13, "11:00", "13:00", "브런치 — 수아님", "personal", "성수", "", False, ""), ] # ---- 이벤트 직접 액션 (cal.jsx 어젠다 '내가 맡기로 한 일' — e3, e4) ---- EVENT_ACTIONS = { "e3": [("온보딩 와이어프레임 피드백 정리", "오늘"), ("푸시 알림 QA 결과 공유", "내일")], "e4": [("온보딩 3번 화면 CTA 수정안 반영", "내일"), ("음성 안내 카피 검토", "이번 주")], } # ---- 집중 블록 (cal-data.js: focusBlocks, day 8) ---- FOCUS = [ ("f1", 8, "09:00", "09:20", "현우님 온보딩 시안 회신", "light", "메일", 0), ("f2", 8, "10:05", "10:25", "PR #482 빠른 리뷰", "light", "개발", 1), ("f3", 8, "15:10", "16:25", "분기 리포트 초안 마무리", "deep", "딥 워크", 2), ("f4", 8, "17:10", "17:35", "독서모임 책 2장 읽기", "light", "성장", 3), ] # ---- 회의 (cal-data.js: meets) ---- MEETINGS = { "e3": dict( phase="done", one_on_one=False, meta="09:30–09:45 · 15분 · 음성 기록 → 노트 자동 정리됨", summary=[ "온보딩 와이어프레임 피드백이 중심 안건 — 3번 화면 CTA 수정안으로 정리", "푸시 알림 QA는 iOS 완료 · Android 진행 중", "분기 리포트는 매출 섹션만 남음 — 현우님이 오늘 중 데이터 전달", ], decisions=["온보딩 3번 화면 CTA는 하단 고정형으로 확정"], actions=[ ("온보딩 와이어프레임 피드백 정리", "나", "오늘", True), ("푸시 알림 QA 결과 공유", "수아", "내일", True), ("매출 데이터 전달", "현우", "오늘", False), ], ), "e4": dict( phase="live", one_on_one=False, meta="11:00–11:45 · 진행 중 · 아리가 실시간으로 받아적고 있어요", summary=[ "환영 화면 카피 톤 — ‘친근하게, 두 문장 이내’로 의견 수렴 중", "권한 요청 화면 재배치안 공유 — 이탈률 데이터 근거로 논의", ], decisions=[], actions=[("온보딩 3번 화면 CTA 수정안 반영", "나", "내일", False)], ), "e6": dict( phase="upcoming", one_on_one=False, starts_in="2시간 50분 후 시작", agenda=[ "Q2 핵심 지표 리뷰 — 리텐션 · 매출", "예산 재배분 안건 — 오늘 의사결정 필요", "다음 분기 OKR 방향 합의", ], last_meeting={ "when": "지난주 월 14:00 · 분기 전략 미팅", "note": "리텐션 개선 실험 3종 승인 · 예산 재배분은 데이터 보강 후 재논의하기로", }, last_actions=[ {"text": "리텐션 코호트 분석", "who": "수아", "done": True}, {"text": "MRR / ARR 표 정리", "who": "나", "done": True}, {"text": "예산 시나리오 2안 작성", "who": "재무팀장", "done": True}, {"text": "경쟁사 가격 조사", "who": "현우", "done": True}, {"text": "예측 시나리오 3종", "who": "나", "done": False}, ], insights=[ "리텐션 KPI가 전분기 대비 +6%p — 첫 화두로 추천드려요", "내 액션 중 ‘예측 시나리오 3종’이 미완 — 미팅 전 12:00 빈 블록을 비워뒀어요", ], docs=["분기 리포트 초안 · 75%", "예산 재배분 시나리오 v2"], ), "e7": dict( phase="upcoming", one_on_one=True, starts_in="오늘 16:30", person={"name": "민서", "initial": "민", "tone": "green"}, last_meeting={ "when": "5월 25일 · 지난 1:1", "note": "성장 로드맵 — 데이터 분석 역량을 키우고 싶다는 의사. 분석 과제 1건을 맡겨보기로 약속", }, promises=[ {"text": "데이터 전처리 파이프라인 과제 위임", "done": True}, {"text": "분석 강의 수강 지원 품의 올리기", "done": False}, ], signals=[ {"k": "업무량", "v": "진행 4건 · 평균보다 +1건", "tone": "amber"}, {"k": "위임 과제", "v": "전처리 파이프라인 60% · 순항", "tone": "green"}, {"k": "최근 성과", "v": "회고 문서 정리 — 팀 반응 좋음", "tone": "blue"}, ], talking_points=[ "전처리 과제에서 막히는 부분이 있는지", "강의 지원 품의 — 지난 약속, 진행 상황 공유", "업무량이 살짝 높아요 — 우선순위 조정이 필요한지", ], ), } def _seed_calendar(s: Session) -> None: """일정 시드 — run_seed 내부에서 호출하는 헬퍼.""" for cid_, name, tone, on, order in CALS: s.add(Calendar(id=cid_, name=name, tone=tone, on=on, sort_order=order)) for i, (eid, day, st, en, title, cal, loc, note, soon, people) in enumerate(EVENTS): s.add( CalEvent( id=eid, day=day, start=st, end=en, title=title, cal=cal, loc=loc, note=note, soon=soon, people=people, sort_order=i, ) ) macnt = 0 for eid, acts in EVENT_ACTIONS.items(): for j, (text, when) in enumerate(acts): macnt += 1 s.add( MeetingAction( id=f"ea{macnt}", event_id=eid, source="event", idx=j, text=text, who="나", when_text=when, added=False, sort_order=j, ) ) for fid, day, st, en, title, typ, tag, order in FOCUS: s.add( FocusBlock( id=fid, day=day, start=st, end=en, title=title, type=typ, tag=tag, auto=True, sort_order=order, ) ) s.commit() mcnt = 0 for eid, d in MEETINGS.items(): s.add( Meeting( id=eid, event_id=eid, phase=MeetPhase(d["phase"]), one_on_one=d.get("one_on_one", False), meta=d.get("meta", ""), starts_in=d.get("starts_in", ""), summary_json=json.dumps(d.get("summary", []), ensure_ascii=False), decisions_json=json.dumps(d.get("decisions", []), ensure_ascii=False), agenda_json=json.dumps(d.get("agenda", []), ensure_ascii=False), last_meeting_json=json.dumps(d.get("last_meeting", {}), ensure_ascii=False), last_actions_json=json.dumps(d.get("last_actions", []), ensure_ascii=False), insights_json=json.dumps(d.get("insights", []), ensure_ascii=False), docs_json=json.dumps(d.get("docs", []), ensure_ascii=False), person_json=json.dumps(d.get("person", {}), ensure_ascii=False), promises_json=json.dumps(d.get("promises", []), ensure_ascii=False), signals_json=json.dumps(d.get("signals", []), ensure_ascii=False), talking_points_json=json.dumps(d.get("talking_points", []), ensure_ascii=False), ) ) for k, (text, who, when, added) in enumerate(d.get("actions", [])): mcnt += 1 s.add( MeetingAction( id=f"ma{mcnt}", meeting_id=eid, source="meeting", idx=k, text=text, who=who, when_text=when, added=added, sort_order=k, ) ) s.commit()