diff --git a/docs/DEV_PROD_DB_PROTOCOL.md b/docs/DEV_PROD_DB_PROTOCOL.md index 5e84cc4..ce5ca3e 100644 --- a/docs/DEV_PROD_DB_PROTOCOL.md +++ b/docs/DEV_PROD_DB_PROTOCOL.md @@ -11,20 +11,21 @@ ### 코드 경로 - 공개용 `8080`: `/home/hyunho/projects/mh-dashboard-organization` -- 작업용 `8081`: `/home/hyunho/projects/mh-dashboard-organization` +- 작업용 `8081`: `/tmp/mh-dashboard-organization-dev-worktree` ### 작업용 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`에서 띄운다 ### DB 볼륨 - 공개용 `8080`: `mh-dashboard-organization_postgres_data` - 작업용 `8081`: `mh-dashboard-organization-dev_postgres_data` -즉 현재는 코드 workspace는 같아도 compose project 와 DB volume 이 분리된 상태다. +즉 현재는 `8080` 과 `8081` 이 코드 workspace 와 DB volume 모두 분리된 상태로 운영한다. ## 정본 기준 @@ -172,11 +173,30 @@ 사용 방법: ```bash -docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d +./scripts/prepare_dev_worktree.sh +cd /tmp/mh-dashboard-organization-dev-worktree +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 ``` +`prepare_dev_worktree.sh`가 같이 처리하는 것: + +- 메인 workspace를 `/tmp/mh-dashboard-organization-dev-worktree`로 복제 +- `.env` 복사 +- 로컬 전용 디자인 참고 자산 복사 + - `incoming-files/sample style.css` + - `incoming-files/260320.html` + - `incoming-files/사업관리대장/` + - `incoming-files/1.png` + - `incoming-files/seat/center_chair_people_map(2).html` + +중요: + +- `8081`은 현재 메인 workspace를 직접 마운트하면 안 된다 +- 컨테이너가 `/home/hyunho/projects/mh-dashboard-organization/...`를 물고 있으면 분리 상태가 깨진 것이다 +- 정상 상태는 `docker inspect mh-dashboard-organization-dev-backend-1` 기준 마운트 소스가 `/tmp/mh-dashboard-organization-dev-worktree/...`로 나와야 한다 + 규칙: - `minimal` diff --git a/docs/REGRESSION_CHECKLIST.md b/docs/REGRESSION_CHECKLIST.md index 7d431f9..d3eb8ef 100644 --- a/docs/REGRESSION_CHECKLIST.md +++ b/docs/REGRESSION_CHECKLIST.md @@ -25,7 +25,8 @@ - `8081` 작업용 접속 확인 - `8080` 공개용 접속 확인 - `docker compose ps`에서 `backend`, `frontend`, `proxy`, `db`가 정상인지 확인 -- `8081`은 기본적으로 `docker compose -p mh-dashboard-organization-dev --env-file .env -f docker-compose.8081.yml up -d` 로 기동 +- `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/...`인지 확인 ### 2. 데이터 동기화 범위 결정 diff --git a/docs/WORK_RULEBOOK.md b/docs/WORK_RULEBOOK.md index 0afba6f..c367728 100644 --- a/docs/WORK_RULEBOOK.md +++ b/docs/WORK_RULEBOOK.md @@ -193,6 +193,41 @@ mock, fallback, hotfix, 임시 우회 로직은 허용할 수 있다. - 작업 중간 상태는 워크트리에 남겨둘 수 있으며, 임의로 잘라서 자주 커밋하지 않는다. - 커밋이 필요하다고 판단되면 먼저 상태와 이유를 공유하고, 지시를 받은 뒤 진행한다. +## Rule 12. Promote 8081 To 8080 By Reviewed File Diff Only + +`8081` 작업용에서 검증된 변경을 `8080` 공개용으로 가져갈 때는 전체 workspace 를 통째로 덮지 않는다. + +세부 규칙: + +- 먼저 `8081` 작업용의 변경 파일 목록과 diff 를 확인한다. +- 공개용에 필요한 파일만 선택해서 메인 workspace 로 반영한다. +- 반영 후에는 메인 workspace 기준으로 최소 회귀 검증을 다시 수행한다. +- `8081` DB 기준으로만 맞는 수정인지, `8080` 기준 데이터에서도 맞는지 다시 확인한다. +- 검증이 끝나기 전에는 공개용 완료로 판단하지 않는다. + +금지: + +- `8081` 작업 디렉터리를 통째로 복사해서 `8080`에 덮어쓰기 +- diff 확인 없이 일괄 반영 +- `8081`에서 됐으니 `8080`도 같을 것이라고 가정하기 + +## Rule 13. 8081 Must Start From The Isolated Worktree + +`8081` 작업용은 포트만 다른 복제 서버가 아니라, 코드 소스까지 분리된 전용 worktree여야 한다. + +세부 규칙: + +- `8081`은 항상 `/tmp/mh-dashboard-organization-dev-worktree`에서 띄운다. +- 기동 전 `./scripts/prepare_dev_worktree.sh`를 먼저 실행한다. +- `.env`와 로컬 전용 디자인 자산은 준비 스크립트가 복사한 것을 기준으로 사용한다. +- 기동 후 `docker inspect mh-dashboard-organization-dev-backend-1`로 마운트 소스를 확인한다. + +금지: + +- 현재 메인 workspace를 직접 마운트한 상태로 `8081`을 띄우기 +- `8080`과 `8081`이 같은 `frontend/public`, `legacy/static`, `incoming-files`를 동시에 보게 두기 +- `8081`에서 보이던 디자인을 `8080` 공통 소스에 바로 덮어쓰기 + ## Daily Start Checklist 매일 첫 작업 시작 전 체크: diff --git a/scripts/prepare_dev_worktree.sh b/scripts/prepare_dev_worktree.sh new file mode 100755 index 0000000..1add650 --- /dev/null +++ b/scripts/prepare_dev_worktree.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +DEV_DIR="${DEV_DIR:-/tmp/mh-dashboard-organization-dev-worktree}" +TARGET_REF="${1:-HEAD}" + +copy_optional_path() { + local rel_path="$1" + local src="${ROOT_DIR}/${rel_path}" + local dst="${DEV_DIR}/${rel_path}" + if [[ ! -e "${src}" ]]; then + return 0 + fi + mkdir -p "$(dirname "${dst}")" + cp -a "${src}" "${dst}" +} + +if [[ "${DEV_DIR}" == "${ROOT_DIR}" ]]; then + echo "DEV_DIR must not be the same as the production workspace." >&2 + exit 1 +fi + +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 "[3/6] Checking out detached ref ${TARGET_REF}" +git -C "${DEV_DIR}" checkout --detach "${TARGET_REF}" >/dev/null + +echo "[4/6] Copying local runtime env when available" +copy_optional_path ".env" + +echo "[5/6] Copying local-only incoming design assets when available" +copy_optional_path "incoming-files/1.png" +copy_optional_path "incoming-files/260320.html" +copy_optional_path "incoming-files/sample style.css" +copy_optional_path "incoming-files/seat/center_chair_people_map(2).html" +copy_optional_path "incoming-files/사업관리대장" + +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" diff --git a/scripts/sync_prod_db_to_dev.sh b/scripts/sync_prod_db_to_dev.sh index cfa4d18..8618d20 100755 --- a/scripts/sync_prod_db_to_dev.sh +++ b/scripts/sync_prod_db_to_dev.sh @@ -4,9 +4,9 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PROD_DIR="${ROOT_DIR}" -DEV_DIR="${DEV_DIR:-${ROOT_DIR}}" +DEV_DIR="${DEV_DIR:-/tmp/mh-dashboard-organization-dev-worktree}" DEV_PROJECT_NAME="${DEV_PROJECT_NAME:-mh-dashboard-organization-dev}" -DEV_COMPOSE_FILE="${DEV_COMPOSE_FILE:-${ROOT_DIR}/docker-compose.8081.yml}" +DEV_COMPOSE_FILE="${DEV_COMPOSE_FILE:-${DEV_DIR}/docker-compose.8081.yml}" SCOPE="${1:-minimal}" if [[ ! -f "${PROD_DIR}/docker-compose.yml" ]]; then