docs: overhaul README with modern design philosophy and standardize CalDAV/Android sync guidelines
Build and Push Docker Image / build-and-push (push) Failing after 1m41s
Build and Push Docker Image / build-and-push (push) Failing after 1m41s
This commit is contained in:
+2
-1
@@ -20,14 +20,15 @@
|
|||||||
- Verified 100% implementation of core features: n-depth recursive checklist, real-time subtask synchronization, modular blocks & split resizer, 3-way theme (VSCode dark / pastel light / system), global `UserPrefs` customization, Labs Kanban view, and mobile bottom sheet.
|
- Verified 100% implementation of core features: n-depth recursive checklist, real-time subtask synchronization, modular blocks & split resizer, 3-way theme (VSCode dark / pastel light / system), global `UserPrefs` customization, Labs Kanban view, and mobile bottom sheet.
|
||||||
- Enhanced CalDAV / DAVx⁵ synchronization endpoint (`src/app/api/dav/[...path]/route.ts`) with full RFC 4791 support: `OPTIONS`, `PROPFIND` (principal & calendar collection discovery), `REPORT` (calendar-query/multiget), `PUT` (task upsert from VTODO), and `DELETE`.
|
- Enhanced CalDAV / DAVx⁵ synchronization endpoint (`src/app/api/dav/[...path]/route.ts`) with full RFC 4791 support: `OPTIONS`, `PROPFIND` (principal & calendar collection discovery), `REPORT` (calendar-query/multiget), `PUT` (task upsert from VTODO), and `DELETE`.
|
||||||
- Upgraded Settings Modal "Integrations (CalDAV)" tab with multi-platform interactive guides (Android/DAVx⁵, Apple Reminders, Thunderbird), one-click URL copy feedback, ICS feed direct download, and live endpoint test ping.
|
- Upgraded Settings Modal "Integrations (CalDAV)" tab with multi-platform interactive guides (Android/DAVx⁵, Apple Reminders, Thunderbird), one-click URL copy feedback, ICS feed direct download, and live endpoint test ping.
|
||||||
|
- Standardized all synchronization terminology from brand-specific references to open standards and Android/Apple cross-platform guidelines.
|
||||||
- Implemented full-fidelity standard Task Export pair (`/api/export`) supporting RFC 4180 / TickTick-compatible CSV with UTF-8 BOM, and RFC 5545 iCalendar (`.ics` VTODO) format.
|
- Implemented full-fidelity standard Task Export pair (`/api/export`) supporting RFC 4180 / TickTick-compatible CSV with UTF-8 BOM, and RFC 5545 iCalendar (`.ics` VTODO) format.
|
||||||
- Added Export modal in Sidebar user popover menu supporting format selection, target list filtering, completed tasks inclusion toggle, and seamless Demo mode client-side Blob generation.
|
- Added Export modal in Sidebar user popover menu supporting format selection, target list filtering, completed tasks inclusion toggle, and seamless Demo mode client-side Blob generation.
|
||||||
- Added localized i18n strings for Export across English, Korean, and Japanese.
|
- Added localized i18n strings for Export across English, Korean, and Japanese.
|
||||||
- Migrated repository and commit history to self-hosted Gitea remote origin.
|
|
||||||
- Configured production multi-stage `Dockerfile` with standalone Next.js runner, Prisma CLI migrations support, and automated `docker-entrypoint.sh` startup script.
|
- Configured production multi-stage `Dockerfile` with standalone Next.js runner, Prisma CLI migrations support, and automated `docker-entrypoint.sh` startup script.
|
||||||
- Added `.dockerignore` for minimal context transfer and fast build times.
|
- Added `.dockerignore` for minimal context transfer and fast build times.
|
||||||
- Refined `docker-compose.yml` and `.env.example` to support prebuilt registry images (`CHECKFLOW_IMAGE`) and automated database migrations.
|
- Refined `docker-compose.yml` and `.env.example` to support prebuilt registry images (`CHECKFLOW_IMAGE`) and automated database migrations.
|
||||||
- Automated Gitea Actions CI workflow (`.gitea/workflows/docker-build.yaml`) for building & pushing container images to Gitea Container Registry.
|
- Automated Gitea Actions CI workflow (`.gitea/workflows/docker-build.yaml`) for building & pushing container images to Gitea Container Registry.
|
||||||
|
- Completely revamped `README.md` to reflect project design philosophy, architecture, Docker setup, and open-standard CalDAV sync guidelines.
|
||||||
- Validated that `npm run lint` and `npm run build` execute with 0 errors and 0 warnings.
|
- Validated that `npm run lint` and `npm run build` execute with 0 errors and 0 warnings.
|
||||||
|
|
||||||
- **Next Steps (Todo):**
|
- **Next Steps (Todo):**
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
3. **외부 플랫폼 연동 & Import/Export**:
|
3. **외부 플랫폼 연동 & Import/Export**:
|
||||||
- TickTick 등 외부 플랫폼과의 호환을 위한 **CSV 및 ICS(iCalendar) 파일 Import/Export 완벽 지원** (하단 프로필 메뉴 내 배치).
|
- TickTick 등 외부 플랫폼과의 호환을 위한 **CSV 및 ICS(iCalendar) 파일 Import/Export 완벽 지원** (하단 프로필 메뉴 내 배치).
|
||||||
- Formula Injection 방어(`sanitizeFormula`) 및 Excel 호환 UTF-8 BOM 지원.
|
- Formula Injection 방어(`sanitizeFormula`) 및 Excel 호환 UTF-8 BOM 지원.
|
||||||
- Galaxy(Android) 폰 연동: DAVx⁵ 앱을 통한 CalDAV/CardDAV (`/api/dav`) 동기화 지원.
|
- Android 모바일 연동: DAVx⁵ 앱을 통한 CalDAV (`/api/dav`) 표준 양방향 동기화 지원.
|
||||||
4. **PWA (Progressive Web App)**:
|
4. **PWA (Progressive Web App)**:
|
||||||
- 모바일/데스크톱 설치 가능 및 오프라인 캐싱 지원 (`manifest.json`, `sw.js`).
|
- 모바일/데스크톱 설치 가능 및 오프라인 캐싱 지원 (`manifest.json`, `sw.js`).
|
||||||
5. **모바일 바텀시트 드로어**:
|
5. **모바일 바텀시트 드로어**:
|
||||||
@@ -119,7 +119,7 @@ src/
|
|||||||
- 목록별 필터링 및 완료 태스크 포함 여부 선택 모달
|
- 목록별 필터링 및 완료 태스크 포함 여부 선택 모달
|
||||||
- [x] **CalDAV 양방향 동기화 및 가이드 고도화**:
|
- [x] **CalDAV 양방향 동기화 및 가이드 고도화**:
|
||||||
- RFC 4791 표준 준수: `OPTIONS`, `PROPFIND` (Principal & Collection 탐색), `REPORT` (VTODO 쿼리), `PUT` (태스크 업서트), `DELETE`
|
- RFC 4791 표준 준수: `OPTIONS`, `PROPFIND` (Principal & Collection 탐색), `REPORT` (VTODO 쿼리), `PUT` (태스크 업서트), `DELETE`
|
||||||
- 설정 모달 내 플랫폼별 인터랙티브 가이드 (Samsung Galaxy / DAVx⁵, Apple 미리알림, Thunderbird)
|
- 설정 모달 내 플랫폼별 인터랙티브 가이드 (Android / DAVx⁵, Apple 미리알림, Thunderbird)
|
||||||
- 실시간 엔드포인트 응답 상태 테스트 및 ICS 피드 다운로드 기능
|
- 실시간 엔드포인트 응답 상태 테스트 및 ICS 피드 다운로드 기능
|
||||||
- [x] **TickTick 스타일 스마트 퀵애드 툴바** (날짜, 우선순위 프리셋)
|
- [x] **TickTick 스타일 스마트 퀵애드 툴바** (날짜, 우선순위 프리셋)
|
||||||
- [x] **상단 프로젝트 브레드크럼 & 리스트 이동기** (`📁 프로젝트명 ▾`)
|
- [x] **상단 프로젝트 브레드크럼 & 리스트 이동기** (`📁 프로젝트명 ▾`)
|
||||||
|
|||||||
@@ -1,117 +1,224 @@
|
|||||||
# CheckFlow
|
<div align="center">
|
||||||
|
|
||||||
> 셀프호스팅 TickTick-like Todo 앱 — 계층형 체크리스트 + 메모장 + CardDAV + PWA
|
# ⚡ CheckFlow
|
||||||
|
|
||||||

