feat: add diary notion core v7 - #4
Merged
Merged
Conversation
- 구조: 루트 페이지 → 연도 페이지 → 단일 Entries DB (Project select 분류) - 작업 분리: 슬래시 커맨드 안의 Claude가 transcript를 semantic 단위로 N개 task 분리 - LLM: Claude Code 구독 활용 (별도 Anthropic API 키 X) - 셋업: claude-diary notion init 대화형 명령 (token + URL → page_id 파싱 + 권한 검증) - 멱등성: Session ID + Task Index hidden 컬럼, --force 시 archive&recreate - 에러: 401/403 fail fast, 400 skip, 429/5xx retry, 404 자동 재생성 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- DB 스키마: Branch (select) 컬럼 추가, 표시 7→8개. CLI가 자동 채움 (commit 있으면 그 branch, 없으면 HEAD branch) - 작업 분리 룰 보완: branch 경계 최우선 → 의미 단위 세션 중 git switch 하면 무조건 새 task로 분리. 한 task = 한 branch 보장 - 결정 표에 #15(Branch) + #16~19(에러처리/retry/캐시/부분실패) 채움 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- lib/notion_cache.py: 연도 페이지/DB/행 ID 캐시 (config의 root_page_id 변경 시 자동 무효화) - exporters/notion_hierarchical.py: Notion API 클라이언트 + 페이지/DB/행 CRUD - HTTP retry: 429 Retry-After 준수, 5xx exponential backoff (3회) - 에러 분기: 401/403→NotionAuthError, 404→NotionNotFound, 400→NotionBadRequest - 멱등성: Session ID + Task Index로 행 검색 - --force용 archive_rows_for_session - 새 테스트 34개 (전체 477 통과) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- cli/notion_push.py: JSON read → entry_data → push pipeline - 멱등성: Session ID + Task Index로 skip - --force: 같은 session_id 행 archive 후 재push - 에러 분기: NotionAuthError fail fast, NotionBadRequest skip+continue - 실패 시 임시 JSON 보존, 성공 시 자동 삭제 - env vars (CLAUDE_DIARY_NOTION_TOKEN/ROOT_PAGE_ID) 우선 - formatter.py: build_notion_blocks() — Notion API block list 빌더 (body_intro paragraph + 사용자요청/파일/명령/Git/에러 섹션, 2000자 truncate) - git_info.py: task별 branch 결정 함수 4개 추가 (get_branch_for_commit, get_head_branch, get_commit_info, get_diff_stat_for_commits) - cli/__init__.py: `notion <action>` 그룹 명령 추가 (push 동작, init은 Phase 3) - 새 테스트 44개 (전체 521 통과) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- cli/notion_init.py: claude-diary notion init
- getpass로 token 가려서 입력 + URL/ID 받기
- parse_page_id(): URL/대시UUID/평탄 hex 모두 지원 → canonical 32hex
- 권한 검증: GET /users/me (token) + GET /blocks/{id} (페이지 접근)
- 친절한 에러: 401 → token 발급 URL, 404 → Connections 공유 안내
- 검증 성공 시 exporters.notion_hierarchical에 저장
- cli/__init__.py: notion init 호출 활성화
- 새 테스트 17개 (전체 538 통과)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- setup.py: SLASH_COMMANDS dict로 일반화 (filename → (content, marker))
- DIARY_NOTION_SLASH_COMMAND 추가 (Branch 경계 → Semantic-first 분리 룰
+ title/body_intro 가이드 + JSON 스키마 + 임시 파일 흐름)
- _install_all_slash_commands / _uninstall_all_slash_commands
- cmd_install/uninstall이 두 슬래시 커맨드 모두 처리
- 업그레이드 path: 기존 diary.md 보존, diary-notion.md만 추가
- 사용자 수정한 슬래시 파일은 marker로 판별, uninstall 시 보존
- 새 테스트 15개 (전체 553 통과)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- README.md: 'Notion 업무일지 — /diary-notion 슬래시 커맨드' 섹션 추가 - 계층 구조 다이어그램 + 5단계 셋업 가이드 + 사용법 + DB 컬럼 표 - 설계 문서 링크 - 보안 주의 (config.json 공유 금지, .gitignore 권장 패턴) - CHANGELOG.md: [Unreleased] 섹션에 변경 요약 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- DB 스키마에 3개 컬럼 추가 (표시 11 + hidden 2 = 13개): - Status (select, 5단계): Discussion/Design/Implementation/Testing/Deployed - Task Group (select): 큰 작업 단위 묶음 - Depends On (relation, self-ref, 단방향): 선행 작업 참조 - JSON 스키마에 status/task_group/depends_on_indices 필드 추가 - 결정 #20~23 (마이그레이션 정책 포함) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…(Phase 6b)
- exporters/notion_hierarchical.py: _create_database()
- Status (select), Task Group (select) 컬럼 추가
- DB 생성 직후 _add_depends_on_relation()으로 PATCH /databases/{id}
호출해 self-referential 'Depends On' relation 컬럼 추가
(database_id가 생성 후에야 알려지므로 2단계 호출 필수)
- test_notion_hierarchical.py: 새 컬럼 + PATCH 호출 검증
- 전체 553 통과
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…신 (Phase 6c) - exporters/notion_hierarchical.py: update_row_relation() 추가 (페이지 PATCH로 Depends On relation 설정) - cli/notion_push.py: 2-pass 흐름 - Pass 1: 모든 행 생성 (Depends On 비워둠) → task_index → row_id 맵 누적 - Pass 2: depends_on_indices 가 있는 task만 PATCH로 relation 채움 - _build_properties: status (VALID_STATUSES 검증), task_group 추가 - cli/setup.py: - DIARY_NOTION_SLASH_COMMAND 갱신 (status/task_group/depends_on_indices 가이드) - _install_slash_command(--force): 사용자 수정 안 한 파일만 덮어쓰기 - cli/__init__.py: install --force 옵션 - 새 테스트 12개, 전체 565 통과 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
기존 9개 행이 들어있던 이전 push의 DB에는 Status/Task Group 컬럼이 없어서
재push가 'property does not exist' 400 으로 실패. ensure_database가 cache hit
경로에서도 _ensure_db_schema_extensions를 호출하도록 변경 (idempotent — cache
에 schema_v 플래그 두고 한 번만 PATCH).
- exporters/notion_hierarchical.py
- _create_database에서 Status/Task Group 제거 (책임 분리)
- _ensure_db_schema_extensions(): Status + Task Group + self-relation
Depends On 한 번의 PATCH로 보장
- ensure_database가 cache hit/miss 둘 다 schema extension 호출
- lib/notion_cache.py: schema_v 키 load/save 지원
- 테스트 2건 추가 (기존 DB 업그레이드 path, 캐시 플래그로 skip)
- 전체 567 통과
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
이전 commit (e70cb96)에서 git add -A로 부분 실패 보존된 임시 JSON이 함께 staged됨. .diary-notion-*.json 패턴을 .gitignore에 추가해 향후 재발 방지. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
_wire_parent_tasks lacked the self-reference guard that _wire_depends_on has, so a task whose parent_index points at its own index would be set as its own Parent Task and own Sub-item. Skip when parent_idx == idx. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
git emits UTF-8, but subprocess.run(text=True) decodes with the locale codec (cp949 on Korean Windows), raising UnicodeDecodeError on Korean commit messages / branches / paths. The broad excepts swallowed it, silently dropping all git info. Pin encoding="utf-8", errors="replace" on all 8 git calls. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rows pushed before Parent Task became a synced dual_property could be missing the reverse Sub-items link, which hides Notion's native sub-item toggle on the parent row. Add a best-effort repair step to ensure: it reads all rows, treats Parent Task as source of truth, and patches each parent's Sub-items to include any children pointing at it. Idempotent, skips self/dangling refs, dry-run reports without writing, and query/PATCH failures degrade to warnings instead of failing the run. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Only Notion's native sub-item relation drives the expand/collapse nesting, and it can only be created via the Notion UI (locale-named, e.g. 상위 항목/하위 항목 or Parent item/Sub-item). The tool's own Parent Task/ Sub-items relation is a parallel dual_property that Notion never treats as native, so data pushed there never nested. - detect_subitem_relation(): find the native pair by elimination (the self-referential dual_property that is not one of our reserved names), orienting parent/child via localized name tokens — no hardcoded names. - push: write each child's link into the native parent side (one write per child; Notion syncs the child side). If no native relation exists yet, skip nesting with a one-time hint to enable Sub-items in the UI. - ensure: point the 작업 계층 view's subtasks at the native child relation, hide the legacy Parent Task/Sub-items columns, and migrate existing Parent Task links into the native relation (idempotent, best-effort). Verified end-to-end on a live Korean-locale database: detection, view wiring, and migration are idempotent and nesting renders. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reflect the native sub-item architecture in README/CHANGELOG: nesting is driven by Notion's UI-created native relation (locale-named), enabled once per database via ⋯ → Sub-items. push auto-detects it and writes parent links there; ensure points the 작업 계층 view at it and migrates legacy Parent Task data. The legacy Parent Task/Sub-items relation is kept hidden. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the operational gotchas surfaced while debugging native sub-items: enabling Sub-items once per DB in the UI, why legacy rows have empty Status/Purpose/Task Group, per-year DB re-enablement, and refreshing the Codex skill (new session + skipped user-modified slash command). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
공통 diary-notion schema/view/push/ensure 로직을 main에 병합하기 위한 PR입니다. Codex 전용 skill 계약은 feat/diary-notion-codex-v7 브랜치에서 별도 처리합니다.