다우오피스 · DO서비스기획팀 기획문서

팀원 실무 가이드 A to Z

클론부터 배포 확인까지, 순서대로 따라가면 끝나도록 썼습니다. 처음이면 0장부터 차례대로, 이미 쓰고 있다면 필요한 장만 보시면 됩니다. 이 문서는 쓰는 사람용입니다 — 링크만 보는 유관부서에게는 소개 장표를 보내시면 됩니다.

기획디자인개발QA

PART 0준비물 — 이 다섯 개면 됩니다

설치할 것이 거의 없습니다. 명세 도구가 레포 안에 들어 있어서 스킬을 따로 설치하는 과정이 없고, 의존성은 python3 뿐입니다.

준비물확인 방법없으면
GitHub 접근 권한저장소 페이지가 열리는지 레포 소유자에게 Write 권한으로 초대를 요청합니다.
gitgit --version 사내 표준 설치 절차대로 설치합니다.
python3python3 --version 3.10 이상이면 됩니다. macOS·리눅스는 대개 기본 탑재입니다.
Claude Codeclaude --version 이게 실제 작업 도구입니다. 없으면 CLI 로도 되지만 버전·이력을 직접 챙겨야 합니다.
브라우저 결과 미리보기에 씁니다.
선택 mermaid 렌더러로컬에서 흐름도를 도식으로 보고 싶을 때만 설치합니다 (npm i -g @mermaid-js/mermaid-cli). 없으면 흐름도 자리에 원문이 그대로 보이고 경고가 뜰 뿐, 정보는 잃지 않습니다. 배포본은 CI가 렌더러를 설치하므로 항상 도식입니다 — 안 깔아도 유관부서가 보는 화면은 정상입니다.
필요 없는 것 Cloudflare 계정은 필요 없습니다. 호스팅은 최초 설정한 한 사람만 만지고, 배포는 main 병합의 부산물입니다. 누구도 어디에 파일을 업로드하지 않습니다.

PART 1최초 1회 세팅 — 10분

한 번만 하면 끝입니다. 마지막 3단계에서 도구가 실제로 도는지까지 확인하고 넘어갑니다.

  1. 저장소를 클론합니다
    git clone https://github.com/DOServicePlanning/DaouPlanning.git
    cd DaouPlanning

    사내 어느 PC 든 같습니다. 클론한 이 폴더가 앞으로 모든 작업의 기준입니다.

  2. 도구가 도는지 확인합니다
    python3 .claude/skills/spec-hub/scripts/spechub.py status

    기능 현황표가 나오면 성공입니다. 이 명령이 길어서 앞으로는 아래처럼 줄여 씁니다 — 터미널을 새로 열 때마다 한 번씩 실행하면 됩니다.

    # 이 가이드의 모든 예시는 이 S 를 씁니다
    S=".claude/skills/spec-hub/scripts/spechub.py"
    python3 $S status
    확인 표에 DOP-16724 같은 행들이 보이면 준비가 끝났습니다. No such file 가 나오면 클론한 폴더 안에 있는지(pwd) 확인합니다.
  3. git 이름·이메일을 채웁니다
    git config user.name "정민경"
    git config user.email "본인아이디@daou.co.kr"

    커밋 기록과 변경이력의 작성자로 그대로 남습니다. 비워 두면 누가 무엇을 바꿨는지 추적이 끊깁니다.

  4. Claude Code 를 이 폴더에서 엽니다
    # 클론한 DaouPlanning 폴더 안에서
    claude

    .claude/skills/spec-hub/ 가 레포 안에 있으므로 설치 과정 없이 스킬이 자동으로 잡힙니다. 다른 폴더에서 열면 잡히지 않습니다.

    확인 이렇게 물어보세요 — 버전과 링크가 돌아오면 스킬이 잡힌 것입니다.
    "DOP-16724 지금 최신 버전 뭐야?"
  5. (선택) 흐름도 렌더러를 깝니다
    npm i -g @mermaid-js/mermaid-cli

    로컬 미리보기에서 흐름도를 도식으로 보고 싶을 때만 하면 됩니다. 나중에 해도 됩니다.

PART 2아무것도 바꾸지 않고 먼저 익히기

첫 작업 전에 남의 기능 하나를 열어보는 것으로 시작하는 편이 빠릅니다. 구조가 모든 기능에서 같으므로, 하나를 이해하면 전부 이해한 셈이 됩니다.

