# 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()