DOCS/journey/plans/260313_nas_본체_go_companyx_sync_계획.md
2026-03-13 18:48:51 +09:00

9.0 KiB

tags
tags
infra
nas
companyx
sync
go
plans

260313 NAS 본체 Go Company X Sync 계획

상태: 완료 (2026-03-13 Go CLI 빌드, 테스트, 대표 폴더 dry-run/실동기화 검증 완료)

상위 원칙

관련 문서

문제 정의

  • 이미 닫힌 문제는 외부 NAS -> 내부 저장소 기본 동기화 구조가 성립하는가이다.
  • 이번에 푸는 문제는 NAS 본체에서 이 구조를 Go 코드로 재현 가능하게 실행하고, 이후 운영 기준을 그 구현 위에 올릴 수 있는가다.
  • 즉 새 코드는 외부 NAS 직접 사용 제거, 내부 저장소 단일 기준 유지, NAS 본체 직접 실행, 재개 가능한 동기화를 실제 실행 단위로 고정해야 한다.

이번 계획에서 고정하는 범위

  • 실행 주체는 NAS 본체다.
  • 구현 언어는 Go로 고정한다.
  • 초기 실행 형태는 1회 실행 CLI로 고정한다.
  • 대상 원본 루트는 외부 NAS /6.Company X다.
  • 대상 내부 저장 루트는 NAS 본체의 Company X 저장 경로다.
  • 외부 접근 방식은 DSM File Station API pull로 유지한다.
  • 기본 증분 기준은 수정시각 + 파일 크기로 유지한다.
  • 외부 삭제는 내부 저장소에 자동 전파하지 않는다.
  • 실패 기록, 상태 기록, 요약 기록은 파일로 남긴다.

이번 계획에서 아직 고정하지 않는 범위

  • 최종 cron 주기
  • 상주 daemon 채택 여부
  • Search API 채택 여부
  • 인증서 정상화 방식
  • 최종 로그 포맷의 세부 필드 추가 확장

구현 목표

1. Go 실행 엔트리를 만든다

  • infra/scripts 저장소에 NAS 본체에서 직접 실행할 Go 진입점을 추가한다.
  • 단일 바이너리 실행을 기준으로 하고, 초기 단계는 CLI 1회 실행 모델로 둔다.
  • 이후 cron에서 재사용할 수 있게 입력 인자와 종료 코드를 단순하게 유지한다.
  • 초기 바이너리 이름은 companyx-sync로 고정한다.
  • 초기 소스 루트는 infra/scripts/go/companyx-sync로 고정한다.

2. workspace-config를 읽는 구조를 고정한다

  • 비민감값은 runtime.env, 민감값은 secrets.env에서 읽는다.
  • 코드 안에 운영 기본값과 인증값을 하드코딩하지 않는다.
  • 대상 루트, 로그 루트, 상태 파일 경로도 설정에서 주입 가능한 구조로 둔다.
  • 필수 키가 없으면 즉시 실패하고, 누락 키 이름을 로그에 남긴다.

3. DSM API pull 기본 경로를 재현한다

  • 로그인
  • 폴더 목록 조회
  • 파일 다운로드
  • 다운로드 후 내부 저장소 반영
  • 이 네 가지를 먼저 Go에서 재현한다.

4. 증분 판정과 기록 구조를 넣는다

  • 파일 존재 여부
  • 파일 크기
  • 수정시각
  • 이 세 가지로 기본 다운로드 여부를 판단한다.
  • 실패 로그, 상태 파일, 실행 요약 파일을 남긴다.
  • 로그 루트 기본값은 Company X 동기화 로그가 이미 쌓이는 경로 계열을 따른다.
  • 초기 기본 경로는 /workspace/.sync-logs로 고정한다.
  • 상태 파일 기본 경로는 /workspace/.sync-logs/companyx_sync_state.json로 고정한다.
  • 실패 로그 기본 경로는 /workspace/.sync-logs/companyx_sync_failures_YYYYMMDD.jsonl 패턴으로 고정한다.
  • 요약 파일 기본 경로는 /workspace/.sync-logs/companyx_sync_summary_YYYYMMDD_HHMMSS.json 패턴으로 고정한다.
  • 삭제 후보 로그 기본 경로는 /workspace/.sync-logs/companyx_delete_candidates_YYYYMMDD.jsonl 패턴으로 고정한다.

5. 삭제 비전파 원칙을 유지한다

  • 외부에 없는 파일을 바로 지우지 않는다.
  • 삭제 후보 로그만 남긴다.
  • 자동 삭제는 이번 계획 범위에 넣지 않는다.

6. 재개 가능성을 우선 확보한다

  • 전체 트리 중 어디까지 스캔했는지 상태 파일에 남긴다.
  • 마지막으로 실제 다운로드한 경로도 남긴다.
  • 실패 후 다음 실행이 완전 초기화 없이 이어질 수 있게 최소 상태를 유지한다.