2-1. 현황표 읽는 법

python3 $S status
의미
버전 · 상태기획문서의 현재 버전과 진행 상태(기획중 / 리뷰중 / 확정 / 개발중 / QA중 / 배포완료)
배포미배포 면 소스에 main 에 아직 안 올라간 변경이 있다는 뜻입니다
REQ · 태깅요구사항 수와, 그중 목업에 data-req 로 태깅된 수
개발기능점검점검 체크리스트 진행률 (완료/전체)
구현구현 대조 진행률 (반영/전체)
최종변경변경이력 맨 위 항목의 날짜와 작성자

2-2. 배포 없이 결과를 봅니다

고쳐 보기 전에, 완성된 페이지가 어떻게 생겼는지 먼저 봅니다.

python3 $S build "specs/DOP-16724_기타휴가_부여이력,_회수"
# → 그 폴더에 hub.html 이 생깁니다. 브라우저로 열어보세요.
화면에서 눌러볼 것
  • 좌측 목차 — 기획문서 5장 / 화면 / Appendix. 문서 / 요구사항 목록
  • — 명세 · 화면 · 흐름 · 변경이력 · 점검 · 구현 · 문의
  • REQ 표시 — 켜면 목업 UI 요소마다 요구사항 번호가 뜨고, 누르면 명세가 열립니다
  • 넓게 / 좁게 — 패널 폭을 바꾸면 목업이 그 폭에 맞춰 리플로우됩니다
  • 변경이력에서 버전 선택 — 그 시점의 기획서가 명세 탭 자리에 열립니다
주의 hub.html생성물이고 git 에서 제외돼 있습니다. 손으로 고치지 마세요 — 다음 build 에서 통째로 덮어써집니다. 항상 소스를 고치고 다시 만듭니다.

2-3. 브랜치를 만들고 작업합니다

main 에 직접 커밋하지 않습니다. 병합되는 순간 유관부서가 보는 링크가 바뀌기 때문입니다.

git switch main && git pull origin main
git switch -c DOP-16724-필터-기본값-정정

PART 3새 기능 기획 A to Z 기획

