Redmine 공정관리 시스템 운영 가이드
Google Sheets ↔ n8n ↔ Redmine 양방향 동기화 기반 WBS 공정 관리 워크플로우
🏗️01. 시스템 구성
Google Sheets
계획 마스터
WBS 작성 · 대시보드
WBS 작성 · 대시보드
▶ Workflow A
◀ Workflow B
via webhook
n8n
동기화 중개자
HMAC 검증 · 변환 · 충돌 감지
HMAC 검증 · 변환 · 충돌 감지
▶ REST API
◀ Webhook
via HTTPS
Redmine
실적 마스터
이슈 · 진행률 · 코멘트
이슈 · 진행률 · 코멘트
| 시스템 | URL | 역할 |
|---|---|---|
| Redmine | https://redmine.gc-si.dev |
이슈 관리, 실적 입력, 진행률 관리 |
| n8n | https://guide.gc-si.dev/n8n |
양방향 동기화 자동 처리 |
| Google Sheets | 프로젝트별 스프레드시트 (PMO가 안내) | WBS 계획 작성, 대시보드 모니터링 |
👥02. 역할별 작업 흐름
PM / PL
계획 수립 · 일정 관리
Google Sheets에서 WBS 작성
CWBS Code (예: 1.1.2)DDep (계층 깊이 0~7)E가중치F~K작업명 (Dep에 따라 해당 열)M담당자O계획 시작일P계획 종료일 ← 자동 동기화 발동- UUID 자동 생성 (AB열)
- n8n Workflow A → Redmine 이슈 생성
- 이슈 ID 역기록 (AC열)
개발자
실적 입력 · 진행률 갱신
Redmine에서 작업
- 이슈 상태 변경: 대기 → 진행중 → 완료
- 진행률 입력: 30% → 50% → 100%
- n8n Workflow B → Sheets 실적 컬럼 갱신
- 실적진척율 (U열)
- 실적시작일 (S열)
- 실적종료일 (T열)
PMO
모니터링 · 위험 관리
Sheets 대시보드 확인
- 계획 진척 vs 실적 진척 비교
- SPI (일정성과지수) 확인
- 잔여일 (Y열) 확인
- 지연 여부 (Z열) 확인
- 충돌큐 시트 처리
≥ 0.95 양호 ·
0.85~0.95 주의 ·
< 0.85 위험
🔀03. Git 커밋 — Redmine 이슈 연동
Gitea에 push한 커밋 메시지에 이슈 번호를 포함하면, Redmine이 자동으로 해당 이슈에 커밋을 연결합니다.
동기화 방식
1
개발자가 Gitea에 push
커밋 메시지에 키워드 + 이슈 번호 포함
2
cron (5분마다) bare clone fetch
/opt/redmine/repos/<프로젝트>.git 갱신3
Redmine이 새 커밋 읽고 키워드 파싱
refs, fixes 등 키워드 매칭
4
해당 이슈에 커밋 이력 자동 연결
이슈 상세 → "관련 변경분" 탭에 표시
키워드 — Keep a Changelog 규격
참조 키워드 (상태 변경 없음, 커밋-이슈 연결만)
| 키워드 | 효과 |
|---|---|
refs |
이슈에 커밋 참조 연결 |
references |
동일 |
상태 변경 키워드 (커밋 시 이슈 상태/진행률 자동 변경)
| 키워드 | 의미 | Redmine 상태 | 진행률 |
|---|---|---|---|
Added |
새로운 기능 | 진행중 | 50% |
Changed |
기존 기능의 변경사항 | 진행중 | 50% |
Deprecated |
곧 지워질 기능 | 보류 | 유지 |
Removed |
지금 지워진 기능 | 완료 | 100% |
Fixed |
버그 픽스 | 완료 | 100% |
Security |
취약점이 있는 경우 | 진행중 | 50% |
커밋 메시지 작성 규칙
<유형>: <설명> #이슈번호
# 새 기능 추가 → 이슈 진행중 (50%)
git commit -m "Added: 사용자 인증 모듈 추가 #12"
# 버그 수정 → 이슈 완료 (100%)
git commit -m "Fixed: 로그인 실패 시 에러 메시지 미표시 수정 #30"
# 기존 기능 변경 → 이슈 진행중 (50%)
git commit -m "Changed: API 응답 포맷 변경 #15"
# 기능 지원 중단 예정 → 이슈 보류
git commit -m "Deprecated: v1 API 지원 중단 예정 #20"
# 기능 제거 → 이슈 완료 (100%)
git commit -m "Removed: 레거시 인증 방식 제거 #25"
# 보안 패치 → 이슈 진행중 (50%)
git commit -m "Security: XSS 취약점 패치 #35"
# 참조만 (상태 변경 없음)
git commit -m "DB 스키마 설계 refs #12"
# 여러 이슈 동시 참조
git commit -m "Changed: 공통 모듈 리팩토링 #12, #13"
확인 방법: Redmine에서 이슈 상세 페이지 → "관련 변경분" 탭에서 연결된 커밋 확인. 커밋 해시, 작성자, 메시지, 변경 파일 목록이 표시됩니다.
현재 연동 저장소
| 프로젝트 | Gitea 저장소 | Redmine 경로 |
|---|---|---|
| AI 불법조업 | gc/snp-connection-monitoring |
/opt/redmine/repos/snp-connection-monitoring.git |
저장소 추가 절차: bare clone 생성 → Redmine 프로젝트에 저장소 등록 → cron 추가
📊04. Google Sheets 시트 구조
공정 진행표(WBS) — 행 구성
Row 1: n8n용 숨김 헤더 (1px, 사용자에게 안 보임)
Row 2: 메타 영역 — 제목, 기준일자, 계획진척, 실적진척, SPI, 양호도
Row 3~5: 2단 헤더 (병합)
Row 6+: 데이터
열 그룹 — 입력 주체
| 열 그룹 | 열 | 입력 주체 | 설명 |
|---|---|---|---|
| 식별 | B~D | PM/PL | No, WBS Code, Dep |
| 계획 | E~Q | PM/PL | 가중치, 작업명(F~K), 담당자(L), 계획일정/진척율 |
| 실적 | R~U | 자동 (수식+n8n) | 실적시작일, 종료일, 진척율, 구성비 |
| 지표 | V~Y | 자동 (수식) | 구성진행비율, 잔여일, 차 |
| 결과 | Z | PM/PL | 산출물명 → Redmine Deliverable 동기화 |
| 시스템 | AA~AF | 자동 (n8n) | sheets_row_id, redmine_issue_id, last_synced, sync_locked, sync_status, redmine_done_ratio |
| 동기화 플래그 | AG |
PM/PL | TRUE = Redmine 동기화 대상, FALSE/빈값 = 비대상 |
자동 계산 수식 (템플릿 기본 제공)
| 열 | 수식 | 설명 |
|---|---|---|
N 계획기간 | =CONCATENATE(NETWORKDAYS(O,P,공휴일),"일") | 영업일 기준 기간 |
R 계획구성비 | =E × Q / 100 | 가중치 × 계획진척율 |
V 실적구성비 | =E × U | 가중치 × 실적진척율 |
W 구성비계획 | =Q × E / 100 | 가중치 × 계획진척율 |
X 구성비실적 | =E × U | 가중치 × 실적진척율 |
Y 잔여일 | =NETWORKDAYS(TODAY(), P, 공휴일) | 영업일 기준 |
Z 차 | =X - W | 구성비 실적 - 계획 차이 |
PMO가 직접 설정해야 하는 수식
주의: Q열(계획 진척율)과 W열(구성진행비율)은 Dep 계층 구조에 따라 수식이 달라지므로 PMO가 WBS 구조 확정 후 직접 설정해야 합니다.
말단 작업 (Dep 2~7) — Q열
=IF(COUNTBLANK(O:P)>0, 0,
1/NETWORKDAYS(O,P) * IF(기준일자<=O, 0,
NETWORKDAYS(O, IF(기준일자>P, P, 기준일자))))
기준일자: 메타 영역의 기준일자 셀 참조 (절대참조)- 계획 기간 대비 기준일자까지의 경과 비율을 자동 계산
상위 노드 (Dep 0~1) — Q열
=SUM(W하위행1, W하위행2, ...)
- 하위 작업의 구성진행비율(W열) 합산
- 하위 행 범위는 WBS 구조에 따라 수동 지정
상위 노드 (Dep 0) — W열
=W하위행1 + W하위행2 + ...
- 하위 Dep 1 행의 W값 합산
- 하위 행 범위는 수동 지정
참고: 원본 엑셀(MDA4_PB_07)의 수식을 참조하여 프로젝트 WBS 구조에 맞게 설정하세요.
대시보드 (메타 Row 3)
| 지표 | 수식 | 설명 |
|---|---|---|
| 계획진척 | =SUMPRODUCT(가중치, 계획진척율) / SUM(가중치) | 가중 평균 |
| 실적진척 | =SUMPRODUCT(가중치, 실적진척율) / SUM(가중치) | 가중 평균 |
| SPI | =실적진척 / 계획진척 | 일정성과지수 |
| 양호도 | SPI ≥ 0.95 양호 0.85~ 주의 < 0.85 위험 | — |
충돌큐 시트
- 동기화 충돌 발생 시 자동 기록
- 해결 상태:
OPEN→RESOLVED_SHEETS/RESOLVED_REDMINE/RESOLVED_MANUAL - PMO가 확인 후 처리
공휴일 시트
- 대한민국 공휴일 목록
- NETWORKDAYS 수식에서 참조
- 연도별 업데이트 필요
🔄05. Redmine 이슈 상태 흐름
상태 흐름은 트래커(일감 종류)에 따라 다릅니다.
기능 트래커 (기본 상태: 대기)
대기
→
진행중
→
완료
↕ 진행중에서 분기:
보류
(상호 전환)
💡 완료 → 진행중 으로 재오픈 가능
비기능 트래커 (기본 상태: 부분)
부분
↔
외부산출물
비기능 트래커는 닫히는(closed) 상태가 없습니다 — 부분 / 외부산출물 모두 진행 상태로 유지됩니다.
상태 정의
| 상태 | ID | 트래커 | closed | 설명 | 실적진척율 |
|---|---|---|---|---|---|
| 대기 | 7 | 기능 | — | 착수 전 | 0% |
| 진행중 | 8 | 기능 | — | 진행 중 | 1~99% |
| 보류 | 12 | 기능 | — | 보류 | 유지 |
| 완료 | 13 | 기능 | ✓ | 완료 | 100% |
| 부분 | 9 | 비기능 | — | 부분 산출 | 유지 |
| 외부산출물 | 11 | 비기능 | — | 외부 산출물 | 유지 |
📦06. 산출물 관리
산출물은 하이브리드 방식으로 관리합니다.
- 작업 중 산출물 + 대장 · 라이프사이클 →
산출물트래커 이슈 (필터 · 검색 · 상태 추적 가능) - 승인된 최종본 보관함 → 문서 모듈 (분류별 라이브러리)
필터링 · 정렬 · 그룹이 되는 "산출물 대장"의 정본은 이슈 기반입니다. 문서 모듈은 최종본 보관 용도입니다.
산출물 트래커 (이슈)
산출물 트래커로 이슈를 만들면 산출물 1건이 됩니다. 이슈 제목 = 산출물명, 설명 = 주요 내용.
| 필드 | 형식 | 값 / 비고 |
|---|---|---|
| 산출물코드 | 텍스트 | AN-01, DS-12 등 |
| 단계 | 목록 | 분석 / 설계 / 구현 / 시험 / 안정화 / 감리 |
| 산출물유형 | 목록 | 필수 / CBD / 감리 / 선택 |
| 관련요구사항 | 텍스트 | 요구사항ID (예: COR-01) |
| AI산출물 | 예/아니오 | AI 관련 산출물 플래그 |
| 검토자(Reviewer) | 사용자 | 검토 담당자 |
| 담당자 | 사용자 | 작성 담당자 |
| 첨부 | 파일 | 산출물 파일 (최대 100MB) |
산출물 상태 흐름
기존 상태를 산출물 라이프사이클로 사용합니다.
| 상태 | 산출물 의미 |
|---|---|
| 대기 | 착수 전 |
| 진행중 | 작성 중 |
| 부분 | 초안 / 부분 제출 |
| 외부산출물 | 외부 작성 (감리법인 등) |
| 보류 | 반려 / 보류 |
| 완료 | 승인(최종) — 종료 |
대기
→
진행중
→
완료 (승인)
↕ 진행중에서 분기:
부분
(상호 전환)
대기
→
외부산출물
→
완료
💡 반려 시 → 보류 상태로 이동
산출물 대장 (저장 쿼리)
상단 일감 → 쿼리 목록 "산출물 대장" (전 프로젝트 공통, 공개).
단계별로 그룹되어 코드 · 유형 · 담당자 · 검토자 · 상태 · 관련요구사항이 한눈에 보입니다.
단계별로 그룹되어 코드 · 유형 · 담당자 · 검토자 · 상태 · 관련요구사항이 한눈에 보입니다.
문서 모듈 (승인 최종본 보관함)
프로젝트 → 문서 → 새 문서.
- 분류(category) = 단계: 분석 / 설계 / 구현 / 시험 / 운영 / 감리 산출물
- 문서 커스텀필드: 산출물코드 · 산출물유형 · 관련요구사항 · AI산출물 (이슈와 동일 라벨)
- 문서 목록은 분류별 묶음으로만 표시 (이슈처럼 필드 필터 · 정렬은 없음)
문서 권한
| 역할 | 조회 | 추가 | 편집 | 삭제 |
|---|---|---|---|---|
| 관리자 / PM / PL / PMO | ✓ | ✓ | ✓ | ✓ |
| 개발자 | ✓ | ✓ | ✓ | ✗ |
| 보고자 / 검토자 | ✓ | ✗ | ✗ | ✗ |
작업 절차
1
산출물 트래커로 이슈 생성
코드 · 단계 · 유형 · 관련요구사항 · 검토자 입력
2
작성 중 파일을 이슈에 첨부
상태: 진행중 / 부분
3
검토자 검토 → 승인 시 상태 변경
승인 → 완료 / 반려 → 보류
4
승인 최종본을 문서 모듈에 등록
해당 분류(단계)로 업로드 + 커스텀필드(코드 · 유형 · 요구사항 · AI) 입력
5
"산출물 대장" 쿼리로 단계별 진행 현황 추적
PMO/PM이 주간 단위 점검
➡️07. Workflow A · Sheets → Redmine 이슈 생성/수정
트리거
- PM/PL이 Sheets에 새 행 입력 후 AG열(sync_flag)을 TRUE로 설정
- 이후 계획 필드 수정 시 Apps Script
onEditWBS자동 발동 - AG열이 TRUE가 아닌 행은 동기화하지 않음 (선택적 동기화)
동기화 조건 (모두 충족 시)
AG열
sync_flag (필수)
TRUE 필수 — Redmine 관리 대상 행만 체크
C열
WBS Code
계층 코드 (예: 1.1.2)
F~K열 중 하나
작업명
Dep에 따라 해당 열에 입력
N열
계획 시작일
yyyy-mm-dd
O열
계획 종료일
yyyy-mm-dd
처리 흐름
1
PM/PL이 AG열을 TRUE로 설정
Redmine 관리 대상 행만 sync_flag 체크 — 선택적 동기화
2
계획 필드 입력/수정 → onEditWBS 발동
Apps Script가 변경 감지
3
sync_flag=TRUE 확인 + 필수 필드 검증
AG열이 TRUE가 아니거나 필수 필드 누락 시 중단
4
UUID 자동 생성 (AA열)
없을 때만 자동 부여 — 동기화 식별 키
5
n8n webhook 호출
HMAC 서명 포함 — 위조 방지
6
데이터 검증
WBS Code 형식, 날짜 유효성, 담당자 매핑 등
7
Redmine API 호출 (분기)
AB열에 issue_id 있음 →
PUT (기존 이슈 수정) / 없음 → POST (신규 이슈 생성)8
Sheets 역기록
redmine_issue_id, last_synced, sync_status 갱신
9
검증 실패 시 충돌큐 기록
충돌큐 시트에 에러 row 추가 + PMO 알림
Sheets → Redmine 필드 매핑
| Sheets 열 | Redmine 필드 | 방향 |
|---|---|---|
C WBS Code | WBS Code (UDF) | Sheets → Redmine |
D Dep | Tree Depth (UDF) | Sheets → Redmine |
E 가중치 | Weight (UDF) | Sheets → Redmine |
F~K 작업명 | Subject | Sheets → Redmine |
N 계획시작일 | Start Date | Sheets → Redmine |
O 계획종료일 | Due Date | Sheets → Redmine |
P 계획진척율 | Planned Ratio (UDF) | Sheets → Redmine |
Z 산출물 | Deliverable (UDF) | Sheets → Redmine |
AA sheets_row_id | Sheets Row ID (UDF) | 양방향 (동기화 키) |
⬅️08. Workflow B · Redmine → Sheets 실적 동기화
트리거
- Redmine 이슈 변경 시 webhook 호출 (수동 또는 플러그인)
- 현재: 수동 webhook 호출 / 추후: redmine_webhook 플러그인으로 자동화 예정
처리 흐름
1
Redmine 이슈 변경
상태 / 진행률 / 코멘트 등
2
n8n webhook 수신
payload 정규화
3
Sheets Row ID로 해당 행 조회
UDF의 sheets_row_id로 Sheets에서 lookup
4
충돌 검출 (5초 이내 동시 편집)
last_synced와 updated_on 비교
5
Sheets 실적 컬럼 갱신
충돌 없으면 U, S, T 컬럼 갱신
6
충돌 시 충돌큐 기록
PMO 수동 처리 대기
Redmine → Sheets 필드 매핑
| Redmine 필드 | Sheets 열 | 방향 |
|---|---|---|
done_ratio (진행률) | U 실적진척율 | Redmine → Sheets |
| Actual Start (UDF) | S 실적시작일 | Redmine → Sheets |
closed_on | T 실적종료일 | Redmine → Sheets |
issue.id | AC redmine_issue_id | Redmine → Sheets |
📁09. 프로젝트 목록
ai-illegal-fishing
AI 불법조업
AI 기반 불법조업 탐지·차단 플랫폼
wing
WING
해양환경 위기대응 플랫폼 - 2차
mda5
MDA5
해양경비지원 플랫폼 - 5차
mof
해수부
해수부 플랫폼
⚠️10. 주의사항
1. sync_flag (AG열) —
TRUE인 행만 Redmine에 동기화됩니다. 모든 WBS 항목을 관리할 필요 없이, Redmine으로 관리할 행만 선택적으로 체크하세요.
2. Sheets 편집 시 —
sync_flag=TRUE + 필수 4개 필드(C, F~K, N, O) 충족 시에만 동기화 발동합니다.
2-1. 상위(부모) 작업 행은 날짜·진척 수정 불가 — 하위 이슈가 등록된 행은 시작일·종료일·진척률이 하위 작업에서 자동 계산(롤업)됩니다(Redmine
parent_issue_dates=derived). 따라서 시트에서 부모 행의 계획시작일(N)·계획종료일(O)·계획진척율(P)을 바꿔도 Redmine에 반영되지 않습니다. 계획 일정·진척률은 반드시 말단(최하위) 작업 행에서 입력하세요. 부모/단계 행의 값은 자식들로부터 자동으로 채워집니다.
3. sync_locked (AD열) —
TRUE로 설정하면 해당 행 동기화 차단. 일괄 작업 시 활용하세요.
4. 시스템 컬럼 (AA~AF) — 수동 편집 금지. n8n이 자동 관리합니다.
AG열(sync_flag)만 사용자가 직접 설정.
5. 이슈 삭제 — Redmine에서 이슈 삭제 시 Sheets에는 반영되지 않습니다 (수동 정리 필요).
6. 공휴일 — 매년 초 공휴일 시트 업데이트 필요. NETWORKDAYS 수식이 참조합니다.
7. 담당자 — 현재 Redmine assigned_to 자동 매핑 미구현. 수동 지정해주세요.
8. 산출물 (Z열) — Redmine
Deliverable(산출물명) 필드에 자동 동기화됩니다.