Bluehair Today 처음부터 따라 하는 사용 가이드#
대상: 시간표를 사용하는 사람, Windows 위젯을 설치하는 사람, 그리고 이후 유지·보수를 맡을 사람
기준 시간대: 모든 날짜와 시간은 Asia/Seoul(한국 시간) 입니다.
시간표 화면 상단의 사용 가이드를 누르면 Windows 위젯 화면에서도 이 문서를 언제든 다시 열 수 있습니다. 아직 로그인하지 않았다면 시간표 잠금 해제 창의 사용법 먼저 보기를 누르세요. 이 페이지 상단의 유지보수 인덱스는 운영·디버깅·확장 담당자를 위한 더 깊은 문서로 연결됩니다.
목차#
- 먼저 알아둘 것
- 매일 쓰는 가장 빠른 사용법
- 일정과 체크리스트 관리
- 실시간 동기화 확인
- Windows 데스크톱 위젯 설치와 자동 시작
- ChatGPT로 일정 편집하기
- 처음부터 로컬에서 실행하기
- 백업과 복구
- 문제 발생 시 초간단 진단
- 운영·보수·확장 인덱스
- 안전한 변경·배포 순서
1. 먼저 알아둘 것#
이 서비스는 무엇을 하나요?#
Bluehair Today는 하나의 시간표 데이터를 여러 화면에서 보여 줍니다.
| 사용하는 곳 | 하는 일 | 설치 필요 여부 |
|---|---|---|
| 웹 시간표 | 일정 추가·수정, 오늘의 흐름 확인, 체크리스트 완료 | 없음 |
| Windows 위젯 | 데스크톱 가장자리에 오늘·다음 일정을 상시 표시 | 최초 1회 |
| ChatGPT 앱 연결 | 대화로 일정·체크리스트 조회 및 편집 | 지원되는 ChatGPT 웹 워크스페이스에서만 |
저장 위치는 Cloudflare D1 데이터베이스 한 곳입니다. 웹, Windows 위젯, ChatGPT가 별도의 시간표를 갖는 구조가 아니므로, 한 곳에서 저장한 변경은 다른 곳에도 반영됩니다.
준비물#
- 웹 사용: 최신 Chrome 또는 Edge와 인터넷 연결
- 로그인: 시간표 소유자가 안전한 방법으로 전달한
APP_TOKEN - Windows 위젯 설치: Windows 10 1809 이상(Windows 11 권장), 인터넷 연결, WebView2 Runtime
- 소스에서 위젯까지 직접 빌드할 때만: .NET SDK 8.0, Windows SDK 10.0.19041 이상
APP_TOKEN은 Cloudflare 로그인 비밀번호나 API 토큰이 아닙니다. 시간표 잠금을 푸는 비밀값입니다. 채팅, GitHub 이슈, 소스 코드, 화면 공유, 명령 기록에 붙여 넣지 마세요.
운영 주소#
- 시간표: https://today.bluehair.blue
- 비상 대체 주소: https://timetable.odeye3217.workers.dev
- ChatGPT MCP 연결 주소: https://mcp.bluehair.blue/mcp
대체 주소는 custom domain 문제를 가려내는 용도입니다. 두 주소는 같은 운영 시간표를 가리킵니다.
2. 매일 쓰는 가장 빠른 사용법#
1단계 — 웹 시간표 열기#
- 브라우저에서 https://today.bluehair.blue를 엽니다.
- 처음에는 시간표 잠금 해제 창이 보입니다.
APP_TOKEN을 입력하고 연결을 누릅니다.- 화면 상단 상태가
실시간 연결 · 서울 시간이 되면 정상입니다.
토큰 자체는 브라우저에 저장되지 않습니다. 로그인 뒤에는 7일 동안 유효한 보안 세션 쿠키가 사용되며, 만료되거나 로그아웃하면 다시 토큰을 입력합니다.
2단계 — 화면 읽는 법#
| 화면 요소 | 뜻 |
|---|---|
| 현재 | 지금 진행 중인 일정입니다. 종료 시간이 있으면 진행률도 표시합니다. |
| 다음 일정 | 곧 시작할 일정과 남은 시간입니다. |
| 오늘 | 반복 일정과 오늘 날짜의 단발성 할 일을 시간순으로 보여 줍니다. |
| 체크리스트 | 오늘만의 완료 여부를 기록합니다. 내일이 되면 다시 미완료로 시작합니다. |
| 단발성 할 일 | 특정 날짜에 한 번만 해야 하는 일입니다. |
| 반복 시간표 | 요일마다 반복되는 일정입니다. |
위젯 보기 |
같은 웹 앱을 간결한 위젯 화면으로 엽니다. |
일정 상태는 시간이 흐르면서 자동으로 바뀝니다. 별도 새로고침 없이 현재 시간, 진행 중인 일, 다음 일정이 갱신됩니다.
3단계 — 오늘 할 일 하나를 빠르게 추가하기#
- 화면 중간의 빠른 입력 · 단발성 할 일에서 제목을 입력합니다.
- 날짜, 시작 시간(선택), 분류를 고릅니다.
- 추가를 누릅니다.
종료 시간이나 상세 메모까지 필요하면 상단의 할 일 추가를 사용하세요. 추가 직후에는 다른 화면에도 자동으로 반영됩니다.
4단계 — 오늘 끝낸 것을 체크하기#
- 단발성 할 일: 제목 왼쪽의 빈 체크 버튼을 누릅니다.
- 체크리스트: 항목 자체를 누릅니다.
한 번 더 누르면 완료를 취소할 수 있습니다. 체크리스트의 완료는 오늘 날짜에만 적용됩니다.
3. 일정과 체크리스트 관리#
단발성 할 일 추가·수정·삭제#
상세하게 새로 추가하기
- 상단의 할 일 추가를 누릅니다.
- 제목, 상세, 날짜, 시작·종료 시간, 분류를 입력합니다.
- 저장을 누릅니다.
제목은 1~120자, 상세 메모는 최대 600자입니다. 시작·종료 시간은 비워 둘 수 있습니다. 시간은 HH:MM 형식으로 처리됩니다.
이미 만든 할 일 바꾸기 또는 삭제하기
- 단발성 할 일 목록에서 할 일의 제목을 누릅니다.
- 필요한 값을 고치고 저장을 누릅니다.
- 지우려면 편집 창의 삭제를 누른 뒤 확인합니다.
삭제는 되돌리기 버튼이 없으므로, 중요한 대량 정리 전에는 백업을 먼저 만드세요.
반복 시간표 추가·수정·삭제#
새 반복 일정 추가하기
- 주간 계획 · 반복 시간표의 반복 일정 추가를 누릅니다.
- 요일, 제목, 시작 시간(필수), 종료 시간(선택), 분류와 상세를 입력합니다.
- 저장을 누릅니다.
반복 일정 수정 또는 삭제하기
- 주간 표의 일정 카드를 누릅니다. 주말 일정은 해당 날짜의 오늘 화면에서 카드를 누릅니다.
- 내용을 수정하고 저장하거나, 삭제를 누릅니다.
반복 일정은 매주 같은 요일에 나타납니다. 특정 하루에만 해야 할 일은 반복 일정을 만들지 말고 단발성 할 일로 추가하세요.
체크리스트 사용 범위#
웹 화면에서는 기존 체크리스트 항목의 오늘 완료/해제를 할 수 있습니다. 체크리스트 항목 자체의 추가·문구 수정·비활성화는 현재 웹 화면에 버튼이 없으므로, ChatGPT MCP 연결을 사용하거나 운영자가 API를 통해 관리해야 합니다.
ChatGPT로 요청할 때는 다음처럼 날짜와 원하는 결과를 분명히 적으세요.
체크리스트에 "단어 30개 복습"을 추가해 줘.
체크리스트 "단어 30개 복습"의 문구를 "단어 50개 복습"으로 바꿔 줘.
<YYYY-MM-DD>의 "단어 50개 복습"을 완료로 표시해 줘.
분류는 이렇게 쓰입니다#
| 화면에 보이는 이름 | 저장되는 분류 |
|---|---|
| 영어 | english |
| 실전 | exam |
| 콘텐츠 | content |
| 복습 | review |
| 휴식 | rest |
4. 실시간 동기화 확인#
정상 동기화 확인 방법#
- PC 웹 시간표와 Windows 위젯을 모두 엽니다. 또는 서로 다른 두 브라우저 창에서 같은 시간표에 로그인합니다.
- 두 화면 모두 상단에
실시간 연결또는동기화됨상태가 보이는지 확인합니다. - 한 화면에서 단발성 할 일을 하나 추가합니다.
- 다른 화면에 새 항목이 나타나는지 확인합니다.
각 저장은 데이터의 새 버전(rev)을 만들고 연결된 화면에 변경 신호를 보냅니다. 신호를 받은 화면은 서버의 최신 데이터로 다시 읽기 때문에, PC·위젯·ChatGPT에서 만든 일정이 같은 기준으로 보입니다.
상태 문구별 의미#
| 상태 | 의미와 할 일 |
|---|---|
실시간 연결 · 서울 시간 |
정상입니다. 그대로 사용하세요. |
동기화됨 · 재연결 대기 |
최근 데이터는 받았지만 실시간 연결을 다시 여는 중입니다. 잠시 기다리거나 새로고침을 누르세요. |
실시간 연결 재시도 중… |
네트워크 또는 WebSocket이 잠시 끊겼습니다. 인터넷이 살아 있으면 자동 재시도합니다. |
오프라인 · 마지막 동기화 데이터 |
마지막으로 정상 수신한 내용을 읽는 중입니다. 이 상태에서는 저장이 성공하지 않습니다. 온라인이 된 뒤 다시 시도하세요. |
네트워크 연결이 필요합니다 |
처음 불러올 데이터가 없습니다. 인터넷과 주소를 확인하세요. |
다른 기기에서 바꾼 내용이 늦어지면 먼저 새로고침을 한 번 누르세요. 그래도 보이지 않으면 초간단 진단을 따릅니다.
5. Windows 데스크톱 위젯 설치와 자동 시작#
이미 설치되어 있는 경우#
시작 메뉴에서 Bluehair Today를 실행합니다. 첫 실행에는 위젯 안의 로그인 화면에서 APP_TOKEN을 입력합니다. 위젯의 로그인 정보는 일반 브라우저와 분리된 WebView2 프로필에 안전하게 보관되므로, 웹에서 이미 로그인했더라도 위젯에서는 한 번 더 로그인해야 할 수 있습니다.
창을 닫으면 앱이 종료되지 않고 트레이로 숨겨집니다. 트레이의 Bluehair Today 아이콘을 더블클릭하거나 우클릭 메뉴의 보이기를 선택하면 다시 열립니다. 완전히 끝내려면 트레이 메뉴의 종료를 사용합니다.
소스에서 처음 설치하기#
이 저장소를 받은 뒤 PowerShell에서 아래를 실행합니다. 관리자 권한은 필요 없습니다.
아래의 <REPOSITORY_PATH>는 이 저장소를 내려받은 실제 폴더로 바꿉니다. 예: C:\Projects\timetable-cloudflare.
Set-Location "<REPOSITORY_PATH>\windows"
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\Install.ps1 -StartOnLogin
Install.ps1는 빌드 결과가 없으면 먼저 자체 포함형 x64 앱을 만들고, 현재 사용자 계정의 아래 경로에 설치한 뒤 실행합니다.
%LOCALAPPDATA%\Bluehair\TodayWidget\App
.NET SDK 8.0 was not found 또는 WebView2 관련 오류가 나오면 .NET 8 SDK와 WebView2 Runtime을 설치한 뒤 같은 명령을 다시 실행하세요. Windows SDK는 소스에서 새로 빌드할 때만 필요합니다.
위젯을 원하는 대로 배치하기#
- 위쪽 바를 끌어 원하는 위치로 옮기고, 창 가장자리를 드래그해 크기를 바꿉니다.
- 위젯 상단의 오른쪽 맞춤 버튼 또는 트레이 메뉴 오른쪽 가장자리에 맞추기를 사용합니다.
- 핀 버튼 또는 트레이 메뉴 항상 위를 켜면 다른 창 위에 남습니다. 기본값은 꺼짐입니다.
- 위젯 상단의 전체 플래너 버튼 또는 트레이 메뉴 전체 플래너 열기는 일반 브라우저에서 전체 시간표를 엽니다.
위젯 모드는 지나간 일정과 완료된 일을 줄이고, 최대 여섯 개의 관련 일정을 보여 줍니다. 전체 편집은 전체 플래너 열기에서 하는 것이 편합니다.
로그인할 때마다 자동으로 띄우기#
설치 때 -StartOnLogin을 사용했다면 이미 켜져 있습니다. 이후에는 트레이 아이콘을 우클릭해 Windows 로그인 시 시작을 체크/해제하면 됩니다.
PowerShell로 바꾸려면 다음 명령을 사용합니다.
Set-Location "<REPOSITORY_PATH>\windows"
# 켜기
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\Set-Startup.ps1 -Mode Enable
# 끄기
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\Set-Startup.ps1 -Mode Disable
자동 시작은 현재 사용자 계정의 HKCU\Software\Microsoft\Windows\CurrentVersion\Run에만 등록됩니다. 관리자 권한이나 전체 PC 설정을 바꾸지 않습니다.
6. ChatGPT로 일정 편집하기#
먼저 확인할 제한#
이 연결은 mcp.bluehair.blue의 별도 OAuth MCP 서버입니다. 현재 프로젝트 기준으로 ChatGPT 웹의 Business, Enterprise 또는 Edu 워크스페이스에서 Developer Mode와 앱 생성 권한이 있는 경우에 사용하도록 구성되어 있습니다. ChatGPT 모바일 앱에서는 custom MCP 앱 연결을 지원하지 않습니다.
ChatGPT의 기본 예약 작업(Scheduled Tasks) 저장소와 이 시간표 데이터베이스는 자동 양방향 동기화되지 않습니다. 예약 작업의 프롬프트가 연결된 도구를 호출하도록 만들 수는 있지만, 예약 작업 자체가 시간표로 복사되지는 않습니다.
처음 연결하기#
ChatGPT 웹에서 워크스페이스 설정을 엽니다.
Apps에서 Developer Mode를 활성화하고 Create를 선택합니다. 이 메뉴가 없으면 워크스페이스 관리자에게 권한을 요청합니다.
MCP endpoint에 다음 주소를 넣습니다.
https://mcp.bluehair.blue/mcp인증 방식으로 OAuth를 선택하고 Scan Tools를 누릅니다.
인증 화면에서 시간표
APP_TOKEN을 입력하고 요청된 권한을 승인합니다.앱 초안을 만든 뒤 새 웹 대화에서 앱을 켭니다.
첫 요청은 읽기 전용으로 확인합니다. 예:
이번 주 시간표를 보여 줘.
ChatGPT에는 시간표 비밀값이 전달·저장되지 않습니다. OAuth 연결 뒤에는 서버 내부의 안전한 연결이 시간표 API를 호출합니다.
대화로 정확히 편집하는 요령#
쓰기 작업은 삭제·덮어쓰기가 될 수 있으므로 ChatGPT의 확인 내용을 읽고 승인하세요. 날짜와 시간을 가능한 한 절대 형식으로 적으면 오해가 줄어듭니다.
<YYYY-MM-DD> 19:00부터 20:00까지 "모의고사 오답 정리"를 단발성 할 일로 추가해 줘. 분류는 복습.
매주 수요일 07:30에 시작하는 "영어 단어" 반복 일정을 만들어 줘. 종료 시간은 08:00.
<YYYY-MM-DD>의 "모의고사 오답 정리"를 완료로 바꿔 줘.
ChatGPT에서 저장한 뒤 웹 또는 위젯을 보면 같은 변경이 실시간으로 반영되어야 합니다. 반영이 늦으면 실시간 동기화 확인의 절차로 점검합니다.
7. 처음부터 로컬에서 실행하기#
이 절은 운영 중인 주소를 쓰는 일반 사용자에게는 필요 없습니다. 로컬에서 수정·테스트하거나 운영 환경을 재구성하는 담당자용입니다.
로컬 개발 환경 준비#
필요한 것: Node.js 22 이상, pnpm, Cloudflare 계정 권한. 아래에서 <LOCAL_DEVELOPMENT_TOKEN>은 운영 토큰과 다른 로컬 전용 값으로 바꾸세요.
Set-Location "<REPOSITORY_PATH>"
pnpm install --frozen-lockfile
Copy-Item .dev.vars.example .dev.vars
.dev.vars를 열어 다음처럼 입력합니다. 이 파일은 Git에 올리지 않습니다.
APP_TOKEN=<LOCAL_DEVELOPMENT_TOKEN>
이어서 로컬 D1 데이터베이스를 만들고 기본 시간표를 넣은 뒤 앱을 시작합니다.
pnpm types
pnpm db:migrate:local
pnpm db:seed:local
pnpm dev
브라우저에서 http://localhost:8787을 열고, 방금 .dev.vars에 넣은 로컬 전용 토큰으로 로그인합니다. 로컬 데이터는 .wrangler/에 있으며 운영 D1과 분리되어 있으므로, 로컬에서 추가·삭제한 내용이 운영 시간표에는 나타나지 않습니다.
운영 Worker를 처음 배포하거나 다시 배포할 때#
이미 운영 중인 today.bluehair.blue를 단순히 사용하는 경우에는 실행하지 마세요. Cloudflare 권한이 있는 운영자만, 백업과 검토 후 진행합니다.
Set-Location "<REPOSITORY_PATH>"
pnpm exec wrangler login
pnpm check
pnpm exec wrangler secret put APP_TOKEN
pnpm exec wrangler d1 migrations apply timetable --remote
pnpm exec wrangler deploy --dry-run
pnpm exec wrangler deploy
초기 데이터가 정말 필요한 새 데이터베이스에서만 다음을 추가로 실행합니다.
pnpm exec wrangler d1 execute timetable --remote --file=./seed.sql
ChatGPT MCP도 운영한다면 두 Worker의 APP_TOKEN은 같은 값이어야 합니다. 토큰을 교체할 때는 시간표 Worker와 MCP Worker의 secret을 함께 교체하고, 새 토큰으로 웹 로그인과 ChatGPT 읽기 요청을 각각 확인합니다.
8. 백업과 복구#
백업 원칙#
- 이 프로젝트에는 자동 예약 백업 기능이 구현되어 있지 않습니다. 스키마 변경, 대량 삭제, 토큰 교체 전에는 수동 백업을 만드세요.
- 백업 SQL에는 일정 제목과 날짜 등 개인 데이터가 들어갈 수 있습니다. Git 저장소 밖의 접근 제한된 폴더에 보관합니다.
- 복구는 운영 데이터를 덮어쓰거나 중복시킬 수 있는 작업입니다. 반드시 먼저 새 백업을 만들고, 영향 범위를 확인하세요.
운영 D1을 SQL 파일로 백업하기#
아래 명령은 운영 데이터베이스 timetable의 스키마와 데이터를 하나의 SQL 파일로 내보냅니다.
Set-Location "<REPOSITORY_PATH>"
$backupRoot = Join-Path $env:USERPROFILE "Documents\BluehairBackups"
New-Item -ItemType Directory -Force -Path $backupRoot | Out-Null
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
$backupFile = Join-Path $backupRoot "timetable-$stamp.sql"
pnpm exec wrangler d1 export timetable --remote --output $backupFile
Get-FileHash $backupFile -Algorithm SHA256
파일 이름, 생성 시각, SHA-256 해시를 별도 보관하면 나중에 백업 파일이 바뀌지 않았는지 확인할 수 있습니다.
먼저 해 볼 안전한 복구: 별도 D1에 가져오기#
운영 데이터베이스에 바로 SQL을 실행하지 마세요. 우선 새 복구용 데이터베이스에 백업을 불러와 내용이 맞는지 확인합니다.
Set-Location "<REPOSITORY_PATH>"
pnpm exec wrangler d1 create timetable-recovery
pnpm exec wrangler d1 execute timetable-recovery --remote --file "C:\Users\<YOUR_WINDOWS_USER>\Documents\BluehairBackups\timetable-<YYYYMMDD-HHMMSS>.sql"
pnpm exec wrangler d1 execute timetable-recovery --remote --command "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY name;"
timetable-recovery의 실제 생성 결과와 ID를 기록하세요. 이 별도 데이터베이스를 운영 Worker로 바꾸는 작업은 wrangler.jsonc의 D1 binding 변경과 재배포를 포함하므로, 안전한 변경·배포 순서를 따른 뒤 운영자가 수행합니다.
운영 D1을 과거 시점으로 되돌리기#
Cloudflare D1 Time Travel을 쓸 수 있는 계정이라면, 사고 전 시점의 bookmark를 확인한 뒤 복구합니다. 이 작업은 현재 운영 데이터베이스를 그 시점으로 덮어씁니다.
# 1) 현재 상태를 먼저 SQL로 백업한 뒤, 원하는 과거 시점의 bookmark를 확인
pnpm exec wrangler d1 time-travel info timetable --timestamp "<RFC3339_TIMESTAMP>"
# 2) 출력에 나타난 정확한 bookmark를 검토한 뒤에만 실행
pnpm exec wrangler d1 time-travel restore timetable --bookmark "<BOOKMARK_FROM_INFO>"
Time Travel 복구 직후 웹에서 새로고침을 눌러 결과를 확인하고, 일정·체크리스트·revision이 의도한 상태인지 확인하세요. 복구 전 bookmark도 적어 두면 다시 되돌릴 여지가 생깁니다. Cloudflare의 보존 기간과 플랜 조건은 변할 수 있으므로 실행 전 D1 Time Travel 문서를 확인하세요.
9. 문제 발생 시 초간단 진단#
아래 순서대로만 확인하면 대부분의 문제를 분리할 수 있습니다. 비밀값을 로그·스크린샷·채팅에 넣지 마세요.
| 증상 | 먼저 할 일 | 그래도 안 되면 |
|---|---|---|
| 로그인에 실패함 | APP_TOKEN 앞뒤 공백 없이 다시 입력 |
시간표 소유자에게 현재 토큰 확인을 요청합니다. Cloudflare API 토큰을 넣은 것은 아닌지 확인합니다. |
| 다른 화면의 변경이 안 보임 | 양쪽 화면에서 새로고침을 누르고 상태 문구 확인 | 한 화면을 닫았다 다시 열고 로그인 상태를 확인합니다. 둘 다 같은 운영 주소를 쓰는지 확인합니다. |
오프라인 · 마지막 동기화 데이터 |
인터넷 연결을 복구 | 운영 주소와 대체 주소를 각각 열어 봅니다. 읽기는 되지만 저장은 온라인이 될 때까지 하지 마세요. |
today.bluehair.blue만 안 열림 |
대체 주소를 엽니다 | 대체 주소도 안 되면 서비스/네트워크 문제입니다. 대체 주소만 되면 DNS·custom domain 문제입니다. |
| 위젯이 안 보임 | 트레이 아이콘을 찾아 보이기를 누릅니다 | 트레이 메뉴에서 종료 후 시작 메뉴의 Bluehair Today를 다시 실행합니다. |
| 위젯이 WebView2 오류를 보임 | Windows 업데이트와 WebView2 Runtime을 확인 | 아래의 Smoke Test와 로그 위치를 확인합니다. |
| Windows 부팅 후 위젯이 안 뜸 | 트레이 메뉴의 Windows 로그인 시 시작이 체크됐는지 확인 | Set-Startup.ps1 -Mode Enable을 실행합니다. |
| ChatGPT에 앱 생성/Developer Mode 메뉴가 없음 | ChatGPT 웹, 올바른 워크스페이스인지 확인 | 워크스페이스 관리자에게 Developer Mode와 앱 생성 권한을 요청합니다. |
Windows 위젯 자체 점검#
Set-Location "<REPOSITORY_PATH>\windows"
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\Smoke-Test.ps1
성공하면 WebView2 Runtime, 앱 셸, 프로필 경로, 대상 URL을 JSON으로 출력합니다. 오류 로그는 다음 위치에 날짜별로 남습니다.
%LOCALAPPDATA%\Bluehair\TodayWidget\Data\Logs\today-widget-YYYYMMDD.log
기본 점검에서 사용자 데이터 폴더를 바로 지우지 마세요. 이 폴더에는 위젯 창 설정과 로그인 WebView2 프로필이 들어 있습니다. 정말 초기화해야 할 때는 위젯을 트레이 메뉴에서 종료하고, 먼저 폴더를 백업한 뒤에만 제거합니다.
운영자용 서버 진단#
Cloudflare 인증이 된 터미널에서 아래 명령을 실행하면 운영 Worker의 실시간 요청·예외를 볼 수 있습니다.
Set-Location "<REPOSITORY_PATH>"
pnpm exec wrangler tail
민감한 요청 본문이나 토큰을 직접 출력하는 로그는 추가하지 마세요. Worker의 운영 로그는 Cloudflare Dashboard의 Workers & Pages → timetable → Logs에서도 확인할 수 있습니다.
10. 운영·보수·확장 인덱스#
먼저 찾을 파일#
| 바꾸려는 것 | 주 파일 | 함께 확인할 것 | 최소 검증 |
|---|---|---|---|
| 웹 화면·문구·버튼 | public/index.html, public/app.js, public/styles.css |
public/timetable-core.js, test/web-core.test.js, public/sw.js |
pnpm test |
| 현재·다음 일정 계산 | public/timetable-core.js |
test/web-core.test.js |
pnpm test |
| API, 입력 검증, 로그인 | src/index.ts |
test/worker.test.ts, wrangler.jsonc |
pnpm typecheck, pnpm test |
| DB 테이블·인덱스 | migrations/ |
src/index.ts, seed.sql, Worker 테스트 |
로컬 migration + 전체 검사 |
| 기본 시간표 데이터 | seed.sql |
실제 운영 데이터와 중복·영향 여부 | 로컬 DB에서 먼저 확인 |
| 실시간 동기화 | src/index.ts의 SyncHub, public/app.js |
revision 증가, /api/changes, /ws |
Worker 테스트 + 두 화면 수동 확인 |
| Windows 위젯 | windows/src/TodayWidget/ |
windows/scripts/, windows/README.md |
windows\scripts\Build.ps1, Smoke-Test.ps1 |
| 로그인 시 자동 실행 | windows/src/TodayWidget/Infrastructure/StartupManager.cs |
windows/scripts/Set-Startup.ps1 |
설치 후 재로그인 확인 |
| ChatGPT 도구/OAuth | integrations/chatgpt-mcp/src/index.ts |
해당 폴더의 wrangler.jsonc, 테스트, README |
MCP 폴더의 검사 명령 전부 |
| 도메인·D1·Durable Object binding | wrangler.jsonc |
worker-configuration.d.ts, Cloudflare Dashboard |
pnpm types, pnpm check |
| CI | .github/workflows/ci.yml |
루트 및 MCP의 lockfile | GitHub Actions 녹색 확인 |
| 사용자·운영 문서 | docs/USER_GUIDE_KO.md, docs/MAINTENANCE_INDEX_KO.md |
scripts/build-docs.mjs, public/docs.css |
pnpm docs:build, pnpm docs:check |
변경할 때 지켜야 하는 구조#
- D1에 직접 쓰는 새 클라이언트를 만들지 않습니다. 브라우저, Windows, ChatGPT의 쓰기는 모두 주 Worker API를 거쳐야 합니다.
- 저장 성공 뒤에는 revision 증가와 Durable Object의 invalidation 알림이 유지되어야 합니다. 이 흐름이 깨지면 다른 화면이 최신 데이터를 다시 읽지 못합니다.
- 스키마 변경은 새 migration 파일로 추가합니다. 이미 배포된 migration을 고쳐서 과거 환경을 불일치하게 만들지 않습니다.
APP_TOKEN은 source,wrangler.jsonc,.dev.vars.example, GitHub Actions 출력에 넣지 않습니다. 운영 값은wrangler secret put APP_TOKEN으로만 설정합니다.- 웹 앱 껍데기(
index.html,styles.css,app.js,timetable-core.js, manifest, icon)를 바꾸면public/sw.js의CACHE버전을 함께 올립니다. 그렇지 않으면 설치된 PWA가 이전 파일을 계속 사용할 수 있습니다. - Windows 위젯의
Data폴더에는 창 설정과 로그인 세션이 있으므로, 앱 업데이트 때App만 교체하고Data는 유지합니다. - ChatGPT MCP는 D1 binding을 갖지 않습니다.
TIMETABLE_APIService Binding을 통해서만 주 Worker를 호출합니다.
테스트 명령 모음#
루트 프로젝트에서 다음 순서로 실행합니다.
pnpm install --frozen-lockfile
pnpm docs:check
pnpm types
pnpm types:check
pnpm typecheck
pnpm test
pnpm check
pnpm check은 wrangler deploy --dry-run입니다. 설정과 배포 가능성을 확인할 뿐 실제 운영 배포는 하지 않습니다.
ChatGPT MCP 변경은 별도 폴더에서 따로 검사합니다.
Set-Location integrations\chatgpt-mcp
pnpm install --frozen-lockfile --ignore-workspace
pnpm types
pnpm typecheck
pnpm test
pnpm check
Windows 위젯 변경은 다음처럼 빌드하고, 배포본을 만들었으면 Smoke Test도 실행합니다.
Set-Location windows
.\scripts\Build.ps1 -Configuration Release
.\scripts\Publish.ps1
.\scripts\Smoke-Test.ps1
11. 안전한 변경·배포 순서#
운영에 영향을 주는 변경은 아래 순서를 따릅니다.
- 범위 정하기 — 웹만, Worker/API, DB, Windows, MCP 중 무엇이 바뀌는지 위 인덱스에서 확인합니다.
- 백업 — 스키마·데이터·삭제 관련 변경 전에는 운영 D1 SQL 백업을 만듭니다.
- 로컬 검증 — 가능한 한 로컬 D1에서 migration과 UI를 먼저 검증합니다.
- 자동 검사 — 해당 패키지의 typecheck, test, dry-run을 모두 통과시킵니다.
- 변경 검토 —
git diff로 토큰, D1 ID, 도메인, 삭제 SQL이 의도치 않게 바뀌지 않았는지 확인합니다. - 운영 배포 — 담당자 검토 후에만
pnpm exec wrangler deploy를 실행합니다. CI는 검증만 하며 자동 배포하지 않습니다. - 즉시 확인 — 운영 주소에서 로그인, 일정 추가·수정, 다른 화면의 실시간 반영, Windows 위젯, 필요 시 ChatGPT 읽기 요청을 확인합니다.
- 기록 — 변경 시각, 배포 commit, 백업 파일명·해시, 점검 결과를
docs/WORKLOG.md또는 PR에 남깁니다. 비밀값은 기록하지 않습니다.
문제가 생기면 먼저 새 백업을 만든 뒤, 마지막으로 정상 동작하던 배포·D1 bookmark를 확인합니다. 데이터 복구와 코드 롤백은 서로 다른 작업이므로, 한 번에 둘 다 바꾸지 말고 하나씩 확인하세요.