폴더 만들기부터 링크 공유까지 전 과정입니다. 실제로는 대부분 Claude Code 에 말로 시키면 아래 단계를 도구가 대신 밟습니다 — 그래도 무엇이 일어나는지는 알고 있어야 결과를 검토할 수 있습니다.

  1. 폴더와 파일을 만듭니다
    python3 $S new DOP-21000 "연차 이월 정책 개편"

    specs/DOP-21000_연차_이월_정책_개편/ 이 생기고 파일 5개가 스캐폴딩됩니다 — spec.md · CHANGELOG.md · qa.md · impl.md · mockup.html. 폴더 이름의 앞부분이 JIRA 키이고 그게 곧 URL 경로가 됩니다.

  2. 앞머리(프론트매터)를 채웁니다 — project 를 빼먹지 마세요
    specs/DOP-21000_연차_이월_정책_개편/spec.md
    ---
    key: DOP-21000
    title: 연차 이월 정책 개편
    screen: App 관리 > 근태 > 연차 관리 > 이월 정책
    version: 0.1.0
    status: 기획중
    project: HR2.0 하반기 자산화   # ← 템플릿에 없습니다. 직접 적으세요
    owners:
      기획: 정민경
      디자인: "-"
      개발: "-"
      QA: "-"
    jira: https://issue.daou.co.kr/browse/DOP-21000
    ---
    가장 흔한 실수 project:스캐폴딩 템플릿에 없습니다. 안 적으면 목록 페이지의 "미분류" 묶음으로 떨어집니다. 쓸 수 있는 값은 레포 루트 .spechub.jsonproject_groups 에 있습니다 — 현재는 HR2.0 하반기 자산화 / 전자계약 - 싸인오케이 / 운영 입니다. 프로젝트가 늘면 그 배열에 추가하면 됩니다.
    손대지 않는 값 version 은 직접 고치지 않습니다. 8단계 bump 가 변경이력과 함께 올립니다. 어긋나면 검사에서 오류로 걸립니다.
  3. 표준 5장을 채웁니다 — 비어도 지우지 않습니다
    ## 제목 (그대로 쓰세요)무엇을 씁니까
    1## 기획배경왜 하는지. 어떤 문의·장애·요청에서 출발했는지. AS-IS 의 문제
    2## 기능정의서아래에 ### REQ-xxx 카드들 (5단계)
    3## 유저 업무 Flow + E2E프로세스업무 순서 + 시스템 처리. 흐름도를 여기에 넣습니다 (7단계)
    4## 벤치마킹타 제품 방식과 채택/미채택 판단까지
    5## KPI지표 · 기준치(AS-IS) · 목표치(TO-BE) · 측정 방법

    기능마다 목차가 다르면 읽는 쪽이 매번 구조를 다시 파악해야 합니다. 그래서 다섯 장은 항상 있습니다. 내용이 없으면 목차에 미작성 으로 남습니다 — 장을 지워서 경고를 없애지 마세요. 빠진 게 보여야 채워집니다.

    옛 문서 이미 ## 배경 · ## 요구사항 · ## 흐름 으로 쓴 문서는 그대로 1·2·3장으로 인식됩니다. 고칠 필요 없습니다. 새로 쓸 때만 위 제목을 씁니다.
  4. 요구사항을 씁니다 — 이 문법만 지키면 됩니다
    ## 기능정의서 아래
    ### REQ-001 · 이월 한도 설정 항목 신설
    
    - 상태: 확정
    - UI: 목업의 "이월 한도" 입력칸
    
    본문. 표·목록·**굵게**·`코드`·인용 다 쓸 수 있습니다.
    본문에서 REQ-002 처럼 다른 번호를 언급하면 허브에서 자동으로 링크됩니다.
    
    ### REQ-002 · 이월 상한 초과분 소멸 처리
    
    - 상태: 확정필요
    - UI: 없음
    규칙
    ### REQ-001 ·번호는 3자리 이상. 구분자는 · : - 아무거나
    - 상태:필수. 확정 / 검토중 / 확정필요 / 제외 넷 중 하나. 확정필요 로 두면 허브 상단에 "확정필요 N" 버튼이 떠서 유관부서가 미결 쟁점을 놓치지 않습니다
    - UI:선택. 화면 요소가 없는 순수 백엔드 요구사항이면 없음 으로 적어 목업 태깅 검사에서 면제받습니다
    절대 규칙 번호는 재사용하지 않습니다. 한 번 쓴 REQ-003 은 영구히 그 요구사항의 것입니다. 재사용하면 과거 변경이력·점검 결과·구현 대조가 전혀 다른 요구사항에 붙어버립니다. 없어진 요구사항은 지우지 말고 - 상태: 제외 로 남기고, 새 요구사항은 번호를 계속 올려 씁니다.
    순서 주의 - 상태: 같은 메타 줄은 본문보다 먼저 나와야 합니다. 본문이 시작된 뒤의 - 상태: 는 그냥 본문 불릿으로 취급돼 상태가 인식되지 않습니다.
  5. 목업을 만들고 data-req 를 붙입니다
    <button class="tab-btn" data-req="REQ-001">이월 정책</button>
    <tr data-req="REQ-002 REQ-003">…</tr>
    <input type="number" data-req="REQ-001">

    이 태깅이 있어야 명세의 "화면에서 보기" 가 그 요소를 짚어 줍니다. 화면이 하나면 루트의 mockup.html 을, 여러 개면 mockups/01_목록.html 처럼 나눠 담습니다(앞의 숫자가 목차 순서이고 표시에서는 자동으로 떼어집니다).

    지킬 것이유
    요구사항이 말하는 대상 그 자체에 붙입니다 컨테이너에 뭉텅이로 붙이면 "화면에서 보기" 가 화면 절반을 점멸시켜 쓸모가 없어집니다. 반대로 너무 잘게 쪼개지도 않습니다 — 표의 한 행이 한 요구사항이면 <tr> 에 붙입니다
    외부 CDN·폰트·이미지를 쓰지 않습니다 게시 후 보안 정책에 막혀 깨집니다. 시스템 폰트 스택을 쓰거나 임베드합니다
    폭이 줄어도 무너지지 않게 만듭니다 명세 패널을 열면 화면이 그만큼 좁아집니다(가리지 않고 밀어냅니다). 고정 픽셀 폭 대신 max-width + %, 표는 overflow-x:auto 컨테이너에
    화면이 여러 개면 전역 함수명이 겹치지 않게 합니다 두 화면이 모두 showTab() 을 정의하면 나중에 로드된 쪽이 이깁니다. 접두어를 붙이거나 전체를 IIFE 로 감쌉니다
    명세 텍스트를 목업에 옮겨 적지 않습니다 설명은 명세에만 둡니다. 중복이 곧 v1/v2 불일치의 씨앗입니다
    <title> 을 넣습니다 목차 라벨이 됩니다. 없으면 파일명이 그대로 노출됩니다
  6. 흐름도를 명세 안에 씁니다

    도식은 별도 파일이나 이미지로 만들지 않습니다. 3장 안에 텍스트로 넣으면 배포 시점에 그림으로 그려집니다 — 본문과 같은 파일이라 어긋나지 않습니다.

    ## 유저 업무 Flow + E2E프로세스 아래
    ### 이월 한도 저장 시 처리 — REQ-001, REQ-002
    
    ```mermaid
    sequenceDiagram
        autonumber
        actor 관리자
        participant FE as 이월 정책 화면
        participant API as PolicyController
        participant DB as annual_carryover
    
        관리자->>FE: 한도 입력 후 저장
        FE->>API: PUT /carryover (REQ-001)
        API->>DB: 정책 저장 + 초과분 소멸 예약
        DB-->>API: OK
        API-->>FE: 200
    ```
    • 제목이나 도식 안에서 REQ-001 을 언급하면 명세 항목과 서로 링크됩니다
    • 없는 번호를 참조하면 검사에서 오류로 걸립니다
    • 흐름이 여러 개면 시작 흐름을 먼저 씁니다 — 요구사항당 대표 흐름 하나에만 링크가 걸립니다. 순서를 바꾸기 어려우면 제목에 [대표] 를 붙입니다
    • sequenceDiagram · flowchart · stateDiagram · erDiagram 다 됩니다. 너무 긴 시퀀스는 두세 개로 쪼갭니다
  7. 버전을 올립니다 (bump)
    python3 $S bump "specs/DOP-21000_연차_이월_정책_개편" \
      --author "정민경" \
      --level minor \
      --note "REQ-001 추가: 이월 한도 설정 항목" \
      --note "REQ-002 추가(확정필요): 상한 초과분 소멸 처리"

    spec.mdversionCHANGELOG.md 항목이 함께 올라갑니다. 손으로 변경이력을 쓰지 않는 이유가 이것입니다 — 둘이 어긋나면 검사에서 오류가 됩니다.

    --level언제
    patch1.2.0 → 1.2.1오탈자, 문구 다듬기, 링크 정정 — 판단이 바뀌지 않는 변경
    minor1.2.1 → 1.3.0기본값. 요구사항 추가·변경·제외, 목업 수정, 정책 확정
    major1.3.0 → 2.0.0기능 범위를 다시 잡는 수준의 재작성
    --note 에 반드시 번호를 넣습니다 REQ-001 같은 번호를 적으면 그 요구사항 카드에 변경 N건 칩이 붙어, 유관부서가 명세를 읽다가 바로 이력을 열어볼 수 있습니다. 번호를 빼면 연결이 끊기고, 이력을 남기는 이유가 사라집니다.
  8. 검사를 돌립니다 (lint) — 오류가 남아 있으면 안 됩니다
    python3 $S lint                    # 전체
    python3 $S lint "specs/DOP-21000_연차_이월_정책_개편"   # 한 기능만

    번호가 어긋나거나 태깅이 유령 참조를 가리키면 여기서 걸립니다. 읽는 법은 7장에 있습니다.

    이 레포의 현재 상태 PR 단계 자동 검사가 아직 붙어 있지 않습니다. 지금은 main 병합 시점에만 검사가 돌므로, PR 올리기 전에 이 명령을 직접 돌려야 정합성이 깨진 명세가 병합되는 것을 막을 수 있습니다.
  9. 미리 보고 확인합니다
    python3 $S build "specs/DOP-21000_연차_이월_정책_개편"
    # hub.html 을 브라우저로 열어 REQ 표시·흐름·변경이력을 확인합니다
  10. 커밋 → PR → 병합
    git add specs/DOP-21000_연차_이월_정책_개편
    git commit -m "DOP-21000 v0.2.0 — REQ-001·REQ-002 신설"
    git push -u origin DOP-21000-이월-정책-개편

    커밋 메시지에 버전과 바뀐 번호를 남깁니다. PR 을 올리고 병합하면 끝입니다.

  11. 배포를 확인하고 링크를 공유합니다

    병합되면 GitHub Actions 탭의 명세 허브 배포 가 돌고, 1~2분 뒤 고정 링크에 반영됩니다.

    https://daouplanning.pages.dev/DOP-21000/
    채팅에는 이것만 링크와 변경 요약만 남깁니다 — "v0.2.0 올렸습니다, REQ-002 확정 필요 1건". 명세 본문을 채팅에 다시 붙여넣지 마세요. 그게 바로 원본이 흩어지는 경로입니다. 링크는 영구적이라 다시 뿌릴 일이 없습니다.

