diff --git a/.github/workflows/md-to-notion.yml b/.github/workflows/md-to-notion.yml index 1323b0e..9e6033e 100644 --- a/.github/workflows/md-to-notion.yml +++ b/.github/workflows/md-to-notion.yml @@ -7,7 +7,7 @@ on: - 'docs/**/*.md' permissions: - contents: read + contents: write jobs: sync: @@ -39,3 +39,13 @@ jobs: - name: Sync docs to Notion run: python3 scripts/md_to_notion.py + + - name: Commit updated sync maps + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add 'docs/**/.notion-sync.json' || git add docs/ + if ! git diff --staged --quiet; then + git commit -m "chore: .notion-sync.json 업데이트 (md→Notion 동기화)" + git push + fi diff --git a/.github/workflows/notion-sync.yml b/.github/workflows/notion-sync.yml index 085a6ab..43ad2fc 100644 --- a/.github/workflows/notion-sync.yml +++ b/.github/workflows/notion-sync.yml @@ -49,49 +49,49 @@ jobs: if [ -n "$_BLOG_DB" ]; then NOTION_DATABASE_ID="$_BLOG_DB" SAVE_DIR=docs/blog FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_CONTRIBUTE_DB" ]; then NOTION_DATABASE_ID="$_CONTRIBUTE_DB" SAVE_DIR=docs/contribute FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_ABOUT_DB" ]; then NOTION_DATABASE_ID="$_ABOUT_DB" SAVE_DIR=docs/about FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_ARCHITECTURE_DB" ]; then NOTION_DATABASE_ID="$_ARCHITECTURE_DB" SAVE_DIR=docs/architecture FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_POC_DB" ]; then NOTION_DATABASE_ID="$_POC_DB" SAVE_DIR=docs/poc FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_DOCS_DB" ]; then NOTION_DATABASE_ID="$_DOCS_DB" SAVE_DIR=docs/guide FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_RELEASE_DB" ]; then NOTION_DATABASE_ID="$_RELEASE_DB" SAVE_DIR=docs/release-notes FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$_INSTALL_DB" ]; then NOTION_DATABASE_ID="$_INSTALL_DB" SAVE_DIR=docs/install FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi diff --git a/CLAUDE.md b/CLAUDE.md index df5c30d..4aa6b6d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,60 +1,197 @@ -# CLAUDE.md — docs-web 작업 가이드 (허브) +앞으로 branch 는 main 만 쓰도록 해 -SceneMakerAI 기술 문서 사이트의 작업 가이드이자 **문서 인덱스**다. 작업 대부분은 콘텐츠(Markdown)·EN 번역이지만, 사이트 코드(`src/`·`scripts/`·설정)의 유지보수·기능개선도 포함한다. **콘텐츠는 Notion에서 `main`으로 자동 동기화**되고, **코드 작업은 [브랜치 전략](#-브랜치-전략-요약)(main/develop)**을 따른다. +# CLAUDE.md — docs-web 작업 가이드 ---- - -## 📚 문서 맵 - -| 무엇을 찾나 | 문서 | -|------------|------| -| 외부 첫인상 · 빠른 시작 · 포인터 | [README.md](./README.md) | -| 기여 룰 · **브랜치 전략(상세·다이어그램)** · 릴리즈 룰 | [CONTRIBUTING.md](./CONTRIBUTING.md) | -| 디렉토리 구조 · slug 시스템 · 빌드 게이트 · 사이드바 · 콘텐츠 추가 | [dev-docs/codebase.md](./dev-docs/codebase.md) | -| i18n 메커니즘 (symlink · DeepL · EN 파일 규칙) | [dev-docs/i18n.md](./dev-docs/i18n.md) | -| Notion 동기화 (서버 crontab · DB 매핑 · 내부 로직) | [dev-docs/notion-sync.md](./dev-docs/notion-sync.md) | -| 디자인 토큰 (Revolut 스타일) | [.aidocs/design.md](./.aidocs/design.md) | - -> 이 파일(CLAUDE.md)은 **허브**다 — 프로젝트 컨텍스트 + 핵심 함정 + 자주 쓰는 것만 담고, 상세는 위 문서로 위임한다. +SceneMakerAI 기술 문서 사이트의 작업 가이드. 코드 개발 저장소가 아닌 **콘텐츠 사이트**다. 작업의 대부분은 Markdown 추가·수정과 EN 번역이다. --- -## 환경 +## 프로젝트 개요 -프로젝트가 무엇을 하는지(4대 서비스·KPI 등)는 [README](./README.md) 참조. 여기엔 작업에 필요한 사실만 둔다. +**SceneMakerAI**는 오픈소스 AI(멀티모달 LLM)로 방송 콘텐츠(드라마·예능·다큐멘터리)를 재가공하는 **솔박스(Solbox Inc.) 사내 프로젝트**다. 2026 NIPA 오픈소스 AI·SW 지원사업으로 진행 중이며, 4대 서비스(모아보기·리믹스·광고·Batch)와 오픈소스 기여 30+건을 목표로 한다. - 운영 URL: `https://doc.scenemaker.solbox.com` - GitHub: `https://github.com/SceneMakerAI/docs-web` - 기술 스택: **Docusaurus 3.10.1** (React 19, TypeScript 6) - 기본 언어: 한국어(KR), 번역: 영어(EN) -- 콘텐츠 원본: **Notion DB** → 서버 crontab(2분 주기)이 `main`으로 자동 동기화 (GitHub Actions `notion-sync.yml`은 수동 백업) +- 콘텐츠 원본: **Notion DB** → GitHub Actions로 자동 동기화 + +--- + +## 디렉토리 구조 + +``` +docs-web/ +├── docs/ # KR 원본 문서 (Notion 자동 동기화 대상) +│ ├── about/ # 프로젝트 소개 +│ ├── architecture/ # 아키텍처 설계 +│ ├── blog/ # 블로그 (docs 섹션으로 운영, blog 플러그인 비활성) +│ ├── contribute/ # 오픈소스 기여 가이드 +│ ├── guide/ # 시작하기 / 문서 인덱스 +│ ├── install/ # 설치 가이드 (Qwen, LLM 등) +│ ├── poc/ # PoC 기획안 및 벤치마크 +│ └── release-notes/ # 릴리즈 노트 +│ +├── docs_en/ # EN 번역 문서 (개발자 편집 위치) +│ └── (docs/ 와 동일한 서브디렉토리 구조) +│ +├── i18n/ +│ └── en/ +│ ├── docusaurus-plugin-content-docs/ +│ │ └── current -> ../../../docs_en ← symlink (docs_en/ 가리킴) +│ ├── docusaurus-theme-classic/ +│ │ ├── navbar.json # EN 네비바 라벨 +│ │ └── footer.json # EN 푸터 라벨 +│ └── code.json # EN 컴포넌트 UI 문자열 +│ +├── src/ +│ ├── pages/index.tsx # 홈페이지 (Hero + Features + KPI) +│ ├── components/ +│ │ ├── HomepageFeatures/ # 기능 소개 카드 +│ │ └── HomepageKPI/ # KPI 지표 섹션 +│ └── css/custom.css # 전역 CSS 토큰 +│ +├── static/ +│ ├── img/ # 정적 이미지 (섹션별 하위 폴더) +│ └── CNAME # doc.scenemaker.solbox.com +│ +├── scripts/ +│ ├── notion_to_md.py # Notion DB → docs/ 범용 동기화 (계층 구조 지원) +│ ├── translate_to_en.py # 변경된 docs/ → DeepL 번역 → docs_en/ 저장 +│ ├── notion_to_blog.py # 블로그 전용 동기화 (레거시) +│ └── notion_to_contribute.py # 기여 전용 동기화 (레거시) +│ +├── .github/workflows/ +│ ├── deploy.yml # main push 시 GH Pages 자동 배포 +│ └── notion-sync.yml # workflow_dispatch 수동 실행 (DAILY/ALL 선택) +│ +├── docusaurus.config.ts # 사이트 설정 (i18n, navbar, footer, webpack) +├── sidebars.ts # 8개 사이드바 정의 (autogenerated) +└── .aidocs/design.md # 미래 리디자인용 토큰 참조 (Revolut 스타일, 현재 미적용) +``` --- -## ⚠️ 핵심 함정 (작업 전 반드시) +## i18n 구조 핵심 + +**한국어가 원본, 영어는 번역본.** + +| 경로 | 역할 | +|------|------| +| `docs/` | KR 원본. Notion 자동 동기화 대상. | +| `docs_en/` | EN 번역본 편집 위치. **실제 파일이 여기 있다.** | +| `i18n/en/.../current` | `docs_en/`을 가리키는 심볼릭 링크. Docusaurus가 읽는 경로. | + +### 주의: symlink 방향 + +``` +i18n/en/docusaurus-plugin-content-docs/current → ../../../docs_en +``` + +- `docs_en/` = 실제 파일 +- `i18n/.../current` = symlink + +**반대로 하면 안 된다.** webpack이 symlink를 real path로 resolve해서 Docusaurus SSG 라우팅과 불일치 → DocItem `content` props undefined 오류 발생. `docusaurus.config.ts`의 `resolve.symlinks: false` 플러그인이 이 문제를 해결한다 (방향이 맞더라도 적용 중). -작업 중 가장 자주 부딪히는 메커니즘. 상세는 각 dev-docs 참조. +### EN 파일 추가 규칙 -- **symlink 방향** — `i18n/.../current → docs_en` (반대로 만들면 빌드 라우팅 깨짐). → [i18n.md](./dev-docs/i18n.md) -- **한글 파일명은 정상** — `notion_to_docs_generic.py` slugify가 한글 제목을 보존하고, URL은 `slug: "숫자"`로 따로 잡힌다. 수동 파일만 kebab-case. → [codebase.md](./dev-docs/codebase.md) -- **`onBrokenLinks: 'throw'`** — 깨진 내부 링크 = 빌드 실패. PR 전 `npm run build` 필수. -- **서버 crontab 2분 push** — main에 콘텐츠가 2분마다 자동 commit/push된다. main 관련 작업 직전 `git pull --rebase origin main`. → [notion-sync.md](./dev-docs/notion-sync.md) -- **`_category_.json`** — 서브디렉토리는 sync가 자동 생성(수동 수정은 다음 sync에 덮어씌워짐). 부모 `index.md`에 `id:` 추가 금지(파일 경로 기반 ID와 충돌). -- **수동 `git mv`로 KR 파일명 변경 시** — 대응 EN 파일도 함께 옮길 것. (Notion sync를 통한 rename은 old 삭제를 `git diff -D`가 잡아 EN까지 자동 처리되지만, 사람이 직접 `git mv`하면 자동 감지 밖이라 stale EN이 남는다.) +1. `docs/section/filename.md`에 KR 파일이 있으면 → `docs_en/section/filename.md` 에 EN 번역 추가 +2. EN 파일 frontmatter에 `slug: "N"` 반드시 포함 (KR과 동일한 값) +3. EN 파일에 `id:` 필드는 넣지 않는다 — `translate_to_en.py`가 자동으로 제거하며, Docusaurus가 파일 경로로 KR/EN 매칭 +4. `sidebar_position:` 은 KR과 동일하게 +5. **`docs_en/` 파일명은 KR 파일명과 반드시 동일해야 한다** — Docusaurus가 파일 경로 기준으로 KR/EN 페이지를 매칭하므로 이름이 다르면 로케일 스위처가 깨짐 + - KR: `docs/poc/poc-기획안-멀티모달-llm.md` → EN: `docs_en/poc/poc-기획안-멀티모달-llm.md` (동일 파일명 필수) + - Notion 동기화로 KR 파일명이 변경되면 EN 파일명도 반드시 함께 변경할 것 + - `translate_to_en.py`가 자동으로 처리하지만, 수동으로 EN 파일 생성 시에도 동일하게 적용 --- -## 🌿 브랜치 전략 (요약) +## URL 구조 (slug 시스템) + +Notion 동기화 파일은 `slug: "N"` frontmatter로 숫자 URL을 갖는다. + +``` +docs/architecture/아키텍처-설계.md (slug: "1") → /docs/architecture/1 +docs/install/qwen-3x-설치.md (slug: "1") → /docs/install/1 +docs/install/llm-설치.md (slug: "2") → /docs/install/2 +``` + +**계층 구조 페이지 (Notion 하위 항목이 있는 경우):** + +``` +docs/poc/vision-bench/index.md (slug: "/") → /docs/poc/vision-bench/ +docs/poc/vision-bench/child.md (slug: "1") → /docs/poc/vision-bench/1 +``` + +- 부모 `index.md`는 `slug: "/"` (디렉토리 루트 URL), `id:` 필드 없음 +- 자식 파일은 `slug: "{child-order}"` (부모 디렉토리 기준 상대 슬러그) +- **slug는 섹션 내 상대경로**. `"architecture/1"` 같은 전체 경로 쓰면 안 된다. +- 새 파일은 섹션 내에서 `sidebar_position` 순서에 맞춰 다음 번호를 부여한다. +- **Notion 동기화 파일**: `scripts/notion_to_md.py`가 `slug` 자동 생성. 수동 추가 파일만 직접 slug를 넣어야 한다. + +--- + +## Notion 동기화 + +### 실제 운영 방식 — 서버 crontab + +GitHub Actions가 아닌 **서버에서 직접 crontab으로 2분마다** 실행한다. + +``` +*/2 * * * * /root/docs-web/scripts/server-sync.sh >> /var/log/notion-sync.log 2>&1 +``` + +**`scripts/server-sync.sh` 흐름:** + +1. `git pull --rebase origin main` — 원격 최신 코드 반영 +2. 8개 Notion DB 병렬 동기화 (`notion_to_md.py`, `FETCH_MODE=ALL`) +3. `translate_to_en.py` — 변경된 KR 파일 DeepL 번역 → `docs_en/` 저장 +4. 변경사항 있으면 `git commit + push` → `deploy.yml` 트리거 → GH Pages 배포 -콘텐츠(Notion 자동 동기화)와 코드 작업을 **main/develop 2개 브랜치**로 분리한다. +환경변수는 `/root/docs-web/.env` 파일에서 로드한다 (레포에 포함되지 않음). -- **main** — 배포 + 서버 crontab 콘텐츠 자동 commit/push. **사람이 직접 작업하지 않는다.** -- **develop** — 상시 통합 브랜치. 모든 기능개선·버그픽스가 모인다. 배포되지 않으므로 검증은 로컬 `npm run build && npm run serve`. -- `feature/*` → PR → **develop** → PR → **main** → 배포 -- `hotfix/*`는 develop을 거치지 않고 **main에 직접 PR** 후 develop으로 백머지(미완성 기능 동반 배포 방지). -- 모든 PR은 `pr-build.yml`(빌드)을 통과해야 머지(브랜치 보호 규칙으로 강제). +로그 확인: +```bash +tail -f /var/log/notion-sync.log +``` -> **다이어그램·머지 전략·역방향 흡수 등 상세는 [CONTRIBUTING.md §7](./CONTRIBUTING.md#7-코드사이트-기여-github-develop-플로우)**. +> **GitHub Actions `notion-sync.yml`** 은 수동 실행용 백업 (`workflow_dispatch`). 평소에는 서버 crontab이 실제 운영을 담당한다. + +--- + +### DB ↔ 디렉토리 매핑 + +| `.env` 변수 | 저장 경로 | +|------------|-----------| +| `NOTION_ABOUT` | `docs/about/` | +| `NOTION_ARCHITECTURE` | `docs/architecture/` | +| `NOTION_BLOG` | `docs/blog/` | +| `NOTION_CONTRIBUTE` | `docs/contribute/` | +| `NOTION_DOCS` | `docs/guide/` | +| `NOTION_INSTALL` | `docs/install/` | +| `NOTION_POC` | `docs/poc/` | +| `NOTION_RELEASE` | `docs/release-notes/` | +| `NOTION_TOKEN` | API 인증 토큰 | +| `DEEPL_API_KEY` | DeepL 번역 API 키 | + +### 동기화 내부 로직 (`notion_to_md.py`) + +Notion "하위 항목" relation을 읽어 자동으로 계층 구조를 결정한다. + +- 하위 항목 없는 페이지 → `docs/{section}/{slug}.md` (평면) +- 하위 항목 있는 부모 → `docs/{section}/{slug}/index.md` + `_category_.json` 자동 생성 +- 자식 페이지 → `docs/{section}/{parent-slug}/{child-slug}.md` + +| 환경변수 | 기본값 | 설명 | +|---------|--------|------| +| `NOTION_PROPERTY_SUBITEM` | `하위 항목` | Sub-items relation 속성명 | +| `NOTION_PROPERTY_PARENT` | `상위 항목` | Parent item relation 속성명 | + +### 수동 동기화 (단일 섹션) + +```bash +NOTION_TOKEN=... NOTION_DATABASE_ID=... SAVE_DIR=docs/guide python3 scripts/notion_to_md.py +``` --- @@ -72,11 +209,59 @@ SceneMakerAI 기술 문서 사이트의 작업 가이드이자 **문서 인덱 --- -## 🚫 하지 말 것 +## 빌드 게이트 + +### CI에서 실패하는 것 +- **깨진 내부 링크** — `onBrokenLinks: 'throw'` 설정. PR 전 `npm run build` 통과 필수. +- **MDX 컴파일 오류** — 프론트매터·JSX 문법 오류. + +### 로컬에서만 확인 +- `npm run typecheck` — `strict: true`지만 빌드와 무관. IDE 보조용. + +--- + +## 콘텐츠 추가 워크플로우 + +### 새 Notion 섹션 추가 시 + +1. `secrets.NOTION_XXX` 시크릿 등록 +2. `.github/workflows/notion-sync.yml`에 새 DB 환경변수 및 실행 블록 추가 +3. `docs/new-section/` 디렉토리 및 `_category_.json` 생성 +4. `sidebars.ts`에 새 사이드바 항목 추가 +5. `docusaurus.config.ts` navbar에 `{type: 'docSidebar', ...}` 추가 + +### 수동으로 새 문서 추가 시 + +1. `docs/section/filename.md` 생성 (slug, id, sidebar_position, title 포함) +2. `docs_en/section/filename.md` 생성 (동일 frontmatter + 영어 내용) +3. `npm run build` 통과 확인 후 main에 push + +--- + +## 사이드바 목록 + +| 사이드바 ID | 네비바 라벨 | `docs/` 디렉토리 | +|------------|------------|-----------------| +| `aboutSidebar` | 프로젝트 소개 | `about/` | +| `architectureSidebar` | 아키텍처 | `architecture/` | +| `installSidebar` | 설치 | `install/` | +| `pocSidebar` | PoC | `poc/` | +| `docsSidebar` | 문서 | `guide/` | +| `blogSidebar` | 블로그 | `blog/` | +| `contributeSidebar` | 오픈소스 기여 | `contribute/` | +| `releaseNotesSidebar` | 릴리즈 노트 | `release-notes/` | + +--- + +## 하지 말 것 - `docusaurus.config.ts`의 `url` / `baseUrl` / `organizationName` / `projectName` 임의 변경 금지 (GH Pages 배포와 RSS 절대 URL에 직접 영향) - `onBrokenLinks: 'throw'`를 `'warn'`으로 낮추지 말 것 - EN 번역 만든다고 KR 원본(`docs/`)을 영어로 덮어쓰지 말 것 -- `i18n/en/.../current` 를 real directory로 바꾸지 말 것 (symlink여야 함 — [i18n.md](./dev-docs/i18n.md)) +- `i18n/en/.../current` 를 real directory로 바꾸지 말 것 (symlink여야 함) - `.docusaurus/`, `build/`, `node_modules/` 커밋 금지 -- `_category_.json` 서브디렉토리 수동 편집 금지(sync가 덮어씀), 부모 `index.md`에 `id:` 금지 — [codebase.md](./dev-docs/codebase.md) · 위 핵심 함정 참조 +- **`_category_.json` 수동 편집 시 주의**: + - **섹션 루트** (`docs/{section}/_category_.json`): 수동 관리. `link.type: "doc"` 사용 시 실제 존재하는 doc ID인지 반드시 확인 (`npm run build` 로컬 통과 필수) + - **서브디렉토리** (`docs/{section}/{subdir}/_category_.json`): `notion_to_md.py`가 자동 생성·관리. 직접 수정하면 다음 sync에 덮어씌워짐 + - 부모 `index.md`에 `id:` 필드 추가 금지 — `_category_.json`의 `link.id`가 파일 경로 기반 ID(`{section}/{slug}/index`)로 고정되어 있어 충돌 발생 +- **KR 파일이 이동(rename)된 경우** 대응하는 stale EN 파일을 수동 삭제해야 함 — `translate_to_en.py`는 git diff 삭제 감지만 하므로 rename은 자동 처리 안 됨 diff --git a/docs/about/.notion-sync.json b/docs/about/.notion-sync.json index ab18e86..0b4fc82 100644 --- a/docs/about/.notion-sync.json +++ b/docs/about/.notion-sync.json @@ -1,8 +1,14 @@ { "365e15b4-0359-8017-817e-d1e2699828db": { "file": "docs/about/테스트로-이름-수정.md", - "last_edited": "2026-05-27T01:55:00.000Z", - "content_hash": "b22a39afc99500a5db384d3bdddde5322211bc7b86339689ba982806ac05a3a8", + "last_edited": "2026-05-27T04:08:00.000Z", + "content_hash": "adb4921510a4919dbfae2d89903400fbc238f4e7ef79b1630eb80a9c6efaed5b", + "order": 1, + "parent_id": null + }, + "36de15b4-0359-814b-9f2b-ddbefb377eda": { + "file": "docs/about/sbin.md", + "last_edited": "2026-05-27T05:32:00.000Z", "order": 1, "parent_id": null } diff --git a/docs/about/sbin.md b/docs/about/sbin.md new file mode 100644 index 0000000..8fe3a1f --- /dev/null +++ b/docs/about/sbin.md @@ -0,0 +1,13 @@ +--- +id: 테스트로-이름-수정 +title: "sbin" +sidebar_position: 1 +slug: "1" +--- + +sbin 이 2026-05-27 14:19 에 수정 + +## 내용 수정 테스트 + +이 내용이 Notion에 반영되면 수정 케이스 동작 확인. + diff --git a/scripts/md_to_notion.py b/scripts/md_to_notion.py index d51c692..e00027d 100644 --- a/scripts/md_to_notion.py +++ b/scripts/md_to_notion.py @@ -11,7 +11,6 @@ source .env && python3 scripts/md_to_notion.py source .env && SAVE_DIR=docs/about python3 scripts/md_to_notion.py """ -import hashlib import json import os import re @@ -265,6 +264,11 @@ def append_blocks(page_id: str, blocks: list): _api("patch", f"/blocks/{page_id}/children", json={"children": chunk}) +def get_page_last_edited(page_id: str) -> str: + r = _api("get", f"/pages/{page_id}") + return r.json().get("last_edited_time", "") + + def update_page_content(page_id: str, blocks: list): """기존 블록 전체 삭제 후 새 블록 추가.""" for bid in get_child_block_ids(page_id): @@ -316,10 +320,6 @@ def file_to_page_id(sync_map: dict, filepath: str) -> str | None: return None -def content_hash(text: str) -> str: - return hashlib.sha256(text.encode()).hexdigest() - - # ── Git diff ────────────────────────────────────────────────────────────────── def get_changed_files(section_dir: str) -> dict[str, list[str]]: @@ -376,7 +376,7 @@ def process_section(section_dir: str): blocks = md_body_to_blocks(body) log(f" [수정] {filepath} → {len(blocks)}개 블록 업로드 중...") update_page_content(page_id, blocks) - sync_map[page_id]["content_hash"] = content_hash(body) + sync_map[page_id]["last_edited"] = get_page_last_edited(page_id) sync_dirty = True log(f" [수정] 완료: {filepath}") @@ -396,8 +396,7 @@ def process_section(section_dir: str): if page_id: sync_map[page_id] = { "file": filepath, - "last_edited": "", - "content_hash": content_hash(body), + "last_edited": get_page_last_edited(page_id), "order": order, "parent_id": None, } diff --git a/scripts/notion_to_docs_generic.py b/scripts/notion_to_md.py similarity index 99% rename from scripts/notion_to_docs_generic.py rename to scripts/notion_to_md.py index 577ec09..e4aea94 100644 --- a/scripts/notion_to_docs_generic.py +++ b/scripts/notion_to_md.py @@ -1,5 +1,5 @@ """ -notion_to_docs_generic.py — Notion DB → Docusaurus docs 섹션 동기화 +notion_to_md.py — Notion DB → Docusaurus docs 섹션 동기화 Env vars (필수): NOTION_TOKEN Notion API 토큰 diff --git a/scripts/server-sync.sh b/scripts/server-sync.sh index 6ea202f..e56633c 100755 --- a/scripts/server-sync.sh +++ b/scripts/server-sync.sh @@ -19,35 +19,35 @@ pids=() [ -n "$NOTION_ABOUT" ] && \ NOTION_DATABASE_ID="$NOTION_ABOUT" SAVE_DIR=docs/about FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_ARCHITECTURE" ] && \ NOTION_DATABASE_ID="$NOTION_ARCHITECTURE" SAVE_DIR=docs/architecture FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_BLOG" ] && \ NOTION_DATABASE_ID="$NOTION_BLOG" SAVE_DIR=docs/blog FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_CONTRIBUTE" ] && \ NOTION_DATABASE_ID="$NOTION_CONTRIBUTE" SAVE_DIR=docs/contribute FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_DOCS" ] && \ NOTION_DATABASE_ID="$NOTION_DOCS" SAVE_DIR=docs/guide FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_INSTALL" ] && \ NOTION_DATABASE_ID="$NOTION_INSTALL" SAVE_DIR=docs/install FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_POC" ] && \ NOTION_DATABASE_ID="$NOTION_POC" SAVE_DIR=docs/poc FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) [ -n "$NOTION_RELEASE" ] && \ NOTION_DATABASE_ID="$NOTION_RELEASE" SAVE_DIR=docs/release-notes FETCH_MODE=ALL \ - python3 scripts/notion_to_docs_generic.py & pids+=($!) + python3 scripts/notion_to_md.py & pids+=($!) # 모든 동기화 완료 대기 failed=0 diff --git a/scripts/sync-local.sh b/scripts/sync-local.sh index 54dc1bc..4dae4b4 100755 --- a/scripts/sync-local.sh +++ b/scripts/sync-local.sh @@ -23,7 +23,7 @@ pids=() BLOG_DB="${NOTION_BLOG:-$NOTION_DATABASE_ID}" if [ -n "$BLOG_DB" ]; then NOTION_DATABASE_ID="$BLOG_DB" SAVE_DIR=docs/blog FETCH_MODE="$FETCH_MODE" \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi @@ -31,44 +31,44 @@ fi CONTRIBUTE_DB="${NOTION_CONTRIBUTE:-$NOTION_CONTRIBUTE_DATABASE_ID}" if [ -n "$CONTRIBUTE_DB" ]; then NOTION_DATABASE_ID="$CONTRIBUTE_DB" SAVE_DIR=docs/contribute FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi # Generic docs sections if [ -n "$NOTION_ABOUT" ]; then NOTION_DATABASE_ID="$NOTION_ABOUT" SAVE_DIR=docs/about FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$NOTION_ARCHITECTURE" ]; then NOTION_DATABASE_ID="$NOTION_ARCHITECTURE" SAVE_DIR=docs/architecture FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$NOTION_POC" ]; then NOTION_DATABASE_ID="$NOTION_POC" SAVE_DIR=docs/poc FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$NOTION_DOCS" ]; then NOTION_DATABASE_ID="$NOTION_DOCS" SAVE_DIR=docs/guide FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$NOTION_RELEASE" ]; then NOTION_DATABASE_ID="$NOTION_RELEASE" SAVE_DIR=docs/release-notes FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi if [ -n "$NOTION_INSTALL" ]; then NOTION_DATABASE_ID="$NOTION_INSTALL" SAVE_DIR=docs/install FETCH_MODE=ALL \ - python scripts/notion_to_docs_generic.py & + python scripts/notion_to_md.py & pids+=($!) fi