|
**프라이버시 중심의 독립형 스마트 태스크 & 마크다운 워크스페이스**
|
||||||
|
*A modern, self-hosted, privacy-first task management & note workspace built for focus, speed, and open-standard freedom.*
|
||||||
|
|
||||||
## 주요 기능
|
<br/>
|
||||||
|
|
||||||
- ✅ **계층형 체크리스트** — 메인 태스크 + 하위 태스크
|
[](https://nextjs.org/)
|
||||||
- 📝 **태스크 메모장** — 넓은 노트 영역 (Markdown 지원)
|
[](https://reactjs.org/)
|
||||||
- 👥 **멀티유저** — 각 사용자 데이터 완전 격리
|
[](https://www.typescriptlang.org/)
|
||||||
- 📱 **PWA** — Android 홈 화면 추가, 오프라인 지원
|
[](https://www.postgresql.org/)
|
||||||
- 📲 **CardDAV** — DAVx⁵ 앱으로 Galaxy 동기화
|
[](https://www.prisma.io/)
|
||||||
- 📥 **TickTick Import** — CSV/ICS 내보내기 파일 import
|
[](https://www.docker.com/)
|
||||||
- 🌙 **다크모드** — 시스템/수동 전환
|
[](https://tools.ietf.org/html/rfc4791)
|
||||||
- 🐳 **Docker** — 원클릭 배포
|
[](https://web.dev/progressive-web-apps/)
|
||||||
|
|
||||||
## 빠른 시작
|
<br/>
|
||||||
|
|
||||||
### 1. 환경 변수 설정
|
[✨ 핵심 기능](#-핵심-기능--디자인-철학) •
|
||||||
|
[🚀 빠른 시작 (Docker)](#-빠른-시작-docker-배포) •
|
||||||
|
[📱 CalDAV 모바일 연동](#-caldav-모바일-및-외부-앱-동기화) •
|
||||||
|
[📦 데이터 호환성](#-데이터-가져오기--내보내기) •
|
||||||
|
[🧪 Labs 커스터마이징](#-checkflow-labs--디자인-시스템) •
|
||||||
|
[🛠️ 개발 환경](#️-로컬-개발-환경)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 프로젝트 소개 & 디자인 철학
|
||||||
|
|
||||||
|
**CheckFlow**는 상용 클라우드 서비스(TickTick, Notion, Todoist 등)의 복잡성과 구독 모델, 데이터 종속에서 벗어나 **사용자 개인의 완벽한 데이터 주권**과 **군더더기 없는 미니멀리즘 작업 경험**을 제공하기 위해 설계된 독립형 웹 애플리케이션입니다.
|
||||||
|
|
||||||
|
- 🎯 **순수한 몰입감**: 산만한 툴바와 불필요한 장식을 배제하고, 에디터 본연의 텍스트 타이핑과 정갈한 마크다운 렌더링에 집중합니다.
|
||||||
|
- 🌲 **자유로운 계층화**: N단계 재귀적 하위 태스크 트리와 직관적인 인라인 수정을 통해 생각의 흐름을 그대로 구조화합니다.
|
||||||
|
- 🌐 **열린 표준**: 폐쇄적인 API 대신 **RFC 4791 CalDAV**, **RFC 5545 iCalendar (`.ics`)**, **RFC 4180 CSV** 표준을 준수하여 어떤 플랫폼에서든 자유롭게 동기화하고 백업할 수 있습니다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ 핵심 기능 & 디자인 철학
|
||||||
|
|
||||||
|
### 1. 🌲 N-Depth 재귀 하위 태스크 & 인라인 편집
|
||||||
|
- **무제한 계층 구조**: 단순 1단계 하위 작업을 넘어 원하는 만큼 서브태스크를 트리 형태로 중첩 확장할 수 있습니다.
|
||||||
|
- **실시간 양방향 동기화**: 중앙 체크리스트와 우측 상세 패널 간의 상태가 지연 없이 1:1로 실시간 동기화됩니다.
|
||||||
|
- **인라인 즉시 수정**: 목록 제목 및 태스크 제목을 더블클릭/클릭하여 즉시 인라인 수정할 수 있습니다 (`Enter` 저장, `ESC` 취소).
|
||||||
|
|
||||||
|
### 2. 📝 적응형(Adaptive) 와이드 마크다운 노트
|
||||||
|
- **넓은 캔버스 레이아웃**: 우측 상세 패널의 대부분을 시원한 노트 공간으로 활용할 수 있습니다.
|
||||||
|
- **뷰 & 에디트 듀얼 모드**: ✏️ 작성 중에는 부드러운 텍스트 에디터로, 👁️ 뷰 모드에서는 웹 문서 수준의 미려한 마크다운 GUI 뷰어로 렌더링됩니다.
|
||||||
|
- **보안 렌더링**: `DOMPurify` 기반의 철저한 XSS 방어 및 안전한 외부 링크(`rel="noopener noreferrer"`)를 지원합니다.
|
||||||
|
|
||||||
|
### 3. 🧪 CheckFlow Labs & 유연한 커스터마이징
|
||||||
|
- **📋 리스트 뷰 ↔ 📊 3컬럼 칸반 보드 원클릭 전환**: `To Do`, `In Progress`, `Done` 컬럼으로 할 일 상태를 시각적으로 관리합니다.
|
||||||
|
- **모듈형 블록 스왑 & 스플릿 리사이저**: 서브태스크 목록과 마크다운 메모장의 상하 위치를 원하는 대로 맞바꾸고(⇄), 마우스 드래그로 높이 비율(15%~85%)을 자유롭게 조절할 수 있습니다.
|
||||||
|
- **개인화 환경설정**: UI 밀도(Compact/Default/Comfortable), 글꼴 크기, 테두리 라운드, 반응형 애니메이션 속도, 액센트 색조(Hue) & 채도(Saturation)를 슬라이더로 조절할 수 있으며, 언제든 초기 순정 상태로 되돌릴 수 있습니다.
|
||||||
|
|
||||||
|
### 4. 🎨 VSCode 무채색 다크 테마 & 파스텔 매트 라이트
|
||||||
|
- 눈의 피로를 최소화하는 **VSCode 스타일 무채색 다크 팔레트** (`#181818`, `#1e1e1e`, `#252526`)와 **매트 파스텔 라이트 테마**, 시스템 동기화 모드를 지원합니다.
|
||||||
|
- 사이드바 및 우측 패널의 너비를 마우스 드래그로 실시간 리사이징할 수 있습니다.
|
||||||
|
|
||||||
|
### 5. 📱 모바일 바텀시트 드로어 & PWA
|
||||||
|
- 스마트폰 화면에서는 우측 상세 패널이 부드러운 **바텀시트(Bottom Sheet)**로 전환됩니다.
|
||||||
|
- 화면 아래로 스와이프하거나 백드롭 오버레이를 터치하여 자연스럽게 패널을 닫을 수 있습니다.
|
||||||
|
- PWA 매니페스트(`manifest.json`)와 서비스워커(`sw.js`)를 통해 앱처럼 홈 화면에 추가하고 오프라인 캐시를 활용할 수 있습니다.
|
||||||
|
|
||||||
|
### 6. 🌐 3개국어 다국어(i18n) 지원
|
||||||
|
- **영어(English)**, **한국어(Korean)**, **일본어(Japanese)** 3개 언어를 완벽하게 지원하며 브라우저 또는 설정에서 즉시 변경할 수 있습니다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 빠른 시작 (Docker 배포)
|
||||||
|
|
||||||
|
CheckFlow는 프로덕션 컨테이너 이미지와 자동 데이터베이스 마이그레이션을 지원하여 `docker compose` 명령 하나로 즉시 구동됩니다.
|
||||||
|
|
||||||
|
### 1. 환경 변수 구성
|
||||||
|
`.env.example` 파일을 복사하여 환경 변수를 설정합니다:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
# .env 파일에서 NEXTAUTH_SECRET 및 POSTGRES_PASSWORD 변경
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Docker로 실행
|
`.env` 파일 예시:
|
||||||
|
```env
|
||||||
|
# 데이터베이스 비밀번호 (프로덕션 환경에서는 안전한 비밀번호로 변경하세요)
|
||||||
|
POSTGRES_PASSWORD=your_secure_password
|
||||||
|
|
||||||
|
# 서비스 도메인 또는 접근 IP
|
||||||
|
NEXTAUTH_URL=http://localhost:3000
|
||||||
|
|
||||||
|
# NextAuth 인증 시크릿 키 (openssl rand -base64 32 등으로 생성)
|
||||||
|
NEXTAUTH_SECRET=your_generated_random_secret_string
|
||||||
|
|
||||||
|
# 외부 노출 포트 (기본값: 3000)
|
||||||
|
PORT=3000
|
||||||
|
|
||||||
|
# (선택사항) 커스텀 레지스트리 이미지를 사용할 경우
|
||||||
|
# CHECKFLOW_IMAGE=gitea.example.com/username/checkflow:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 컨테이너 실행
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
> 💡 컨테이너가 실행될 때 `docker-entrypoint.sh`가 PostgreSQL 헬스체크 후 **Prisma 스키마 마이그레이션을 자동으로 수행**하므로 별도의 수동 DB 설정 명령이 필요하지 않습니다.
|
||||||
|
|
||||||
앱이 시작되면:
|
브라우저에서 `http://localhost:3000`에 접속하여 첫 관리자/사용자 계정을 생성하세요.
|
||||||
```bash
|
|
||||||
# DB 마이그레이션 (최초 1회)
|
|
||||||
docker compose exec app npx prisma migrate deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
`http://localhost:3000` 접속 후 계정 생성.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 개발 환경 실행
|
## 📱 CalDAV 모바일 및 외부 앱 동기화
|
||||||
|
|
||||||
### 요구사항
|
CheckFlow는 **RFC 4791 CalDAV 표준 프로토콜**을 완벽하게 지원하여, 모바일 및 데스크톱 기본 캘린더/할 일 앱과 양방향으로 동기화됩니다.
|
||||||
|
|
||||||
|
- **CalDAV 기본 엔드포인트 URL**: `https://your-domain.com/api/dav`
|
||||||
|
- **사용자 이름**: CheckFlow 계정 이메일
|
||||||
|
- **비밀번호**: CheckFlow 계정 비밀번호
|
||||||
|
|
||||||
|
### 🤖 Android (DAVx⁵ + Tasks.org / OpenTasks)
|
||||||
|
1. F-Droid 또는 Google Play에서 **DAVx⁵** 앱을 설치합니다.
|
||||||
|
2. DAVx⁵ → 계정 추가(+) → **URL 및 사용자 이름으로 로그인** 선택.
|
||||||
|
3. 기본 URL(`https://your-domain.com/api/dav`), 이메일, 비밀번호 입력.
|
||||||
|
4. **VTODO (할 일)** 컬렉션을 활성화하면 **Tasks.org** 또는 **OpenTasks** 앱에서 실시간 양방향 동기화가 이루어집니다.
|
||||||
|
|
||||||
|
### 🍎 Apple Reminders (iOS / iPadOS / macOS)
|
||||||
|
1. 기기 설정 → **미리알림(Reminders)** → **계정** → **계정 추가**.
|
||||||
|
2. **기타** → **CalDAV 계정 추가** 선택.
|
||||||
|
3. 서버 주소, 이메일, 비밀번호 입력 후 미리알림 활성화.
|
||||||
|
|
||||||
|
### 💻 Mozilla Thunderbird (Windows / Linux / macOS)
|
||||||
|
1. Thunderbird 실행 → 캘린더 탭 → **새 캘린더** 생성.
|
||||||
|
2. **네트워크에 저장** → 형식: **CalDAV** 선택.
|
||||||
|
3. 위치에 기본 URL 입력 및 이메일/비밀번호 인증.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 데이터 가져오기 & 내보내기
|
||||||
|
|
||||||
|
언제든 외부 서비스와 자유롭게 데이터를 주고받거나 로컬 백업을 생성할 수 있습니다.
|
||||||
|
|
||||||
|
### 📥 TickTick 데이터 가져오기 (Import)
|
||||||
|
- TickTick 설정 → 데이터 내보내기에서 생성된 **CSV** 또는 **iCalendar (`.ics`)** 파일을 사이드바의 **가져오기** 메뉴에서 업로드하여 기존 할 일, 하위 태스크, 마감일, 우선순위를 그대로 복원합니다.
|
||||||
|
- Formula Injection 및 XSS 공격을 방어하는 보안 검증 모듈이 내장되어 있습니다.
|
||||||
|
|
||||||
|
### 📤 표준 포맷 데이터 내보내기 (Export)
|
||||||
|
- 사이드바 사용자 메뉴 → **내보내기** 선택.
|
||||||
|
- **TickTick 호환 RFC 4180 CSV** (Excel 호환 UTF-8 BOM 포함) 또는 **RFC 5545 iCalendar (`.ics` VTODO)** 형식 지원.
|
||||||
|
- 전체 할 일 또는 특정 목록 필터링, 완료 항목 포함 여부를 자유롭게 선택하여 즉시 다운로드할 수 있습니다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ 로컬 개발 환경
|
||||||
|
|
||||||
|
### 필수 요구사항
|
||||||
- Node.js 20+
|
- Node.js 20+
|
||||||
- PostgreSQL (또는 Docker)
|
- npm 또는 pnpm
|
||||||
|
- PostgreSQL (또는 개발용 SQLite)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 의존성 설치
|
# 1. 저장소 클론 및 패키지 설치
|
||||||
|
git clone https://git.nrh.kr/Neru_Han/checkflow.git
|
||||||
|
cd checkflow
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
# DB 설정
|
# 2. 환경 변수 설정
|
||||||
cp .env.example .env.local
|
cp .env.example .env.local
|
||||||
# .env.local의 DATABASE_URL을 DB에 맞게 수정
|
|
||||||
|
|
||||||
# DB 마이그레이션
|
# 3. Prisma DB 스키마 생성 및 클라이언트 빌드
|
||||||
npx prisma migrate dev
|
npx prisma db push
|
||||||
|
# 또는 SQLite 개발 모드: npm run dev:sqlite
|
||||||
|
|
||||||
# 개발 서버 시작
|
# 4. 로컬 개발 서버 시작 (Turbopack)
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
→ `http://localhost:3000`
|
브라우저에서 `http://localhost:3000` (체험 모드는 `http://localhost:3000/demo`)으로 접속합니다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## DAVx⁵로 Galaxy 연동
|
## 🏗️ 시스템 아키텍처 & 기술 스택
|
||||||
|
|
||||||
1. Play Store에서 **[DAVx⁵](https://play.google.com/store/apps/details?id=at.bitfire.davdroid)** 설치 (무료)
|
```
|
||||||
2. DAVx⁵ 앱 → **+** → Login with URL and user name
|
src/
|
||||||
- **URL**: `http://your-server:3000/api/dav`
|
├── app/
|
||||||
- **Username**: CheckFlow 이메일
|
│ ├── page.tsx ← 메인 앱 진입점 (NextAuth 세션 기반)
|
||||||
- **Password**: CheckFlow 비밀번호
|
│ ├── demo/page.tsx ← DB 연결 없이 LocalStorage 기반 완전 구동 데모
|
||||||
3. Task 목록 동기화 → Samsung Reminder 또는 Tasks 앱에서 확인
|
│ ├── admin/page.tsx ← 멀티유저 관리 및 시스템 대시보드 (ADMIN 전용)
|
||||||
|
│ ├── api/
|
||||||
|
│ │ ├── auth/ ← NextAuth 및 회원가입 엔드포인트
|
||||||
|
│ │ ├── lists/ & tasks/ ← 계층형 태스크 & 리스트 REST API (IDOR 소유권 검증)
|
||||||
|
│ │ ├── import/ & export/ ← RFC 4180 CSV / RFC 5545 ICS 파서 및 익스포터
|
||||||
|
│ │ └── dav/[...path]/ ← RFC 4791 CalDAV 프로토콜 엔드포인트
|
||||||
|
├── components/
|
||||||
|
│ ├── layout/
|
||||||
|
│ │ ├── AppShell.tsx ← 3-Panel 메인 컨테이너, 반응형 리사이저, 모바일 오버레이
|
||||||
|
│ │ └── Sidebar.tsx ← 프로젝트 트리, 언어/테마 선택, 프로필 & Import/Export 팝오버
|
||||||
|
│ ├── tasks/
|
||||||
|
│ │ ├── TaskList.tsx ← N-depth 재귀 체크리스트 트리, 스마트 퀵애드, 인라인 수정
|
||||||
|
│ │ ├── TaskDetail.tsx ← 상세 패널, 블록 스왑, 마우스 스플릿 리사이저, 바텀시트
|
||||||
|
│ │ ├── MarkdownNoteEditor.tsx ← 미니멀 마크다운 에디터 & DOMPurify 보안 프리뷰
|
||||||
|
│ │ └── KanbanView.tsx ← CheckFlow Labs 3컬럼 칸반 보드
|
||||||
|
│ └── settings/
|
||||||
|
│ └── SettingsModal.tsx ← Profile / Preferences / Labs / CalDAV / Admin 5탭 모달
|
||||||
|
└── lib/
|
||||||
|
├── userPrefs.ts ← 반응형 개인화 설정 스토어 (CSS 변수 인젝터)
|
||||||
|
├── i18n/ ← EN/KO/JA 다국어 사전 및 useI18n 훅
|
||||||
|
├── auth.ts & prisma.ts ← NextAuth 구성 및 Prisma DB 커넥터
|
||||||
|
└── mockData.ts ← 데모 모드 전용 LocalStorage 스토리지 레이어
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## TickTick에서 가져오기
|
## 🔒 보안 및 개인정보 원칙
|
||||||
|
|
||||||
1. TickTick 앱 → Settings → Export
|
1. **엄격한 데이터 격리**: 모든 API 요청은 세션 소유권(`userId === session.user.id`)을 검증하며 리스트/태스크 간 IDOR(비인가 접근)를 원천 차단합니다.
|
||||||
2. **Export as CSV** 또는 **Export as iCalendar** 선택
|
2. **XSS 및 수식 주입 방어**: 모든 사용자 입력과 마크다운 렌더링은 `DOMPurify`를 거치며, CSV 가져오기 시 Formula Injection 방어(`sanitizeFormula`)가 적용됩니다.
|
||||||
3. CheckFlow → 사이드바 → **Import Tasks**
|
3. **독립 멀티유저 & 관리자 통제**: 일반 사용자와 관리자(`ADMIN`) 권한이 분리되어 안전하게 셀프호스팅 환경을 운영할 수 있습니다.
|
||||||
4. 파일 선택 후 대상 목록 지정 → Import
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## NPM (Nginx Proxy Manager) 연동
|
## 📄 라이선스 (License)
|
||||||
|
|
||||||
Docker compose가 기본으로 `3000` 포트에서 실행됩니다.
|
This project is licensed under the **MIT License** — see the LICENSE file for details.
|
||||||
NPM에서 Proxy Host 추가:
|
|
||||||
- **Destination**: `http://checkflow-app:3000`
|
|
||||||
- SSL 인증서 설정
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 환경 변수
|
|
||||||
|
|
||||||
| 변수 | 설명 | 기본값 |
|
|
||||||
|------|------|--------|
|
|
||||||
| `DATABASE_URL` | PostgreSQL 연결 문자열 | — |
|
|
||||||
| `NEXTAUTH_URL` | 외부 접근 URL | `http://localhost:3000` |
|
|
||||||
| `NEXTAUTH_SECRET` | JWT 시크릿 (32자 이상 랜덤) | — |
|
|
||||||
| `POSTGRES_PASSWORD` | DB 비밀번호 | `changeme` |
|
|
||||||
| `PORT` | 노출 포트 | `3000` |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 기술 스택
|
|
||||||
|
|
||||||
- **Frontend**: Next.js 16 (App Router) + TypeScript + Vanilla CSS
|
|
||||||
- **Backend**: Next.js API Routes
|
|
||||||
- **DB**: PostgreSQL + Prisma ORM
|
|
||||||
- **Auth**: NextAuth.js (JWT)
|
|
||||||
- **PWA**: Service Worker + Web App Manifest
|
|
||||||
- **CardDAV**: 커스텀 iCalendar VTODO 구현
|
|
||||||
- **Container**: Docker + docker-compose
|
|
||||||
|
|||||||
@@ -514,10 +514,10 @@ export function SettingsModal({ isOpen, onClose, user, isDemo: _isDemo = false }
|
|||||||
{activeTab === "sync" && (
|
{activeTab === "sync" && (
|
||||||
<div className="settings-tab-content">
|
<div className="settings-tab-content">
|
||||||
<h3 style={{ fontSize: 15, fontWeight: 700, marginBottom: 6 }}>
|
<h3 style={{ fontSize: 15, fontWeight: 700, marginBottom: 6 }}>
|
||||||
📱 {t("syncTitle") || "Galaxy & External Sync (CalDAV)"}
|
📱 {t("syncTitle") || "CalDAV & Mobile Sync (Android / Apple)"}
|
||||||
</h3>
|
</h3>
|
||||||
<p style={{ fontSize: 13, color: "var(--text-secondary)", lineHeight: 1.5, marginBottom: 14 }}>
|
<p style={{ fontSize: 13, color: "var(--text-secondary)", lineHeight: 1.5, marginBottom: 14 }}>
|
||||||
{t("syncDesc") || "CheckFlow supports native two-way synchronization with Samsung Galaxy Reminder, Apple Reminders, and Thunderbird via CalDAV."}
|
{t("syncDesc") || "CheckFlow supports native two-way synchronization with Android, Apple Reminders, and Thunderbird via standard CalDAV."}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{/* Endpoint bar & Action buttons */}
|
{/* Endpoint bar & Action buttons */}
|
||||||
@@ -583,9 +583,9 @@ export function SettingsModal({ isOpen, onClose, user, isDemo: _isDemo = false }
|
|||||||
<SegmentedControl
|
<SegmentedControl
|
||||||
value={syncPlatform}
|
value={syncPlatform}
|
||||||
options={[
|
options={[
|
||||||
{ label: `🤖 ${t("syncTabAndroid") || "Galaxy / DAVx⁵"}`, value: "android" },
|
{ label: `🤖 ${t("syncTabAndroid") || "Android (DAVx⁵)"}`, value: "android" },
|
||||||
{ label: `🍎 ${t("syncTabApple") || "Apple Reminders"}`, value: "apple" },
|
{ label: `🍎 ${t("syncTabApple") || "Apple Reminders"}`, value: "apple" },
|
||||||
{ label: `💻 ${t("syncTabThunderbird") || "Thunderbird"}`, value: "thunderbird" },
|
{ label: `🦅 ${t("syncTabThunderbird") || "Thunderbird"}`, value: "thunderbird" },
|
||||||
]}
|
]}
|
||||||
onChange={(v) => setSyncPlatform(v)}
|
onChange={(v) => setSyncPlatform(v)}
|
||||||
/>
|
/>
|
||||||
@@ -606,7 +606,7 @@ export function SettingsModal({ isOpen, onClose, user, isDemo: _isDemo = false }
|
|||||||
{syncPlatform === "android" && (
|
{syncPlatform === "android" && (
|
||||||
<div>
|
<div>
|
||||||
<div style={{ fontWeight: 700, marginBottom: 6, color: "var(--accent)" }}>
|
<div style={{ fontWeight: 700, marginBottom: 6, color: "var(--accent)" }}>
|
||||||
📱 Samsung Galaxy & Android (DAVx⁵ + Reminder / OpenTasks)
|
📱 Android (DAVx⁵ + Tasks.org / OpenTasks)
|
||||||
</div>
|
</div>
|
||||||
<ol style={{ paddingLeft: 20, margin: 0, display: "flex", flexDirection: "column", gap: 4 }}>
|
<ol style={{ paddingLeft: 20, margin: 0, display: "flex", flexDirection: "column", gap: 4 }}>
|
||||||
<li>{t("syncAndroidStep1")}</li>
|
<li>{t("syncAndroidStep1")}</li>
|
||||||
|
|||||||
+12
-12
@@ -76,8 +76,8 @@ export const translations = {
|
|||||||
neverDelete: "Never Auto-Delete",
|
neverDelete: "Never Auto-Delete",
|
||||||
|
|
||||||
// CalDAV & Sync
|
// CalDAV & Sync
|
||||||
syncTitle: "Galaxy & External Sync (CalDAV)",
|
syncTitle: "CalDAV & Mobile Sync (Android / Apple)",
|
||||||
syncDesc: "CheckFlow supports native two-way synchronization with Samsung Galaxy Reminder, Apple Reminders, and Thunderbird via CalDAV.",
|
syncDesc: "CheckFlow supports native two-way synchronization with Android, Apple Reminders, and Thunderbird via standard CalDAV.",
|
||||||
syncBaseUrl: "CalDAV Server Base URL",
|
syncBaseUrl: "CalDAV Server Base URL",
|
||||||
syncCopyUrl: "Copy URL",
|
syncCopyUrl: "Copy URL",
|
||||||
syncCopied: "Copied!",
|
syncCopied: "Copied!",
|
||||||
@@ -85,13 +85,13 @@ export const translations = {
|
|||||||
syncTestConnection: "Test Endpoint",
|
syncTestConnection: "Test Endpoint",
|
||||||
syncTesting: "Testing...",
|
syncTesting: "Testing...",
|
||||||
syncTestSuccess: "✓ CalDAV endpoint responded successfully (200 OK)",
|
syncTestSuccess: "✓ CalDAV endpoint responded successfully (200 OK)",
|
||||||
syncTabAndroid: "Galaxy / Android (DAVx⁵)",
|
syncTabAndroid: "Android (DAVx⁵)",
|
||||||
syncTabApple: "Apple Reminders (iOS / macOS)",
|
syncTabApple: "Apple Reminders (iOS / macOS)",
|
||||||
syncTabThunderbird: "Thunderbird (Desktop)",
|
syncTabThunderbird: "Thunderbird (Desktop)",
|
||||||
syncAndroidStep1: "Install DAVx⁵ from Google Play Store or F-Droid.",
|
syncAndroidStep1: "Install DAVx⁵ from Google Play Store or F-Droid.",
|
||||||
syncAndroidStep2: "Open DAVx⁵ → Add Account → Select 'Login with URL and user name'.",
|
syncAndroidStep2: "Open DAVx⁵ → Add Account → Select 'Login with URL and user name'.",
|
||||||
syncAndroidStep3: "Paste the Base URL above, then enter your CheckFlow email & password.",
|
syncAndroidStep3: "Paste the Base URL above, then enter your CheckFlow email & password.",
|
||||||
syncAndroidStep4: "Enable 'VTODO (Tasks)' collection to sync with Samsung Reminder or OpenTasks.",
|
syncAndroidStep4: "Enable 'VTODO (Tasks)' collection to sync with Android Tasks or OpenTasks.",
|
||||||
syncAppleStep1: "Open Settings → Reminders → Accounts → Add Account.",
|
syncAppleStep1: "Open Settings → Reminders → Accounts → Add Account.",
|
||||||
syncAppleStep2: "Select 'Other' → Add CalDAV Account.",
|
syncAppleStep2: "Select 'Other' → Add CalDAV Account.",
|
||||||
syncAppleStep3: "Server: paste base URL without protocol, User/Pass: CheckFlow credentials.",
|
syncAppleStep3: "Server: paste base URL without protocol, User/Pass: CheckFlow credentials.",
|
||||||
@@ -256,8 +256,8 @@ export const translations = {
|
|||||||
neverDelete: "자동 삭제 안 함",
|
neverDelete: "자동 삭제 안 함",
|
||||||
|
|
||||||
// CalDAV & Sync
|
// CalDAV & Sync
|
||||||
syncTitle: "갤럭시 및 외부 캘린더 연동 (CalDAV)",
|
syncTitle: "CalDAV 모바일 및 외부 동기화 (Android / Apple)",
|
||||||
syncDesc: "삼성 갤럭시 리마인더, 애플 미리알림, Thunderbird 등 CalDAV 표준을 지원하는 모든 기기와 양방향으로 동기화됩니다.",
|
syncDesc: "안드로이드(DAVx⁵, Tasks), 애플 미리알림, Thunderbird 등 CalDAV 표준을 지원하는 모든 기기 및 앱과 실시간 양방향으로 동기화됩니다.",
|
||||||
syncBaseUrl: "CalDAV 기본 주소 (Base URL)",
|
syncBaseUrl: "CalDAV 기본 주소 (Base URL)",
|
||||||
syncCopyUrl: "URL 복사",
|
syncCopyUrl: "URL 복사",
|
||||||
syncCopied: "복사 완료!",
|
syncCopied: "복사 완료!",
|
||||||
@@ -265,13 +265,13 @@ export const translations = {
|
|||||||
syncTestConnection: "엔드포인트 점검",
|
syncTestConnection: "엔드포인트 점검",
|
||||||
syncTesting: "점검 중...",
|
syncTesting: "점검 중...",
|
||||||
syncTestSuccess: "✓ CalDAV 엔드포인트가 정상적으로 응답합니다 (200 OK)",
|
syncTestSuccess: "✓ CalDAV 엔드포인트가 정상적으로 응답합니다 (200 OK)",
|
||||||
syncTabAndroid: "갤럭시 / 안드로이드 (DAVx⁵)",
|
syncTabAndroid: "안드로이드 (DAVx⁵)",
|
||||||
syncTabApple: "애플 미리알림 (iOS / macOS)",
|
syncTabApple: "애플 미리알림 (iOS / macOS)",
|
||||||
syncTabThunderbird: "Thunderbird (PC)",
|
syncTabThunderbird: "Thunderbird (PC)",
|
||||||
syncAndroidStep1: "구글 플레이 스토어 또는 F-Droid에서 'DAVx⁵' 앱을 설치합니다.",
|
syncAndroidStep1: "구글 플레이 스토어 또는 F-Droid에서 'DAVx⁵' 앱을 설치합니다.",
|
||||||
syncAndroidStep2: "DAVx⁵ 실행 → 계정 추가(+) → 'URL 및 사용자 이름으로 로그인'을 선택합니다.",
|
syncAndroidStep2: "DAVx⁵ 실행 → 계정 추가(+) → 'URL 및 사용자 이름으로 로그인'을 선택합니다.",
|
||||||
syncAndroidStep3: "위 기본 주소를 붙여넣고, CheckFlow 로그인 이메일과 비밀번호를 입력합니다.",
|
syncAndroidStep3: "위 기본 주소를 붙여넣고, CheckFlow 로그인 이메일과 비밀번호를 입력합니다.",
|
||||||
syncAndroidStep4: "'VTODO (할 일)'을 켜면 삼성 리마인더 또는 OpenTasks와 자동으로 실시간 동기화됩니다.",
|
syncAndroidStep4: "'VTODO (할 일)'을 켜면 안드로이드 할 일 앱(Tasks.org, OpenTasks 등)과 실시간 동기화됩니다.",
|
||||||
syncAppleStep1: "기기 설정 → 미리알림(또는 캘린더) → 계정 → '계정 추가'를 탭합니다.",
|
syncAppleStep1: "기기 설정 → 미리알림(또는 캘린더) → 계정 → '계정 추가'를 탭합니다.",
|
||||||
syncAppleStep2: "'기타' 선택 → 'CalDAV 계정 추가'를 누릅니다.",
|
syncAppleStep2: "'기타' 선택 → 'CalDAV 계정 추가'를 누릅니다.",
|
||||||
syncAppleStep3: "서버에 위 주소를 입력하고, 사용자 이름/비밀번호에 CheckFlow 계정 정보를 입력합니다.",
|
syncAppleStep3: "서버에 위 주소를 입력하고, 사용자 이름/비밀번호에 CheckFlow 계정 정보를 입력합니다.",
|
||||||
@@ -436,8 +436,8 @@ export const translations = {
|
|||||||
neverDelete: "自動削除しない",
|
neverDelete: "自動削除しない",
|
||||||
|
|
||||||
// CalDAV & Sync
|
// CalDAV & Sync
|
||||||
syncTitle: "Galaxy & 外部カレンダー連携 (CalDAV)",
|
syncTitle: "CalDAV & 外部同期 (Android / Apple)",
|
||||||
syncDesc: "Samsung Galaxy リマインダー、Apple リマインダー、Thunderbird など CalDAV 対応アプリと双方向同期できます。",
|
syncDesc: "Android (DAVx⁵, Tasks)、Apple リマインダー、Thunderbird など CalDAV 対応アプリと双方向同期できます。",
|
||||||
syncBaseUrl: "CalDAV サーバー基本 URL",
|
syncBaseUrl: "CalDAV サーバー基本 URL",
|
||||||
syncCopyUrl: "URL をコピー",
|
syncCopyUrl: "URL をコピー",
|
||||||
syncCopied: "コピーしました!",
|
syncCopied: "コピーしました!",
|
||||||
@@ -445,13 +445,13 @@ export const translations = {
|
|||||||
syncTestConnection: "接続テスト",
|
syncTestConnection: "接続テスト",
|
||||||
syncTesting: "テスト中...",
|
syncTesting: "テスト中...",
|
||||||
syncTestSuccess: "✓ CalDAV エンドポイントは正常に応答しています (200 OK)",
|
syncTestSuccess: "✓ CalDAV エンドポイントは正常に応答しています (200 OK)",
|
||||||
syncTabAndroid: "Galaxy / Android (DAVx⁵)",
|
syncTabAndroid: "Android (DAVx⁵)",
|
||||||
syncTabApple: "Apple リマインダー (iOS / macOS)",
|
syncTabApple: "Apple リマインダー (iOS / macOS)",
|
||||||
syncTabThunderbird: "Thunderbird (PC)",
|
syncTabThunderbird: "Thunderbird (PC)",
|
||||||
syncAndroidStep1: "Google Play または F-Droid から「DAVx⁵」アプリをインストールします。",
|
syncAndroidStep1: "Google Play または F-Droid から「DAVx⁵」アプリをインストールします。",
|
||||||
syncAndroidStep2: "DAVx⁵ を起動 → アカウント追加 →「URL とユーザー名でログイン」を選択します。",
|
syncAndroidStep2: "DAVx⁵ を起動 → アカウント追加 →「URL とユーザー名でログイン」を選択します。",
|
||||||
syncAndroidStep3: "上記の基本 URL を貼り付け、CheckFlow のメールアドレスとパスワードを入力します。",
|
syncAndroidStep3: "上記の基本 URL を貼り付け、CheckFlow のメールアドレスとパスワードを入力します。",
|
||||||
syncAndroidStep4: "「VTODO (タスク)」を有効にすると、Samsung リマインダーや OpenTasks と連携されます。",
|
syncAndroidStep4: "「VTODO (タスク)」を有効にすると、Android Tasks や OpenTasks と連携されます。",
|
||||||
syncAppleStep1: "設定 → リマインダー → アカウント →「アカウントを追加」を開きます。",
|
syncAppleStep1: "設定 → リマインダー → アカウント →「アカウントを追加」を開きます。",
|
||||||
syncAppleStep2: "「その他」を選択 →「CalDAV アカウントを追加」を選択します。",
|
syncAppleStep2: "「その他」を選択 →「CalDAV アカウントを追加」を選択します。",
|
||||||
syncAppleStep3: "サーバーに上記の URL、ユーザー名/パスワードに CheckFlow のアカウント情報を入力します。",
|
syncAppleStep3: "サーバーに上記の URL、ユーザー名/パスワードに CheckFlow のアカウント情報を入力します。",
|
||||||
|
|||||||
+2
-2
@@ -71,7 +71,7 @@ export const INITIAL_DEMO_TASKS: MockTask[] = [
|
|||||||
listId: "list-1",
|
listId: "list-1",
|
||||||
parentId: null,
|
parentId: null,
|
||||||
title: "Setup Self-Hosted CheckFlow on NAS",
|
title: "Setup Self-Hosted CheckFlow on NAS",
|
||||||
note: "## 🐳 Docker Deployment Guide\n\n- Deploy with `docker compose up -d`\n- Forward port 3000 to NPM (Nginx Proxy Manager)\n- Setup SSL certificate for custom domain\n\n### 🔗 Key Endpoints\n- Web App: https://todo.yourdomain.com\n- CardDAV: https://todo.yourdomain.com/api/dav",
|
note: "## 🐳 Docker Deployment Guide\n\n- Deploy with `docker compose up -d`\n- Forward port 3000 to NPM (Nginx Proxy Manager)\n- Setup SSL certificate for custom domain\n\n### 🔗 Key Endpoints\n- Web App: https://todo.yourdomain.com\n- CalDAV: https://todo.yourdomain.com/api/dav",
|
||||||
completed: false,
|
completed: false,
|
||||||
completedAt: null,
|
completedAt: null,
|
||||||
dueDate: new Date(Date.now() + 86400000).toISOString(),
|
dueDate: new Date(Date.now() + 86400000).toISOString(),
|
||||||
@@ -124,7 +124,7 @@ export const INITIAL_DEMO_TASKS: MockTask[] = [
|
|||||||
id: "sub-1-2",
|
id: "sub-1-2",
|
||||||
listId: "list-1",
|
listId: "list-1",
|
||||||
parentId: "task-1",
|
parentId: "task-1",
|
||||||
title: "Test DAVx⁵ sync on Samsung Galaxy",
|
title: "Test CalDAV sync via DAVx⁵ on Android",
|
||||||
note: null,
|
note: null,
|
||||||
completed: false,
|
completed: false,
|
||||||
completedAt: null,
|
completedAt: null,
|
||||||
|
|||||||
Reference in New Issue
Block a user