PART 4기존 명세 고치기 — 가장 흔한 작업

실무의 90%가 이것입니다. 네 단계를 끝까지 밟습니다. 중간에 멈추면 다시 "누구는 v1 을 보는" 상태로 돌아갑니다.

단계하는 일빠뜨리면
1소스 수정
spec.md / mockups/ / docs/ / qa.md / impl.md
2bump 읽는 사람이 바뀐 걸 모릅니다. 버전도 그대로라 최신인지 판단할 근거가 없어집니다
3lint 정합성이 깨진 명세가 병합돼 링크가 깨집니다
4커밋 → PR → 병합 배포되지 않습니다. 브랜치에 푸시만 한 상태는 링크에 반영되지 않습니다

4-1. 실제로는 말로 시킵니다

파일을 직접 고치고 끝내면 버전과 이력이 빠집니다. Claude Code 에 이렇게 말하면 2·3단계까지 도구가 챕니다.

"DOP-16724 상세내역 필터에서 전체 옵션 빼고, 클릭한 행의 휴가유형이 기본 선택되게 해줘"
"근무그룹 휴가사용시간 설정 개발기능점검 체크리스트 만들어줘"
"기타휴가 회수 목업에 회수 사유 입력칸 추가해줘"
"DOP-20230 지금 최신 버전 뭐야?"
"DOP-19102 뭐 바뀌었어? 배포해야 해?"

