From 4b4ffafbd27b06e57159219dc2d61d9ad52b1391 Mon Sep 17 00:00:00 2001 From: hyunho Date: Tue, 31 Mar 2026 17:47:39 +0900 Subject: [PATCH] docs: persist isolated 8081 startup workflow --- .gitignore | 1 + docs/DEV_PROD_DB_PROTOCOL.md | 10 +- docs/NEXT_SESSION_CHECKPOINT.md | 3 + docs/REGRESSION_CHECKLIST.md | 4 +- docs/WORK_EXECUTION_FLOW.md | 259 ++++++++++++++++++++++++++++++ docs/WORK_RULEBOOK.md | 8 +- scripts/prepare_dev_worktree.sh | 23 ++- scripts/start_8081.sh | 15 ++ scripts/start_local_dashboards.sh | 12 ++ 9 files changed, 320 insertions(+), 15 deletions(-) create mode 100644 docs/WORK_EXECUTION_FLOW.md create mode 100755 scripts/start_8081.sh create mode 100755 scripts/start_local_dashboards.sh diff --git a/.gitignore b/.gitignore index 69c9240..362ef2c 100755 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ incoming-files/~$* incoming-files/6f.html incoming-files/7f.html incoming-files/center.html +.dev-worktree-8081/ diff --git a/docs/DEV_PROD_DB_PROTOCOL.md b/docs/DEV_PROD_DB_PROTOCOL.md index ce5ca3e..27024b3 100644 --- a/docs/DEV_PROD_DB_PROTOCOL.md +++ b/docs/DEV_PROD_DB_PROTOCOL.md @@ -11,14 +11,14 @@ ### 코드 경로 - 공개용 `8080`: `/home/hyunho/projects/mh-dashboard-organization` -- 작업용 `8081`: `/tmp/mh-dashboard-organization-dev-worktree` +- 작업용 `8081`: `/home/hyunho/projects/mh-dashboard-organization/.dev-worktree-8081` ### 작업용 Compose 기준 - 공개용 `8080` stack: `docker-compose.yml` - 작업용 `8081` stack: `docker-compose.8081.yml` - 작업용 project name 기본값: `mh-dashboard-organization-dev` -- 작업용 `8081`는 반드시 `/tmp/mh-dashboard-organization-dev-worktree`에서 띄운다 +- 작업용 `8081`는 반드시 `/home/hyunho/projects/mh-dashboard-organization/.dev-worktree-8081`에서 띄운다 ### DB 볼륨 @@ -174,7 +174,7 @@ ```bash ./scripts/prepare_dev_worktree.sh -cd /tmp/mh-dashboard-organization-dev-worktree +cd /home/hyunho/projects/mh-dashboard-organization/.dev-worktree-8081 docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d --build ./scripts/sync_prod_db_to_dev.sh minimal ./scripts/sync_prod_db_to_dev.sh full @@ -182,7 +182,7 @@ docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compos `prepare_dev_worktree.sh`가 같이 처리하는 것: -- 메인 workspace를 `/tmp/mh-dashboard-organization-dev-worktree`로 복제 +- 메인 workspace를 `.dev-worktree-8081`로 복제 또는 재사용 - `.env` 복사 - 로컬 전용 디자인 참고 자산 복사 - `incoming-files/sample style.css` @@ -195,7 +195,7 @@ docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compos - `8081`은 현재 메인 workspace를 직접 마운트하면 안 된다 - 컨테이너가 `/home/hyunho/projects/mh-dashboard-organization/...`를 물고 있으면 분리 상태가 깨진 것이다 -- 정상 상태는 `docker inspect mh-dashboard-organization-dev-backend-1` 기준 마운트 소스가 `/tmp/mh-dashboard-organization-dev-worktree/...`로 나와야 한다 +- 정상 상태는 `docker inspect mh-dashboard-organization-dev-backend-1` 기준 마운트 소스가 `/home/hyunho/projects/mh-dashboard-organization/.dev-worktree-8081/...`로 나와야 한다 규칙: diff --git a/docs/NEXT_SESSION_CHECKPOINT.md b/docs/NEXT_SESSION_CHECKPOINT.md index 26c1760..3623c45 100644 --- a/docs/NEXT_SESSION_CHECKPOINT.md +++ b/docs/NEXT_SESSION_CHECKPOINT.md @@ -6,6 +6,7 @@ - latest checked commit: `24852d4` - main history doc: [DEVELOPMENT_HISTORY.md](/home/hyunho/projects/mh-dashboard-organization/docs/DEVELOPMENT_HISTORY.md) - work rulebook: [WORK_RULEBOOK.md](/home/hyunho/projects/mh-dashboard-organization/docs/WORK_RULEBOOK.md) +- execution flow: [WORK_EXECUTION_FLOW.md](/home/hyunho/projects/mh-dashboard-organization/docs/WORK_EXECUTION_FLOW.md) - dev/prod protocol: [DEV_PROD_DB_PROTOCOL.md](/home/hyunho/projects/mh-dashboard-organization/docs/DEV_PROD_DB_PROTOCOL.md) - regression checklist: [REGRESSION_CHECKLIST.md](/home/hyunho/projects/mh-dashboard-organization/docs/REGRESSION_CHECKLIST.md) - today prep note: [TODAY_WORK_PREP_2026-03-30.md](/home/hyunho/projects/mh-dashboard-organization/docs/TODAY_WORK_PREP_2026-03-30.md) @@ -97,8 +98,10 @@ - 코드 선행은 `8081`, 공개 반영은 `8080` - 데이터 정본은 `8080` DB - `8081` DB는 독립 정본이 아니라 `8080` 기준 복제본처럼 관리해야 함 +- `8081` 코드는 `.dev-worktree-8081` 기준으로 유지 - 조직도, 멤버, 자리배치 검증 전에는 `DEV_PROD_DB_PROTOCOL.md`를 먼저 확인 - 기능 수정 후 완료 판단은 `REGRESSION_CHECKLIST.md`를 기준으로 해야 함 +- 빠른 재시작은 `./scripts/start_local_dashboards.sh` ### Seat Map Save diff --git a/docs/REGRESSION_CHECKLIST.md b/docs/REGRESSION_CHECKLIST.md index d3eb8ef..3cd1661 100644 --- a/docs/REGRESSION_CHECKLIST.md +++ b/docs/REGRESSION_CHECKLIST.md @@ -25,8 +25,8 @@ - `8081` 작업용 접속 확인 - `8080` 공개용 접속 확인 - `docker compose ps`에서 `backend`, `frontend`, `proxy`, `db`가 정상인지 확인 -- `8081`은 기본적으로 `./scripts/prepare_dev_worktree.sh` 후 `/tmp/mh-dashboard-organization-dev-worktree` 에서 `docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d --build` 로 기동 -- `8081` 기동 후 `docker inspect mh-dashboard-organization-dev-backend-1`에서 마운트 경로가 `/tmp/mh-dashboard-organization-dev-worktree/...`인지 확인 +- `8081`은 기본적으로 `./scripts/start_8081.sh` 또는 `./scripts/prepare_dev_worktree.sh` 후 `.dev-worktree-8081` 에서 `docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d --build` 로 기동 +- `8081` 기동 후 `docker inspect mh-dashboard-organization-dev-backend-1`에서 마운트 경로가 `.dev-worktree-8081/...`인지 확인 ### 2. 데이터 동기화 범위 결정 diff --git a/docs/WORK_EXECUTION_FLOW.md b/docs/WORK_EXECUTION_FLOW.md new file mode 100644 index 0000000..9db488f --- /dev/null +++ b/docs/WORK_EXECUTION_FLOW.md @@ -0,0 +1,259 @@ +# Work Execution Flow + +## 목적 + +이 문서는 앞으로 이 프로젝트에서 작업을 어떤 순서로 진행해야 하는지 아주 쉽게 고정하기 위한 문서다. + +세미나에서 들은 흐름을 이 프로젝트 기준으로 다시 쓰면 아래 순서다. + +1. `SSOT` 먼저 확인 +2. 이슈 생성 또는 연결 +3. 완료조건 먼저 적기 +4. 실행 계획 적기 +5. 필요한 동기화 먼저 하기 +6. 코드 수정 / 화면 작업 수행 +7. 가드레일 테스트 +8. 기록 남기기 + +이 순서를 지키는 이유는 하나다. + +- 작업 도중 기준이 바뀌지 않게 하기 +- 임시 연결이 누적되지 않게 하기 +- 나중에 봐도 왜 이렇게 했는지 알 수 있게 하기 +- `8081` 작업이 `8080`을 망가뜨리지 않게 하기 + +## 1. SSOT 먼저 확인 + +`SSOT`는 Single Source Of Truth 의 줄임말이다. + +쉬운 말로: + +- "무엇을 기준 진실로 볼 것인가" + +이걸 먼저 정하지 않으면 작업 중간에 기준이 계속 바뀌어서 코드가 꼬인다. + +이 프로젝트에서 자주 쓰는 SSOT: + +- 공개용 코드 기준: `/home/hyunho/projects/mh-dashboard-organization` +- 작업용 코드 기준: `/home/hyunho/projects/mh-dashboard-organization/.dev-worktree-8081` +- 데이터 정본 기준: `8080` DB +- 기능 검증 기준: `8081` +- 사업관리대장 디자인 기준: `MH 통합 대시보드_260320.html` +- 허브 공통 시각 언어 기준: `sample style.css` +- 현재 작업 지시 기준: 연결된 Gitea 이슈 + +작업 시작 전에 먼저 정해야 하는 질문: + +- 이번 작업의 코드 기준은 어디인가? +- 이번 작업의 데이터 기준은 어디인가? +- 이번 화면의 디자인 기준 파일은 무엇인가? +- 지금 바꾸려는 화면이 실제로 어떤 파일에서 렌더링되는가? + +이걸 모르고 코드를 건드리면 높은 확률로 엉뚱한 파일을 수정하게 된다. + +## 2. 이슈 생성 또는 연결 + +작업은 이슈 없이 하지 않는다. + +이유: + +- 왜 하는 작업인지 남기기 위해 +- 중간에 범위가 커지는 걸 막기 위해 +- 다음 세션에서 바로 이어가기 위해 + +좋은 이슈는 아래 4개가 있어야 한다. + +1. 배경 +2. 목표 +3. 현재 상태 +4. 남은 작업 + +이슈는 길게 쓸 필요는 없다. +하지만 최소한 아래는 있어야 한다. + +- 왜 이 작업을 하는지 +- 어디까지가 이번 범위인지 +- 무엇을 완료로 볼지 + +## 3. 완료조건 먼저 적기 + +이 단계가 중요하다. + +완료조건이 없으면 "대충 된 것 같음" 상태에서 끝나기 쉽다. + +좋은 완료조건 예시: + +- `8081`이 `.dev-worktree-8081`를 실제로 마운트한다 +- `사업관리대장` 탭이 원본 기준 레이아웃으로 열린다 +- `8080`은 영향 없이 유지된다 +- 관련 회귀 검증을 통과한다 + +나쁜 완료조건 예시: + +- 화면이 좀 괜찮아 보인다 +- 아마 될 것 같다 +- 코드 정리함 + +완료조건은 반드시 확인 가능한 문장이어야 한다. + +즉: + +- "봤을 때 예쁨"이 아니라 +- "어떤 URL에서 어떤 동작이 확인됨"이어야 한다 + +## 4. 실행 계획 적기 + +계획은 길 필요 없다. + +이 프로젝트에서는 보통 아래 정도면 충분하다. + +1. 기준 파일과 현재 연결 구조 확인 +2. `8081` worktree 기준으로만 수정 +3. 필요한 데이터 동기화 +4. 화면/기능 수정 +5. 회귀 검증 +6. 이슈 코멘트와 체크포인트 기록 + +핵심은: + +- 수정 전에 먼저 구조를 파악하고 +- 범위를 정하고 +- 검증까지 포함해서 끝내는 것 + +## 5. 실행 전 동기화 + +이 프로젝트는 코드만 맞아도 안 되고, 데이터도 맞아야 한다. + +그래서 실행 전에 동기화가 필요할 수 있다. + +무슨 뜻이냐면: + +- `8081`에서 기능 확인을 하더라도 +- 데이터가 `8080`과 다르면 검증 결과를 신뢰하면 안 된다 + +자주 쓰는 규칙: + +- 조직도 / 멤버 / 자리배치 검증 전 + - `./scripts/sync_prod_db_to_dev.sh minimal` +- 분석 화면까지 공개용 기준으로 맞춰야 할 때 + - `./scripts/sync_prod_db_to_dev.sh full` + +또 코드 동기화도 중요하다. + +- `8081`은 메인 workspace에서 직접 띄우지 않는다 +- 먼저 `./scripts/prepare_dev_worktree.sh` +- 그 다음 `.dev-worktree-8081`에서 실행 + +즉 이 프로젝트의 동기화는 두 종류다. + +- DB 동기화 +- 코드/worktree 동기화 + +## 6. 실제 실행 + +이 단계가 코드를 고치는 단계다. + +하지만 여기서도 규칙이 있다. + +- `8081`에서 먼저 작업 +- 기준 파일이 아닌 곳은 건드리지 않기 +- 임시 우회 연결을 만들었으면 반드시 기록 남기기 +- 연결 구조가 난잡해지면 바로 이슈에 `코드 정리 필요`를 남기기 + +특히 이 프로젝트는 아래가 자주 꼬인다. + +- `frontend/public` +- `legacy/static` +- `incoming-files` +- 정적 HTML +- iframe 연결 +- 버전 쿼리스트링 + +그래서 실행 중 계속 확인해야 한다. + +- 지금 내가 고친 파일이 실제 서빙 파일이 맞는가? +- 지금 수정이 `8081` 전용인가, `8080` 공통인가? +- 이 연결은 임시인가, 기준 구조인가? + +## 7. 가드레일 테스트 + +가드레일 테스트는 쉬운 말로: + +- "이 수정 때문에 같이 망가지면 안 되는 것들을 확인하는 테스트" + +즉 핵심 기능만 보는 게 아니라, 같이 깨지기 쉬운 주변 기능까지 확인하는 것이다. + +이 프로젝트에서 가드레일 테스트 예시: + +- `8081` 디자인 수정 후 + - `8080`은 그대로인지 확인 +- 조직현황 수정 후 + - 조직도 iframe, 모달, 리스트뷰, seat preview 확인 +- 자리배치 수정 후 + - 관리자 저장 + - 비관리자 조회 + - 조직도 상세 seat preview +- 분석 화면 수정 후 + - 기간 필터 + - 프로젝트/팀 전환 + - 빈 데이터 상태 + - 스타일 깨짐 여부 + +가드레일 테스트는 "다 테스트한다"가 아니다. + +이번 수정 때문에 같이 깨질 가능성이 높은 것만 빠르게 확인하는 것이다. + +## 8. 기록 남기기 + +작업은 기록까지 남겨야 끝난다. + +남겨야 하는 것: + +- 무엇을 바꿨는지 +- 무엇을 기준으로 했는지 +- 무엇을 검증했는지 +- 무엇이 아직 안 끝났는지 +- 다음에 어디서 이어야 하는지 + +남길 위치: + +- Gitea 이슈 코멘트 +- 체크포인트 문서 +- 필요하면 룰북/프로토콜 문서 + +## 이 프로젝트용 한 줄 버전 + +앞으로는 아래 순서로 생각하면 된다. + +1. 기준 진실부터 정한다 +2. 이슈에 작업 목적과 완료조건을 적는다 +3. 실행 전에 코드/DB 동기화를 맞춘다 +4. `8081`에서만 수정한다 +5. 같이 깨지면 안 되는 것까지 확인한다 +6. 결과를 기록한다 + +## 시작할 때 바로 쓰는 짧은 템플릿 + +작업 시작 전에 아래 6줄만 적어도 된다. + +- SSOT: + - 코드 기준: + - 데이터 기준: + - 디자인 기준: +- 이슈: +- 완료조건: +- 계획: +- 필요한 동기화: +- 가드레일 테스트: + +예시: + +- SSOT: + - 코드 기준: `/home/hyunho/projects/mh-dashboard-organization/.dev-worktree-8081` + - 데이터 기준: `8080` DB를 sync한 `8081` + - 디자인 기준: `MH 통합 대시보드_260320.html` +- 이슈: `#16` +- 완료조건: `8081`에서 사업관리대장 메인이 원본 톤으로 열리고 `8080`은 안 바뀜 +- 계획: 연결 확인 → worktree 수정 → 검증 → 이슈 기록 +- 필요한 동기화: `minimal` +- 가드레일 테스트: `8080 유지`, `조직현황 탭`, `프로젝트/팀 탭` diff --git a/docs/WORK_RULEBOOK.md b/docs/WORK_RULEBOOK.md index c367728..6895ad9 100644 --- a/docs/WORK_RULEBOOK.md +++ b/docs/WORK_RULEBOOK.md @@ -30,6 +30,11 @@ - "오늘 첫 작업"의 시작점은 코드 수정이 아니라 상태 확인이다. - 이 절차를 건너뛰고 바로 수정 작업에 들어가는 것은 금지한다. +추가 기준: + +- 실제 작업 순서는 [WORK_EXECUTION_FLOW.md](/home/hyunho/projects/mh-dashboard-organization/docs/WORK_EXECUTION_FLOW.md) 를 따른다. +- 특히 `SSOT → 이슈 → 완료조건 → 계획 → 동기화 → 실행 → 가드레일 테스트 → 기록` 순서를 기본 운영 흐름으로 본다. + ## Rule 1. Completed Feature Protection 완료 판정된 작업물의 기능과 코드는 함부로 건드리지 않는다. @@ -217,8 +222,9 @@ mock, fallback, hotfix, 임시 우회 로직은 허용할 수 있다. 세부 규칙: -- `8081`은 항상 `/tmp/mh-dashboard-organization-dev-worktree`에서 띄운다. +- `8081`은 항상 `.dev-worktree-8081`에서 띄운다. - 기동 전 `./scripts/prepare_dev_worktree.sh`를 먼저 실행한다. +- 재부팅 후 빠른 기동은 `./scripts/start_8081.sh` 또는 `./scripts/start_local_dashboards.sh`를 사용한다. - `.env`와 로컬 전용 디자인 자산은 준비 스크립트가 복사한 것을 기준으로 사용한다. - 기동 후 `docker inspect mh-dashboard-organization-dev-backend-1`로 마운트 소스를 확인한다. diff --git a/scripts/prepare_dev_worktree.sh b/scripts/prepare_dev_worktree.sh index 1add650..904c209 100755 --- a/scripts/prepare_dev_worktree.sh +++ b/scripts/prepare_dev_worktree.sh @@ -3,8 +3,9 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -DEV_DIR="${DEV_DIR:-/tmp/mh-dashboard-organization-dev-worktree}" +DEV_DIR="${DEV_DIR:-${ROOT_DIR}/.dev-worktree-8081}" TARGET_REF="${1:-HEAD}" +FORCE_RECREATE="${FORCE_RECREATE:-0}" copy_optional_path() { local rel_path="$1" @@ -22,14 +23,18 @@ if [[ "${DEV_DIR}" == "${ROOT_DIR}" ]]; then exit 1 fi -echo "[1/6] Removing previous dev workspace at ${DEV_DIR}" -rm -rf "${DEV_DIR}" +if [[ -d "${DEV_DIR}/.git" && "${FORCE_RECREATE}" != "1" ]]; then + echo "[1/6] Reusing existing dev workspace at ${DEV_DIR}" +else + echo "[1/6] Removing previous dev workspace at ${DEV_DIR}" + rm -rf "${DEV_DIR}" -echo "[2/6] Cloning production workspace into isolated dev workspace" -git clone --no-hardlinks "${ROOT_DIR}" "${DEV_DIR}" >/dev/null + echo "[2/6] Cloning production workspace into isolated dev workspace" + git clone --no-hardlinks "${ROOT_DIR}" "${DEV_DIR}" >/dev/null -echo "[3/6] Checking out detached ref ${TARGET_REF}" -git -C "${DEV_DIR}" checkout --detach "${TARGET_REF}" >/dev/null + echo "[3/6] Checking out detached ref ${TARGET_REF}" + git -C "${DEV_DIR}" checkout --detach "${TARGET_REF}" >/dev/null +fi echo "[4/6] Copying local runtime env when available" copy_optional_path ".env" @@ -45,3 +50,7 @@ echo "[6/6] Dev worktree ready" echo "Path: ${DEV_DIR}" echo "Use this to start 8081 from the isolated workspace:" echo " cd ${DEV_DIR} && docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d --build" +if [[ "${FORCE_RECREATE}" != "1" ]]; then + echo "To fully rebuild the dev workspace, run:" + echo " FORCE_RECREATE=1 ./scripts/prepare_dev_worktree.sh" +fi diff --git a/scripts/start_8081.sh b/scripts/start_8081.sh new file mode 100755 index 0000000..2fdfa4f --- /dev/null +++ b/scripts/start_8081.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DEV_DIR="${DEV_DIR:-${ROOT_DIR}/.dev-worktree-8081}" + +"${ROOT_DIR}/scripts/prepare_dev_worktree.sh" + +cd "${DEV_DIR}" +docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d --build + +echo "8081 started from ${DEV_DIR}" +echo "Verify mounts with:" +echo " docker inspect mh-dashboard-organization-dev-backend-1 --format '{{range .Mounts}}{{println .Source \"->\" .Destination}}{{end}}'" diff --git a/scripts/start_local_dashboards.sh b/scripts/start_local_dashboards.sh new file mode 100755 index 0000000..5465c3b --- /dev/null +++ b/scripts/start_local_dashboards.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +cd "${ROOT_DIR}" +docker compose up -d +"${ROOT_DIR}/scripts/start_8081.sh" + +echo "8080: http://localhost:8080" +echo "8081: http://localhost:8081"