DB 시드 소스를 코드 트리 안에 두지 않는다
0회 조회
DB 시드 소스를 코드 트리 안에 두지 않는다
콘텐츠 (마크다운·JSON·CSV 등) 를 시드 로 DB 에 넣는 프로젝트에서, 그 시드 파일을 어디에 둘 것인가 는 의외로 큰 결정입니다. 직관적으로 "그 콘텐츠를 쓰는 앱 폴더 안 (frontend/myapp/content/)" 에 두기 쉽지만, 장기적으로는 모노레포 루트 에 두는 편이 거의 항상 옳습니다.
1. 앱 폴더 안에 두면 생기는 사고
| 사고 | 원인 |
|---|---|
| 시드 walker 가 v1 폴더와 v2 폴더 둘 다 스캔 → 중복 insert | 마이그 source 와 SSOT 가 같은 폴더에 공존 |
| 앱 빌드 시 시드 파일이 image 에 포함 → 컨테이너 크기 증가 | 앱 코드와 한 디렉터리에 묶임 |
| 시드 파일을 수정하면 앱이 재빌드 | Next/Vite 가 content 폴더를 watch |
| docker-compose 가 마운트 경로 를 앱 디렉터리로 잡음 → 운영자 직관 어긋남 | 콘텐츠 ≠ 코드 라는 분리가 흐림 |
2. 모노레포 루트 배치의 이점
my-monorepo/
├── notes/ ← 시드 SSOT (모노레포 루트)
│ ├── backend/
│ │ ├── 01-...ko.md
│ │ └── 01-...en.md
│ └── frontend/...
├── courses/ ← 시드 SSOT
│ └── <series>/...
├── frontend/
│ └── admin/ ← 앱 (시더가 ../../notes 를 walk)
└── docker-compose.yml (../../notes:/notes:ro 마운트)
루트에 두면:
- 어느 앱 폴더와도 기계적으로 분리 — 콘텐츠 ≠ 코드 가 폴더 자체로 명시됨
- docker 마운트 경로가 콘텐츠 =
/notes· 코드 =/app으로 깔끔 - 시드 수정 시 앱 재빌드 트리거 0
- v1 → v2 마이그 후 v1 폴더를 삭제 해도 앱 코드는 흠 없음
3. 마이그 후 dead path 청소 — 한 번에 끝낸다
이 패턴을 도입할 때 가장 흔한 사고는 v1 폴더를 남겨 두는 것. "혹시 모르니 보관" 으로 두면:
- 시더가 v1 + v2 둘 다 walk → 중복 insert 또는 누락
- 신규 작업자가 "어느 게 SSOT 인지" 못 잡음
docker-compose.yml의 v1 마운트가 stale dead mount 로 남음
옳은 처리는 한 번에 끝내는 것 — git rm -rf + 마운트 라인 삭제 + helper 함수 삭제 + 5 개 문서 정합. 이 다섯 자리를 한 커밋으로 묶지 않으면 한 자리만 남아도 다음 작업자가 헷갈립니다.
4. 적용 전 / 적용 후
| 측면 | 앱 폴더 안 | 모노레포 루트 |
|---|---|---|
| 콘텐츠와 코드 경계 | 흐림 | 폴더 자체로 분리 |
| 시드 수정 시 빌드 | 트리거 됨 | 트리거 안 됨 |
| 컨테이너 이미지 크기 | 시드 포함 | 시드 미포함 (런타임 마운트) |
| v1 → v2 마이그 후 정리 | 남기기 쉬움 | 한 번에 git rm |
| 신규 작업자 SSOT 인식 | "어느 게?" | 루트가 명시 |
5. 자신의 프로젝트에 적용하려면
-
app/content/또는src/seed/안에 콘텐츠 가 있다면 모노레포 루트로 이동. - 시더가
process.cwd() + ../../를 base 로 walk 하도록 수정. - docker-compose 의 마운트를
../../notes:/notes:ro형태로 통일. - v1 → v2 마이그가 끝났다면 v1 폴더 + 마운트 + helper 를 한 커밋 으로 삭제.
- README · 폴더 구조 문서에 "콘텐츠 SSOT 는 루트
/notes/courses" 명시.
코드와 콘텐츠는 변경 주기가 다른 자산. 변경 주기가 다른 것은 폴더부터 다르게 두는 게 운영 비용이 가장 낮습니다.