4-2. 요구사항을 추가 / 변경 / 뺄 때

상황하는 일
추가기존 번호 다음 번호로 새 카드를 씁니다. 중간에 빈 번호가 있어도 재사용하지 않습니다
변경같은 카드의 본문을 고치고, --noteREQ-00X 변경: 으로 무엇이 어떻게 바뀌었는지 적습니다
범위에서 빼기지우지 않고 - 상태: 제외 로 바꿉니다. 이력 추적과 점검 회귀 판단에 쓰입니다
쟁점이 열려 있음- 상태: 확정필요 로 두면 허브 상단에 건수가 떠서 유관부서가 미결을 놓치지 않습니다

4-3. 기획 오너가 병합 전에 확인하는 방법

다른 부서가 커밋한 변경을 검토할 때 씁니다. 기준은 origin/main — 즉 지금 배포된 것과 현재 소스의 차이입니다.

python3 $S review "specs/DOP-16724_기타휴가_부여이력,_회수"
  • 배포 이후 커밋 — 누가 언제 무엇을 바꿨는지
  • 요구사항 차이 — 번호 단위로 추가 / 상태 변경 / 본문 변경 / 삭제 (삭제가 보이면 번호 재사용 금지 원칙 위반이므로 제외 상태로 되살립니다)
  • 판정최신 이면 할 일 없음. 미배포 변경 있음 이면 병합하면 반영됩니다. 변경은 있는데 버전이 그대로면 bump 누락이므로 먼저 올립니다
예외 도구(스킬) 자체가 업그레이드된 경우는 명세가 그대로여도 허브 화면 구성이 바뀝니다. 기획 변경이 아니므로 bump 하지 말고 그냥 병합하면 됩니다.

PART 5역할별로 만지는 파일이 다릅니다

서로 다른 파일을 만지므로 같은 기능을 동시에 작업해도 충돌이 거의 없습니다. 아래는 각 역할이 자기 파일에서 할 일입니다. 끝은 누구나 같습니다 — 커밋과 PR.

역할파일하는 일
기획spec.md · mockups/요구사항·흐름도·버전. 명세 오너이고 문의에 답을 답니다
디자인mockups/화면 수정. 태깅 유지가 핵심입니다
개발impl.md · qna.md구현 대조 결과, 판단이 안 되는 지점은 문의로
QAqa.md점검 케이스 작성·체크