초기 구조 결정

  • 모듈은 하나로 시작하고, 패키지 분리는 구현 중복이 생길 때만 늘린다.
  • 1차 구조는 config, dsm, sync, main 정도의 최소 패키지로 제한한다.
  • Python 구현과 기능 parity를 무리하게 한 번에 맞추지 않고, 다운로드 -> 증분 -> 상태기록 순으로 단계적으로 맞춘다.
  • 첫 구현에서는 daemon, queue, webhook, Search API 최적화는 넣지 않는다.

실행 순서

  1. infra/scripts에 Go 진입점과 모듈 구조를 추가한다.
  2. workspace-config를 읽는 설정 로더를 만든다.
  3. DSM 로그인, 목록 조회, 다운로드를 재현한다.
  4. /6.Company X의 대표 파일 1건 다운로드까지 먼저 맞춘다.
  5. 대표 하위 폴더 1개 동기화까지 확장한다.
  6. 상태 파일, 실패 로그, 요약 파일을 붙인다.
  7. 전체 트리 1회 실행 가능한 수준까지 올린다.
  8. 이후 cron/주기 계획은 별도 적용 문서나 worklog에서 닫는다.

1차 구현 순서 고정

  1. --remote-root, --local-root, --log-root, --dry-run 플래그를 지원하는 CLI를 만든다.
  2. 설정 파일 없이도 플래그 우선, 설정 파일 fallback 순서로 해석되게 한다.
  3. 대표 파일 1건 다운로드를 먼저 검증한다.
  4. 대표 하위 폴더 1개 동기화를 검증한다.
  5. 같은 입력 재실행 시 skipped가 증가하는지 확인한다.
  6. 실패 강제 상황에서 실패 로그와 상태 파일이 남는지 확인한다.

체크리스트

  • Go 바이너리가 NAS 본체에서 직접 실행된다.
  • 바이너리 이름과 소스 루트가 문서 기준과 일치한다.
  • 외부 DSM API 로그인과 파일 다운로드가 재현된다.
  • 내부 저장소 기준 경로로 파일이 실제 반영된다.
  • 수정시각 + 파일 크기 기준 증분 판정이 동작한다.
  • 실패 로그가 남는다.
  • 상태 파일이 남는다.
  • 요약 파일이 남는다.
  • 삭제는 자동 전파되지 않는다.

검증 기준

  • 대표 파일 1건 다운로드 성공
  • 대표 하위 폴더 1개 동기화 성공
  • 같은 입력 재실행 시 불필요한 재다운로드가 줄어듦
  • 실패 상황에서 실패 로그와 상태 파일이 남음
  • 실행 종료 후 요약 파일에서 downloaded, skipped, failed를 확인할 수 있음

완료 조건

  • NAS 본체에서 Go 기반 동기화 CLI가 직접 돈다.
  • 외부 DSM API pull, 내부 저장소 반영, 기본 증분 판정이 한 흐름으로 연결된다.
  • 상태 파일, 실패 로그, 요약 파일이 실제 산출물로 확인된다.
  • 구현 결과만으로 다음 단계 cron 적용 문서를 쓸 수 있을 만큼 실행 단위와 산출물이 고정된다.
  • 이 주제는 더 이상 Go로 옮길 수 있는가가 아니라 운영 주기와 배포 방식을 어떻게 고정할까 문제만 남는다.

2026-03-13 적용 상태

  • Go 모듈 infra/scripts/go/companyx-sync를 추가했다.
  • CLI 진입점 cmd/companyx-sync를 만들고 workspace-config 기반 설정 로더를 붙였다.
  • DSM API login -> list -> download -> 상태/실패/요약 기록 흐름을 Go로 재현했다.
  • go test ./...는 통과했다.
  • 대표 사진 폴더 /6.Company X/7. 사진/220308_X코스_5기 발표 사진 대상 --dry-run 검증 결과 downloaded=20, failed=0, files_seen=20이었다.
  • 같은 대표 폴더 실동기화 결과도 downloaded=20, failed=0, files_seen=20, downloaded_bytes=6505335였다.
  • 같은 입력 재실행 결과는 downloaded=0, skipped=20, failed=0이었다.
  • 실동기화 후 로컬 저장 경로에는 파일 20개가 실제 생성됐다.
  • 요약 파일과 상태 파일도 실제로 생성돼, 이 계획 문서는 완료로 닫는다.

한 줄 결론

  • 목표는 NAS 본체에서 Go 코드로 외부 NAS /6.Company X -> 내부 저장소 동기화의 기본 실행 단위를 재현하고, 이후 운영 자동화의 기준 구현을 만드는 것이다.