- 발행일
용어 하나를 96개 파일 667곳에서 바꿨다 — 그리고 일부러 안 바꾼 세 경계
용어 하나를 96개 파일 667곳에서 바꿨다
화면에서 쓰는 이름이 "분류체계"에서 "개념체계"로 바뀌었습니다. 도메인 용어를 정리하면서 나온 결정이에요.
코드에서는 원래부터 ConceptScheme이었습니다. SKOS의 skos:ConceptScheme을 그대로 받은 이름인데, 화면 문구만 "분류체계"로 번역돼 있었어요. 그러니까 이번 변경은 화면을 코드 쪽으로 맞추는 방향이었습니다.
치환 결과는 이랬습니다.
96 files changed, 667 insertions(+), 667 deletions(-)
추가와 삭제가 정확히 같습니다. 줄 수가 하나도 안 변한 순수 문자열 교체라는 뜻이에요. 이런 작업은 손이 많이 갈 뿐 어렵지 않습니다. 어려운 건 어디서 멈출지 정하는 쪽이었어요.
어디까지 바꿀 것인가
| 방법 | 장점 | 포기하는 것 | 판단 |
|---|---|---|---|
| ① 화면에 보이는 문구만 | 사용자가 보는 것이 즉시 맞음. 배포로 끝남 | 코드와 화면이 다른 말을 하게 됨 | 채택 |
② ①+ 코드 식별자(Scheme → ConceptScheme 계열 정리) | 읽는 사람이 한 단어만 알면 됨 | 이미 코드는 Concept* 계열이라 바꿀 게 별로 없고, 오히려 scheme 지역 변수 수백 개를 건드리는 무의미한 diff | 기각 |
| ③ ②+ URL·파일명 | 주소까지 일관 | /std-data/scheme/가 외부에 나가 있고 e2e·문서·북마크가 물려 있음. 얻는 것 대비 위험이 큼 | 기각 |
| ④ ③+ DB 데이터 값 | 완전히 한 단어 | 코드 배포로 못 함. 환경마다 사람이 따로 해야 함 | 별건으로 분리 |
①로 정하고 나니 나머지가 자동으로 정해졌습니다. 바꾸는 범위를 정하는 일과 안 바꾸는 이유를 적어두는 일은 같은 일이더군요.
경계 1 — 코드 식별자와 URL은 그대로
치환은 전부 사람이 읽는 문자열에서만 일어났습니다.
- """분류체계(Scheme) 폼 - name 필드 전역 중복 체크"""
- name_duplicate_error_message = _('이미 존재하는 분류체계입니다.')
+ """개념체계(Scheme) 폼 - name 필드 전역 중복 체크"""
+ name_duplicate_error_message = _('이미 존재하는 개념체계입니다.')
...
- parent = forms.ModelChoiceField(..., label='상위 분류체계', required=False)
+ parent = forms.ModelChoiceField(..., label='상위 개념체계', required=False)
label, help_text, 오류 메시지, docstring. 필드 이름 parent도 그대로고 클래스 이름도 그대로입니다. 파일명 변경은 0건이에요 — scheme_list.html.j2, scheme.py, /std-data/scheme/가 전부 살아 있습니다.
여기에 대가가 있습니다. 새로 온 사람이 "개념체계 화면이 어디 있지" 하고 grep 개념체계를 하면 템플릿 문구만 나오고 모델도 URL도 안 나옵니다. 코드를 찾으려면 scheme으로 다시 찾아야 해요. 한 단어로 검색이 안 되는 상태를 만든 겁니다.
그래도 ①로 간 이유는, 이런 용어는 또 바뀌기 때문입니다. 화면 문구는 기획 판단에 따라 몇 달 만에도 바뀌는데 그때마다 모델명과 URL을 따라 바꾸면 그게 더 큰 부채가 됩니다. 코드 식별자를 표준(skos:ConceptScheme)에 붙여 두면 화면 용어가 흔들려도 안 흔들려요.
경계 2 — "분류"는 "분류체계"가 아니다
기계적 치환에서 제일 위험한 자리였습니다. 이 화면에는 "분류 칩"이라는 다른 기능이 있어요. 데이터·시스템/서비스·주체로 나누는 필터인데, 이건 theme이고 scheme이 아닙니다.
분류체계 → 개념체계 ✅
분류 칩 → 분류 칩 ✅ (그대로)
"분류"만 잡는 치환을 돌렸다면 "분류 칩"이 "개념 칩"이 됐을 겁니다. 완전한 단어 분류체계만 대상으로 잡아 피했는데, 이건 운이 좋았다기보다 치환 대상을 짧게 잡을수록 위험하다는 걸 알고 시작한 덕입니다.
경계 3 — DB 데이터 값은 코드 배포로 안 바뀐다
가장 많이 남은 쪽입니다.
- 인스턴스 228건의 명칭·설명
themeTaxonomy라벨- 공지 1건
- 설문 문항
전부 DB 안에 든 사용자 데이터라 코드에 없습니다. 마이그레이션으로 UPDATE를 돌릴 수는 있지만 안 했어요. 이건 데이터의 내용이지 코드가 만든 문자열이 아니고, 어떤 행이 그 뜻으로 쓴 "분류체계"인지는 사람이 봐야 압니다. 설문 문항 안의 "분류체계"가 이 시스템의 그 개념을 가리키는지, 응답자가 아는 일반 명사인지는 문맥 문제예요.
그래서 관리 화면에서 사람이 바꾸는 별건으로 분리하고, 개발·스테이징·운영 DB가 각각 필요하다는 것을 커밋 메시지에 남겼습니다. 코드는 배포로 한 번에 퍼지지만 데이터는 안 그러니까요.
667곳 중 258곳이 문서였다
바꾼 줄을 파일 종류별로 세보고 조금 놀랐습니다.
docs 258곳 (16개 파일) ← 가장 많다
py 140곳 (25개 파일)
templates 121곳 (30개 파일)
e2e 78곳 (15개 파일)
js 52곳 ( 9개 파일)
기타 18곳
화면 문구를 바꾸는 작업인데 문서가 코드보다 많았습니다. docs/metadata-ui-development.md 한 파일에서만 148곳이 바뀌었어요. 이 프로젝트는 화면 결정의 근거를 문서에 길게 남기는 편이라, 용어가 코드보다 문서에 훨씬 촘촘하게 박혀 있었습니다.
여기서 잠깐 멈췄습니다. 문서는 "지금 이렇다"이기도 하지만 "그때 그렇게 불렀다"이기도 하거든요. 2026-03에 쓴 결정 기록의 "분류체계"를 8월에 바꾸면, 그 글이 쓰인 시점에는 없던 단어가 그 글에 들어갑니다.
바꾸기로 했습니다. 이 문서들은 지금 화면을 설명하는 안내서지 회고록이 아니어서요. 여기에 "그때는 분류체계였다"를 남겨야 할 문서가 있다면 그건 별도의 이력 문서지, 현행 규칙을 적은 문서가 아닙니다. 대신 날짜가 붙은 결정 항목(🔄 2026-08-05 같은)은 그대로 두어, 언제 정한 규칙인지는 살아 있게 했습니다.
검증
python manage.py check통과 — 문자열만 바뀐 변경이라 시스템 검사가 첫 관문입니다.std_data서버 테스트 675건 통과. 문구를 단언하는 테스트가 있으면 여기서 빨개집니다.- Playwright 150건 통과. e2e 스펙 자체에도 "분류체계"가 셀렉터·기대 문구로 들어 있어서 스펙 파일 15개가 이번 치환 대상에 포함됐습니다.
- ESLint 회귀 없음 — JS 안의 문구도 대상이었습니다.
e2e/qa/menu-list.json50줄이 바뀐 것을 별도로 확인. 메뉴 136종 QA 스윕이 이 파일을 읽어 메뉴 이름으로 화면을 도는 구조라, 여기가 안 바뀌면 스윕이 옛 이름을 찾다 실패합니다.
남은 것 · 한계
- DB 데이터 값 228건은 아직 그대로입니다. 커밋 메시지에 적어 뒀을 뿐이고, 스테이징·운영에서 누가 언제 하는지는 안 정했습니다. 화면 문구는 "개념체계"인데 그 안의 데이터 이름은 "분류체계"인 상태가 지금 배포돼 있어요. 이 글에서 제일 안 끝난 부분입니다.
- 코드와 화면이 다른 말을 합니다. 의도한 선택이지만, 그 대가를 코드 안에 적어두지는 않았습니다.
ConceptScheme옆에 "화면에서는 개념체계라고 부른다" 한 줄이 있어야 하는데 없어요. - 667이라는 숫자는 치환된 줄 수지 검토한 줄 수가 아닙니다. 문맥을 한 줄씩 다 읽지는 않았어요. "분류체계" 완전 일치만 잡았으니 오탐 가능성은 낮다고 보지만, 낮다고 보는 것과 확인한 것은 다릅니다.
- 제 글 제목도 옛 용어입니다. 이 블로그에 분류체계 화면에서 목록 단계를 없앴다가 있는데, 지금 그 화면은 개념체계라고 불립니다. URL은 유산이라 안 바꾸는 게 맞다고 보지만, 그러면 읽는 사람이 두 이름을 이어 붙일 방법이 없습니다. 이 문단이 지금은 그 역할을 대신하고 있어요.
- 다음에 용어가 또 바뀌면 같은 작업을 처음부터 다시 합니다. 화면 문구를 한 곳에 모으는 구조(용어 사전 조회)가 일부 화면에는 이미 있는데, 전면 적용은 안 했습니다.