5-1. 디자인 mockups/

화면을 고칠 때 data-req 를 지우지 않는 것이 유일한 추가 규칙입니다. 태깅이 끊기면 명세의 "화면에서 보기" 가 그 요소를 못 짚고, 검사에서 경고가 뜹니다. 요소를 새로 만들면 대응하는 번호를 함께 붙입니다. 나머지 작성 규칙은 3장 6단계의 표와 같습니다.

5-2. 개발 impl.md

"기획안대로 만들어졌는가" 를 요구사항 단위로 남깁니다. QA가 기획 목업이 아니라 실제 구현 기준으로 검증할 수 있게 하는 파일입니다.

impl.md
## REQ-001 — 반영

- 근거: `src/main/webapp/annual/carryover.jsp:120`
- 차이: 없음

## REQ-003 — 부분반영

- 근거: `PolicyController.java:88`
- 차이: 변경자 필터가 이름 완전일치로만 동작(명세는 부분검색)
- 후속: 부분검색으로 구현 수정 예정
  • 제목 형식은 ## REQ-xxx — {상태}. 상태는 반영 / 부분반영 / 미반영 / 해당없음 넷 중 하나입니다
  • 해당없음 은 구현 대상이 아닌 요구사항(예: 문서 정책) — 진행률에서 빠집니다
  • 이 내용은 허브의 구현 탭에서만 보입니다. 명세 카드나 상단 배너에는 붙지 않습니다 — 기획 검토 단계에서는 대부분 미반영 이라 카드마다 붙으면 잡음이 됩니다

5-3. QA qa.md

qa.md
## REQ-001

- [x] QA-001-1 이월 한도 입력칸이 정책 카드 우측에 노출된다
- [ ] QA-001-2 한도를 0 으로 저장하면 경고가 뜬다
- [ ] QA-001-3 상한 초과 입력 시 저장이 막힌다
  • ## REQ-xxx 로 묶고 - [ ] / - [x] 체크박스를 씁니다. 체크하면 허브의 진행률(점검 3/8)에 그대로 반영됩니다
  • 정상 · 경계 · 예외를 나눠 씁니다
  • 검증 범위는 구현 탭부분반영 · 미반영 항목으로 잡습니다
QA 가 지켜야 하는 것 명세에 없는 내용을 점검 케이스로 새로 만들지 않습니다. 빠진 게 보이면 케이스를 몰래 늘리지 말고 명세에 요구사항을 먼저 추가해 달라고 요청합니다 (또는 문의로 올립니다). 없는 번호를 쓰면 검사에서 오류로 걸립니다.

PART 6문의(Q&A) 주고받기

명세를 보다 확인이 필요할 때, 채팅으로 묻지 않고 문서 옆에 남깁니다. 채팅에 물으면 답이 흩어지고 다음 사람이 같은 질문을 다시 합니다.

파일이 없으면 만듭니다 qna.md 는 스캐폴딩에 포함되지 않습니다. 기능 폴더에 직접 만들면 허브에 문의 탭이 생깁니다.
specs/{기능폴더}/qna.md
## Q-001 · 이월 한도를 근무그룹별로 다르게 둘 수 있나요?

- 유형: 개발          # 개발 | 디자인 | 기획 | 기타
- 관련: REQ-002, REQ-003
- 상태: 대기          # 대기 | 확인중 | 답변완료 | 보류
- 문의: 2026-08-11 홍길동

질문 본문. 표·목록·`코드` 를 쓸 수 있습니다.

### 답변 — 2026-08-11 정민경

답변 본문. 명세를 고쳐서 답했다면 어느 요구사항을 어떻게 바꿨는지 함께 적습니다.
  • 관련: 에 적은 번호의 명세 카드에 문의 N건 칩이 붙습니다
  • 답변 없는 문의가 있으면 허브 상단에 미답변 N 버튼이 떠서 기획이 놓치지 않습니다
  • ### 답변 을 아래로 이어 붙이면 스레드가 됩니다 — 여러 번 답할 수 있습니다
  • 문의 번호도 재사용하지 않습니다. 없던 일이 된 문의는 지우지 말고 상태: 보류 로 남깁니다(같은 질문이 다시 올라오는 것을 막습니다). 보류는 미답변으로 세지 않습니다
  • 명세가 바뀌어야 하는 문의라면 답변만 달고 끝내지 않습니다spec.md 를 고치고 bump 로 이력에 남깁니다

