Fancy Kanban 보드 스키마
마크다운 기반 칸반 보드 형식에 대한 자체 포함된 명세입니다. 이 스키마를 따라 파일을 읽고 쓰는 모든 앱은 호환 가능한 보드를 생성합니다.
개요
각 보드는 fancy-kanban 식별자를 가진 펜스드 코드 블록 안에 위치합니다. 즉:
- 보드는 노트 내 어디든 일반 텍스트, 링크 및 기타 콘텐츠와 함께 포함될 수 있습니다.
- 노트는 0개, 1개 또는 여러 개의 보드를 포함할 수 있습니다.
- 단일 보드 블록으로만 구성된 파일은 독립형 보드 파일입니다.
- 플러그인이 설치되지 않은 경우 블록은 스타일 없는 코드 블록으로 렌더링되며, 원시 텍스트는 완전히 사람이 읽을 수 있는 상태로 유지됩니다.
블록은 ---로 구분된 두 개의 섹션으로 구성됩니다:
- 설정 섹션 (YAML 스타일) - 필드, 워크플로 및 보기 옵션 정의
- 마크다운 테이블 - 데이터 행 포함
완전한 예제
```fancy-kanban
---
title: My Board
fields:
- name: title, type: Text, label: Title
- name: status, type: Select, options: inbox|doing|done, label: Status, default: inbox
- name: responsible, type: Text, label: Responsible
- name: start_date, type: Date, label: Start Date
- name: notes, type: Textarea, label: Notes
- name: effort, type: Number, label: Effort
- name: docs, type: Link, label: Docs
- name: team, type: Select, options: frontend|backend, label: Team
card_fields: responsible, effort
lanes: team
workflow: inbox→doing, inbox→done, doing→done, doing→inbox, done→doing, done→inbox
---
| _id | Title | Status | Responsible | Start Date | Notes | Effort | Docs | Team |
|--------|----------------|--------|-------------|------------|----------------------------|--------|-----------------------|----------|
| x7k2a1 | Fix login bug | inbox | Alice | 2026-01-15 | Needs investigation | 3 | | backend |
| m3p9b2 | Refactor auth | doing | Bob | | Multi-line\<br\>content here | 5 | design.md | backend |
| q1r4c3 | Setup CI | done | | 2026-01-01 | | 1 | setup.md\|guide.md | frontend |
```
블록 구조
펜스드 블록은 --- 줄로 구분된 정확히 두 개의 섹션을 포함합니다:
```fancy-kanban
---
{설정}
---
{마크다운 테이블}
첫 번째 `---` 이전의 모든 내용은 무시됩니다(향후 사용을 위해 예약됨). 두 개의 `---` 줄 사이의 모든 내용이 설정입니다. 두 번째 `---` 이후의 모든 내용은 테이블입니다.
## 설정 섹션
YAML 스타일의 키-값 쌍입니다. 줄 단위로 파싱됩니다.
### 키
| 키 | 필수 | 기본값 | 설명 |
|-----|----------|---------|-------------|
| `title` | 예 | — | 사람이 읽을 수 있는 보드 이름 |
| `fields` | 예 | — | 필드 정의 목록 (아래 참조) |
| `version` | 아니오 | `1` | 플러그인이 작성하는 형식 버전; 현재 플러그인이 지원하는 것보다 높은 버전의 보드는 읽기 전용 모드로 열림 |
| `workflow` | 아니오 | 모든 전환 허용 | 쉼표로 구분된 `from→to` 쌍 |
| `lanes` | 아니오 | 없음 | 스윔레인 그룹화 차원으로 사용할 필드 이름 |
| `card_title` | 아니오 | 자동 감지 | 카드 제목으로 사용할 필드 이름; 빈 문자열로 설정하면 제목이 표시되지 않음 |
| `card_fields` | 아니오 | 없음 | 카드 제목 아래에 표시할 보조 필드의 정렬된 쉼표 구분 목록 |
| `card_labels` | 아니오 | `true` | `false`로 설정하면 보조 카드 필드의 레이블 접두사를 숨김 |
| `card_limit` | 아니오 | `0` (제한 없음) | 열당 최대 카드 수; 이 수를 초과하는 카드는 "더보기" 버튼 뒤에 숨겨짐 |
### `card_title`
```yaml
card_title: summary
카드 제목으로 렌더링할 필드를 제어합니다:
- 없음 (기본값): 첫 번째
_id또는 열이 아닌 필드가 자동으로 사용됨 - 필드 이름으로 설정: 해당 필드의 값이 제목으로 표시됨
- 빈 문자열로 설정 (
card_title:): 제목이 표시되지 않음; 카드는 보조 필드만 표시함
card_fields
card_fields: priority, due, docs
카드 제목 아래에 표시할 보조 필드 이름의 정렬된 쉼표 구분 목록입니다. 이는 제목 아래에 레이블이 있는 행으로 나타납니다.
기본 동작: card_fields가 없으면 카드는 제목 필드만 표시합니다. card_fields 키가 없는 기존 보드에는 영향을 미치지 않습니다.
알 수 없는 이름: 정의된 필드와 일치하지 않는 필드 이름은 렌더링 시 자동으로 무시됩니다. fields:에서 필드를 제거하면 파싱 오류 없이 카드 표시에서 자동으로 숨겨집니다.
링크 필드: Link 필드가 card_fields에 포함된 경우, 해당 항목은 카드 표시에서 클릭 가능한 링크의 가로 목록으로 렌더링됩니다. 보트 경로는 새 탭에서 열리고 외부 URI는 브라우저에서 열립니다.
card_labels
card_labels: false
false로 설정하면 카드 표시의 보조 필드 행에서 레이블 접두사가 생략되고 값만 표시됩니다. 기본값은 true(레이블 표시)입니다. 이 키는 값이 false인 경우에만 설정에 기록됩니다.
card_limit
card_limit: 5
양의 정수로 설정하면 각 열에는 최대 그 수만큼의 카드가 표시됩니다. 제한을 초과하는 카드는 숨겨지고 열 하단에 더보기 (N) 버튼이 나타납니다. 클릭하면 보드를 다시 로드하지 않고 나머지 모든 카드가 표시됩니다. card_limit: 0으로 설정하거나 키를 생략하면 제한이 완전히 비활성화됩니다.
이는 완료 열에 시간이 지남에 따라 완료된 카드가 많이 누적되는 보드에 특히 유용합니다. 가장 최근에 추가된 카드는 한 눈에 보이고 오래된 기록은 접혀서 방해되지 않습니다.
lanes
필드 이름으로 설정된 경우(Select 필드여야 함), 보드는 행렬로 렌더링됩니다:
- 열 —
status필드의options순서에 따라 결정됨 - 스윔레인 행 —
lanes필드의options순서에 따라 결정됨
lanes 필드에 값이 없는 카드는 하단의 할당되지 않음 가상 레인에 나타납니다. lanes 변경은 보기 구성 변경일 뿐이며 행 데이터에는 영향을 미치지 않습니다.
필드 정의
fields 목록의 각 항목은 한 줄에 쉼표로 구분된 key: value 쌍의 집합이며, - 접두사가 붙습니다:
fields:
- name: title, type: Text, label: Title
- name: status, type: Select, options: inbox|doing|done, label: Status, default: inbox
필드 순서 규칙: title을 먼저 나열하고, 그 다음 status, 그리고 추가 필드 순서로 나열합니다. 데이터 섹션의 테이블 열 순서는 필드 정의 순서를 따르며, 자동 감지된 카드 제목은 첫 번째 _id가 아닌 열 필드로 결정되므로 title을 먼저 배치하면 명시적인 card_title 키 없이도 예측 가능한 제목 결정이 보장됩니다.
필드 속성
| 속성 | 필수 | 설명 |
|---|---|---|
name | 예 | 내부 식별자. 소문자, 공백은 밑줄 사용. |
type | 예 | 다음 중 하나: Text, Textarea, Date, Number, Select, Link |
label | 예 | 사람이 읽을 수 있는 열 헤더. 마크다운 테이블 헤더와 정확히 일치해야 함. |
options | Select 전용 | 파이프(` |
colors | Select, 선택 사항 | 각 옵션에 배경색을 할당하는 파이프 구분 name=hex 쌍 (예: High=#e74c3c|Low=#27ae60). 항목이 없는 옵션은 일반 텍스트로 렌더링됨. |
default | 아니오 | 새 카드의 기본값 |
필드 유형
| 유형 | 저장 형식 | 설명 |
|---|---|---|
Text | 일반 문자열 | 한 줄 텍스트 |
Textarea | 줄바꿈에 <br>을 사용하는 문자열 | 여러 줄 텍스트 |
Date | YYYY-MM-DD | 달력 날짜 |
Number | 정수 또는 소수 문자열 | 숫자 값 |
Select | options 값 중 하나 | 제한된 선택; 옵션은 colors 속성을 통해 16진수 색상을 가질 수 있음 |
Link | <br>로 구분된 경로 또는 URI 목록 | 보트 루트 기준 경로(notes/doc.pdf) 또는 외부 URI(https://…, ftp://…, mailto:…) |
특수 필드 이름
| 이름 | 역할 |
|---|---|
title | 기본 표시 필드. fields:에서 먼저 나열되어야 함. card_title이 설정되지 않은 경우 자동 감지된 카드 제목으로 사용됨. |
status | 필수. 칸반 열 필드. type: Select여야 함. 카드는 이 값에 따라 열로 그룹화됨. 열 순서는 options 순서를 따름. |
다른 모든 필드는 보조 필드이며, card_fields에 나열될 때 카드 메타데이터로 표시됩니다.
항목 식별
모든 카드는 마크다운 테이블의 _id 열에 저장된 안정적인 숨겨진 ID를 갖습니다. UI는 이 열을 절대 표시하지 않습니다.
- 카드 생성 시 생성됨: 짧은 무작위 영숫자 문자열 (예: 8자:
x7k2a1b3) - 모든 직렬화 왕복 과정에서 보존됨
- 재정렬, 드래그 앤 드롭 및 필드 이름 변경에도 유지됨
- 모든 카드 작업(이동, 편집, 삭제)에 내부적으로 사용됨
식별이 ID 기반이고 내용에서 파생되지 않으므로 카드 제목을 변경해도 ID에는 영향을 미치지 않습니다.
워크플로
UI에서 허용되는 상태 전환을 정의합니다:
workflow: inbox→doing, inbox→done, doing→done, doing→inbox, done→doing, done→inbox
- 쉼표로 구분된
from→to쌍 목록 (화살표:→, U+2192) workflow가 생략되면 상태 옵션 간의 모든 전환이 허용됨- UI 선택을 제한하는 데 사용됨 (예: "이동" 메뉴에 유효한 대상만 표시)
- 원시 테이블을 직접 편집하면 일반 텍스트 특성상 워크플로 유효성 검사를 우회함
보드 템플릿
새 보드를 만들 때 사전 정의된 템플릿 세트는 일반적인 status 옵션 세트를 제공합니다. 템플릿은 status 필드 옵션과 workflow만 미리 채우며, 다른 모든 필드는 사용자가 추가합니다.
| 템플릿 | 상태 옵션 | 기본 워크플로 |
|---|---|---|
| Basic | inbox | doing | done | 모든 전환 |
| Software | backlog | todo | in-progress | review | done | 앞으로 + 한 단계 뒤로 |
| Content | idea | draft | review | published | 앞으로만 |
| Project | planning | active | blocked | complete | 모든 전환 (→ planning 제외) |
| Custom | 사용자 정의 | 사용자 정의 |
Custom을 선택하면 status 옵션 및 워크플로 전환을 위한 자유 형식 편집기가 열립니다.
마크다운 테이블
테이블은 설정 섹션의 닫는 --- 바로 뒤에 나타납니다.
구조
| _id | Header1 | Header2 |
|--------|---------|---------|
| abc123 | value | value |
- 헤더 행 — 첫 번째 열은 항상
_id입니다. 나머지 열은 스키마 정의 순서의 필드 레이블입니다. - 구분자 행 — 표준 마크다운 테이블 구분자
- 데이터 행 — 카드당 하나의 행;
_id셀에는 카드의 안정적인 ID가 포함됩니다.
규칙
- 테이블의 열 순서는 필드 정의 순서와 일치해야 합니다 (
_id이후) - 빈 셀은 유효합니다 (필드 값 = 빈 문자열)
- 상태 그룹 내의 행 순서는 표시 순서입니다.
- 빈 테이블 (헤더 + 구분자, 데이터 행 없음)은 유효합니다.
_id열은 항상 첫 번째이며 렌더링된 보드에는 절대 표시되지 않습니다.
이스케이프
| 값의 문자 | 이스케이프 방식 |
|---|---|
| (파이프) | | (백슬래시-파이프) |
| 줄바꿈 | <br> |
| 캐리지 리턴 | <br> |
읽을 때: \| → |, <br> → 줄바꿈.
쓸 때: | → \|, 모든 줄바꿈 → <br>.
파싱 알고리즘
fancy-kanban블록의 열고 닫는 펜스 사이의 원시 문자열 추출- 첫 번째
---줄에서 분할하여 설정 섹션 시작 위치 찾기 - 두 번째
---줄에서 분할하여 설정과 테이블 분리 - 설정을 줄 단위로 파싱:
title,version,fields,workflow,lanes,card_title,card_fields,card_labels,card_limit추출 fields의 경우,-로 시작하는 줄을 수집하고 각각을 쉼표로 구분된key: value쌍으로 파싱;colors는 파이프로 구분된name=hex토큰으로 디코딩- 본문에서 테이블 줄 찾기 (
|로 시작하는 줄) - 첫 번째 테이블 줄은 헤더 행 — 열 레이블 추출;
_id는 항상 첫 번째 - 나머지 헤더 레이블을 대소문자를 구분하지 않는 레이블 조회를 통해 필드 이름에 매핑
- 각 데이터 행 파싱: 이스케이프되지 않은
|로 분할, 셀 트리밍,\|및<br>언이스케이프 - 각 데이터 행의 첫 번째 셀은 카드의
_id status필드 값별로 카드 그룹화,options순서로 그룹 시드 생성
스키마 조정 (파싱 후 적용):
- 스키마에 있지만 카드 데이터에 없는 필드: 필드의
default(또는 빈 문자열)로 백필 - 카드 데이터에 있지만 스키마에서 제거된 필드: 고아 숨겨진 데이터로 보존 (삭제되지 않음)
쓰기 알고리즘
- 현재 스키마에서 설정 섹션 재구성 (가능한 경우 원래 형식 유지)
- 헤더 행 생성:
_id먼저, 그 다음 스키마 정의 순서의 필드 레이블 - 구분자 행 생성
- 카드당 하나의 데이터 행 생성:
_id먼저, 그 다음 스키마 순서의 필드 값, 파이프와 줄바꿈 이스케이프 처리 - 카드에 기존 ID가 없는 경우 무작위 영숫자 문자열을 사용하여 새 카드
_id생성 - 전체 블록 재구성: 여는 펜스, 설정,
---, 빈 줄, 테이블, 닫는 펜스
쓰기-백 원칙: 영향을 받는 블록의 텍스트 범위만 소스 파일에서 패치되며, 주변 콘텐츠는 다시 쓰여지지 않습니다.
최소 실행 가능 보드
```fancy-kanban
---
title: My Board
fields:
- name: title, type: Text, label: Title
- name: status, type: Select, options: inbox|doing|done, label: Status, default: inbox
workflow: inbox→doing, inbox→done, doing→done, doing→inbox, done→doing, done→inbox
---
| _id | Title | Status |
|-----|-------|--------|
## 호환성 참고 사항
- 플러그인 없이 블록은 일반 코드 블록으로 렌더링되며, 모든 데이터는 일반 텍스트로 계속 표시됩니다.
- 블록 내부의 마크다운 테이블은 유효한 마크다운이며 모든 텍스트 편집기에서 읽을 수 있습니다.
- 설정 섹션은 정적 사이트 생성기와 노트 앱에 익숙한 YAML 규칙을 따릅니다.
- 플러그인을 제거해도 모든 데이터는 그대로 유지되며 복구 가능합니다.
## 더 이상 사용되지 않는 기능
이전 버전과의 호환성을 위해 유지되는 더 이상 사용되지 않는 기능 목록은 [docs/deprecations.md](deprecations.md)를 참조하십시오.