## 2026-06-03 — 전역 "내 일정"(My Schedule): 개인 캘린더/메모 + 태그 + Jira 연동

### 배경

기존 플래너·스케줄은 모두 특정 프로젝트에 종속(`project_id NOT NULL`)이라, 프로젝트와 무관한 **개인용 정리 공간**이 없었다. 사이드바(홈·리뷰 큐)에 전역 페이지로 개인 메모/일정을 두고, 동시에 프로젝트 스케줄·플래너 마감일과 내게 할당된 Jira 작업까지 한 캘린더에서 보고 싶었다.

### 주요 변경

#### 1. 전역 "내 일정" 페이지 (`3369b21`)

- **서버**: 신규 전역 테이블 `personal_items`(프로젝트 비종속 — 제목/설명/`due_at`/`all_day`/상태/태그). `routes/personal.ts`: `/api/personal-items` CRUD + `/api/agenda?from&to` 집계 — 개인 항목 + 전 프로젝트 스케줄(`next_run_at`/`run_at`) + 플래너 마감일을 **읽기 전용**으로 합쳐 반환. 실행 없음(순수 개인 정리).
- **클라이언트**: 사이드바에 "내 일정" 항목(`CalendarDays`) + `/agenda` 라우트. `PersonalAgenda` 페이지 — 월 캘린더 그리드 + 선택 날짜 패널 + 날짜 없는 백로그. 프로젝트 스케줄/플래너 항목은 읽기 전용 칩으로 표시하고 클릭 시 해당 프로젝트로 딥링크.

#### 2. 캘린더 뷰 확장: 월/주/일/표 + 빠른 추가 (`242fc61`, `273c83e`, `acb8d5a`)

- **월/주/일** 뷰 토글(하나의 날짜 커서 + 뷰 모드가 표시 범위·그리드 결정, prev/next는 단위별 이동) + **표(테이블)** 뷰(제목/날짜/종류/상태, 행 클릭 시 편집·딥링크).
- 날짜 셀 hover 시 **노션식 "+"** → 그 날짜가 채워진 추가 폼.

#### 3. 메모 에디터: 확장형 + 제목 선택 (`a21a87c`, `0639ccc`, `223995b`, `1452b7f`)

- 모달 좌상단 **크게 보기(⤢)** 토글로 거의 전체화면 페이지 뷰 전환(본문 영역 큼). 제목은 **선택사항**(비우면 본문 첫 줄, 둘 다 없으면 "(제목 없음)"). 제목 입력 필드 배경·포커스 링 다듬기.

#### 4. 태그 시스템 (`322b5f4`)

- 에디터의 칩형 태그 입력(Enter/`,` 추가, Backspace/× 제거). 사이드패널·표에 색상 태그 칩(이름 해시 기반 결정론적 색). 헤더 아래 **태그 필터 칩 줄** — 선택 시 개인 항목만 필터(프로젝트/Jira 집계는 숨김).

#### 5. 사이드 패널 드래그 리사이즈 (`166b401`)

- 캘린더↔패널 경계를 `col-resize` 핸들로 교체, 드래그로 패널 너비 조절(260–760px, localStorage 영속).

#### 6. Jira 연동 — 할당 이슈 오버레이 + 가져오기 (`71b6bae`, `3494152`, `126689f`, `a24cc42`)

- **전용 전역 Jira 연결**: `app_settings`(key/value) 테이블에 `agenda.jira`(enabled/base_url/email/api_token) 저장. **api_token은 응답에 노출 안 함**(`hasToken` 플래그만).
- **서버**(`lib/jira-client.ts` + `routes/personal.ts`): `assignee = currentUser()`인 열린 이슈를 가져와 — 기한 있는 것은 범위로, 기한 없는 것은 `IS EMPTY`로 함께 조회. `/api/agenda/jira`, `/jira-config`(GET/PUT), `/jira-test`, `/jira/import`(이슈→개인 메모).
- **클라이언트**: Jira 이슈를 **별도 비차단 fetch**(실패해도 캘린더 정상) → 파란 칩으로 오버레이, 클릭 시 이슈를 새 탭으로. **소스 레이어 토글**(메모/스케줄/플래너/Jira), 기한 없는 이슈는 사이드패널 "Jira (마감일 없음)" 목록. 헤더 톱니바퀴 → **친절한 연결 모달**(사이트 주소/이메일/토큰 라벨 + 설명 + "API 토큰 발급받기" 링크 + 3단계 안내 + 연결 테스트).
- **엔드포인트 마이그레이션**: Jira Cloud가 제거한 구 `GET /rest/api/3/search` → 신 `/rest/api/3/search/jql`(404/410 시 구 경로 폴백)로 교체. `/myself`만 쓰던 "연결 테스트"는 통과하는데 검색만 조용히 실패하던 문제 해결. 실패 시 소스 범례에 "Jira 오류" 칩(호버=메시지). **프로젝트별 Jira 패널**(`/api/jira/.../issues`)도 같은 신 엔드포인트로 전환.

#### 7. 새로고침 헬프박스 + 공용 `HoverHelp` (`782993f`)

- 탭에 쓰던 호버 헬프를 공용 `HoverHelp`(portal + 뷰포트 클램핑) 컴포넌트로 추출, 새로고침 버튼에 적용 — "현재 범위 재패치, 이동/뷰 전환 시 자동 갱신, 유휴 시 폴링 없음" 설명.

### 수정된 주요 파일

| 파일 | 변경 내용 |
|------|----------|
| `src/server/db/schema.ts` · `queries.ts` | `personal_items`·`app_settings` 테이블 + CRUD/getset, 크로스-프로젝트 집계 쿼리(`getAllUpcomingSchedules`/`getAllPlannerDueItems`) |
| `src/server/lib/jira-client.ts` | 신규 — Basic 인증 `jiraSearch`(신 `/search/jql` + 폴백)·`jiraMyself` |
| `src/server/routes/personal.ts` | `/api/personal-items` CRUD + `/api/agenda` 집계 + `/api/agenda/jira*`(config/test/조회/import) |
| `src/server/plugins/jira/router.ts` | 이슈 검색을 공유 `jiraSearch`(신 엔드포인트)로 전환 + `total` 보정 |
| `src/server/index.ts` | `personalRouter` 등록 |
| `src/client/src/components/PersonalAgenda.tsx` | 신규 — 월/주/일/표 캘린더 + 메모 에디터 + 태그 + 패널 리사이즈 + Jira 오버레이/설정 모달 |
| `src/client/src/components/HoverHelp.tsx` | 신규(ProjectDetail에서 추출) — portal 호버 헬프 |
| `src/client/src/components/Sidebar.tsx` · `App.tsx` | "내 일정" 사이드바 항목 + `/agenda` 라우트 |
| `src/client/src/api/personal.ts` · `types.ts` · `i18n.tsx` | personal/agenda/jira API + 타입 + ko/en 문자열 |

### 아키텍처 결정

1. **전역 개인 엔티티 분리**: 프로젝트 종속 planner/schedule을 일반화하지 않고 `personal_items`를 새로 둠 — 변환 로직 등과 얽힌 기존 모델을 건드리지 않기 위함.
2. **Jira는 읽기 전용 오버레이**: 이슈를 DB로 복사·동기화하지 않고 그때그때 fetch(원하면 메모로 import). 토큰은 `app_settings`에 저장하되 API 응답에는 절대 포함하지 않음.
3. **Jira fetch는 캘린더와 분리**: Jira 실패가 개인 일정 렌더를 막지 않도록 별도 요청 + 에러 칩 노출.