PART 7검사 결과 읽는 법

lint 의 출력은 두 종류입니다. 오류는 배포를 막고, 경고는 판단을 요청합니다. 경고를 없애려고 내용을 지우는 것이 가장 나쁜 선택입니다.

오류 배포 차단

무엇이 걸렸나어떻게 고치나
앞머리 필수 키 누락 / status 규격 위반 key · title · version · status 를 채웁니다. 상태는 기획중 / 리뷰중 / 확정 / 개발중 / QA중 / 배포완료 중 하나
요구사항 0건 / 번호 중복 / 제목·상태 누락 ### REQ-xxx · 제목- 상태: 를 형식대로 씁니다
목업 data-req 가 명세에 없는 번호를 가리킴 유령 참조 번호 오타이거나, 요구사항이 지워졌는데 태깅만 남은 경우입니다. 태깅을 고치거나 요구사항을 제외 상태로 되살립니다
흐름도가 없는 번호를 참조 도식 안의 번호를 고칩니다
qa.md / impl.md 가 없는 번호를 가리킴 명세에 그 요구사항을 먼저 추가하거나, 잘못 적은 번호를 고칩니다
version 과 변경이력 최신 항목 불일치 거의 항상 손으로 고쳐서 생깁니다. bump 로 올리면 둘이 같이 움직입니다. 충돌 정리 중이면 8장

경고 판단해서 처리

무엇을 알려주나보통 이렇게 합니다
요구사항 번호 중간에 빈 번호가 있음 지운 요구사항이면 - 상태: 제외 로 되살려 둡니다
목업 태깅이 없는 요구사항 화면 요소가 없는 요구사항이면 - UI: 없음 을 적어 면제받습니다
확정 상태인데 점검 케이스가 없음 확정된 요구사항은 qa.md 에 케이스를 채웁니다
기획문서 표준 목차 미작성 비어 있는 장을 채웁니다. 장을 지워서 경고를 없애지 않습니다
흐름도 없음 업무·백엔드 흐름이 있는 기능이면 3장에 mermaid 를 넣습니다
확정필요 요구사항 목록 미결 쟁점 알림입니다. 확정되면 상태를 확정 으로 바꿉니다
mermaid 렌더러 없음 로컬 환경 얘기입니다. 무시해도 됩니다 — 배포본은 CI가 도식으로 그립니다

PART 8충돌이 나는 곳은 두 군데뿐입니다

CHANGELOG.md — 가장 흔합니다

새 항목이 항상 맨 위에 들어가므로, 두 사람이 같은 기능을 동시에 bump 하면 같은 줄에서 충돌합니다.

해결 두 항목을 모두 남기고 버전만 순서대로 정리한 뒤, spec.mdversion맨 위 항목과 맞춥니다. 그다음 lint 로 확인합니다 — 불일치를 잡아주므로 틀린 채로 병합되지는 않습니다.
예방 bump 를 작업 시작이 아니라 PR 올리기 직전에 한 번만 돌립니다. 이것만으로 빈도가 크게 줄어듭니다.

spec.md 의 같은 요구사항

기획 두 명이 같은 번호를 동시에 고치는 경우입니다. 요구사항 단위로 블록이 나뉘어 있어 대체로 자동 병합되지만, 같은 블록이면 사람이 판단해야 합니다. 도구로 풀 문제가 아니라 오너를 정하는 문제라서, 앞머리의 owners.기획 을 채워 둡니다.

생성물 충돌은 없습니다 hub.html 은 git 에서 제외돼 있어 생성물 충돌은 아예 발생하지 않습니다.

PART 9막혔을 때

"내가 올린 게 왜 링크에 안 보이지?"

순서대로 확인합니다. ① main병합됐는지 — 브랜치에 푸시만 한 상태는 배포되지 않습니다(가장 흔한 원인). ② GitHub Actions 탭에서 명세 허브 배포 가 성공했는지. ③ 브라우저 새로고침(강제 새로고침).

"목록에 내 기능이 없다"

specs/ 폴더 안에 있어야 합니다. 레포 루트의 낱개 파일은 목록에 뜨지 않습니다. 그리고 spec.md 와 산출물(목업·문서)이 둘 다 있어야 배포본에 들어갑니다 — 하나라도 없으면 dist 가 건너뛰고 그 사실을 출력합니다.

"내 기능이 미분류에 있다"

앞머리에 project: 를 적지 않았습니다. 3장 2단계 참고.

"목록에서 내 문서를 못 찾겠다"

메인 화면 검색창에 이슈 키(DOP-19102) · 문서명(연차정책) · 작성자(정민경) 중 아무거나 넣습니다. 공백으로 끊으면 AND 조건이라 연차 정민경 처럼 좁혀갈 수 있습니다.

"흐름도가 도식이 아니라 글자로 보인다"

로컬에 mermaid 렌더러가 없을 때 나오는 정상 동작입니다. npm i -g @mermaid-js/mermaid-cli 를 한 번 하면 됩니다. 배포본은 항상 도식입니다.

"변경이력에서 옛 버전이 '스냅샷 없음' 이라고 나온다"

그 버전의 원문이 git 이력에 없다는 뜻입니다(단일 원천으로 옮기기 전에 매긴 버전). 없는 것을 없다고 보여주는 편이, 조용히 빠져 아무도 눈치채지 못하는 것보다 낫다고 보고 그대로 노출합니다.

"Cloudflare 계정이 필요한가?"

아니요. GitHub 접근만 있으면 됩니다.

지금 알아둘 제약 열람 제한이 아직 걸려 있지 않습니다. 사이트가 현재 인터넷에 공개돼 있어, @daou.co.kr 접근 제한을 걸기 전에는 유관부서에 링크를 널리 뿌리지 않는 편이 안전합니다. PR 단계 자동 검사도 아직 없습니다 — 그래서 lint 를 직접 돌리는 3단계가 지금은 필수입니다.

PART 10치트시트

명령어

S=".claude/skills/spec-hub/scripts/spechub.py"

python3 $S status                       # 전체 현황표 (버전·상태·배포·진행률)
python3 $S lint                         # 정합성 검사 — PR 전에 필수
python3 $S build specs/DOP-16724_*      # hub.html 생성 → 브라우저로 미리보기
python3 $S review specs/DOP-16724_*     # 배포본과 현재 소스의 차이
python3 $S new DOP-21000 "새 기능명"     # 폴더 + 파일 5개 스캐폴딩
python3 $S bump specs/DOP-16724_* --author "이름" --note "REQ-001 변경: …"
python3 $S dist                         # 전체 배포본 생성 (CI 가 쓰는 것)

말로 시키기

"DOP-16724 상세내역 필터 기본값을 클릭한 행의 휴가유형으로 바꿔줘"
"DOP-20675 개발기능점검 체크리스트 만들어줘"
"DOP-19102 지금 최신 버전 뭐야?"
"DOP-20230 뭐 바뀌었어? 배포해야 해?"
"기타휴가 회수 목업에 회수 사유 입력칸 추가해줘"
"연차 이월 정책 개편 새로 기획 시작할게, 폴더 만들어줘"

절대 하지 않는 것 여섯 개

요구사항 번호 재사용

  • 없어진 요구사항은 - 상태: 제외
  • 번호는 계속 올려 씁니다

hub.html 손으로 고치기

  • 생성물입니다. 다음 빌드에서 덮어써집니다
  • 항상 소스를 고칩니다

version 직접 수정

  • bump 가 변경이력과 함께 올립니다
  • 손으로 고치면 검사에서 오류

변경이력을 손으로 쓰기 · 지우기

  • 항목은 쌓기만 합니다
  • 지우거나 순서를 뒤집으면 as is 가 어긋납니다

명세 본문을 채팅에 붙여넣기

  • 링크와 변경 요약만 남깁니다
  • 원본이 흩어지는 경로입니다

main 에 직접 커밋

  • 병합 즉시 유관부서 링크가 바뀝니다
  • 브랜치 → PR 을 지킵니다

기억할 문장 하나

고쳤으면 네 단계를 끝까지 밟습니다 — 수정 → bump → lint → 병합. 중간에 멈추면 다시 "누구는 v1 을 보는" 상태로 돌아갑니다. 링크는 영구적이라 처음 한 번만 보내면 되고, 이후에는 "v1.2.0 올렸습니다, REQ-003 바뀜" 정도만 알리면 됩니다.