콘티온 ContiOn TIL 9
곡 데이터에 분류·속성·중복 감지·콘티 유형 제약을 붙이는 하루였다. 그 과정에서 판단이 필요했던 것들을 모았다.
곡 번호만 보면 분류를 알 수 있었다
곡마다 번호가 있고, 번호 구간마다 분류(목차의 큰 갈래)가 정해져 있다. 이 분류를 칸에 따로 적어 두면 번호를 고칠 때마다 같이 고쳐야 하고, 처음에도 수백 곡을 한 번씩 채워야 한다(백필 — 이미 있는 행을 뒤늦게 한꺼번에 채우기). 번호에서 분류가 그대로 나오니, 저장하지 않고 그때그때 계산되는 칸(생성 컬럼 — 다른 칸 값으로 자동 계산되는 칸)으로 뒀다.
반면 곡마다 사람이 정해 줘야 하는 속성은 계산할 규칙이 없으니 일반 칸에 저장했다. 규칙이 있으면 계산, 없으면 저장. 이 갈림이 칸 종류를 정한다.
분류 필터 드롭다운도 같은 결이다. 코드에 목록을 박지 않고 실제 있는 분류만 뽑아 채우면 분류가 늘어도 따라온다. 다만 그대로 뽑으면 가나다순이 되어 목차 순서가 깨지므로, 각 분류의 첫 곡 번호 순으로 세웠다. 데이터에서 뽑더라도 쓰는 사람이 익숙한 순서는 따로 챙겨야 한다.
규칙에 걸린 요청은 막되, 무엇을 빼야 하는지 알려 준다
곡 속성 중 일부는 서로 묶여 있다. 하위 속성을 켜면 상위 속성도 켜져야 한다. 또 특정 속성을 가진 곡만 담을 수 있는 콘티 유형도 만들었다. 둘 다 화면에서 막고 서버에서 다시 검사했다. 화면만 막으면 안내일 뿐 방어가 아니라는 건 앞선 TIL 2에서 정리한 그대로다.
여기서 더 정한 건 막는 방식이다. 이미 만든 콘티를 그 유형으로 바꾸려는데 조건에 안 맞는 곡이 들어 있으면, “안 됨”만 돌려주지 않고 걸린 곡 목록을 보여 주며 이것들을 먼저 빼라고 안내하기로 했다. 거부만 하면 쓰는 사람은 콘티를 한 곡씩 뒤져야 한다. 막을 때는 무엇을 고치면 통과하는지까지 주는 게 막는 쪽의 몫이다.
비슷한 곡은 막지 않고 물었다
같은 곡이 제목이나 가사가 조금 달라 따로 등록되는 일이 있었다. 띄어쓰기·문장부호를 걷어낸 제목끼리 얼마나 닮았는지 재고(편집거리 — 한 글자열을 다른 글자열로 바꾸려면 몇 글자를 고쳐야 하는지로 재는 유사도), 가사는 앞부분만 비교해 닮은 곡을 찾게 했다. 이 앱의 DB인 SQLite에는 유사도를 재는 기능이 없어 서버 쪽에서 계산했고, 전체 가사를 다 읽으면 무거우니 앞부분만 잘라 받았다.
닮은 곡이 나와도 등록을 막지는 않고 “비슷한 곡이 있다, 그래도 등록할까”를 묻는 데서 멈추기로 했다. 확실히 맞힐 수 없는 판정은 곡을 아는 사람에게 맡기고(앞선 TIL 7), 막는 대신 묻는다(앞선 TIL 4)는 앞의 판단을 그대로 따랐다. 제목이 비슷해도 정말 다른 곡일 수 있어서, 여기서도 기계는 후보를 보여 주는 데까지만 한다.
형식을 조금 넓혔더니 계획한 기능 하나가 필요 없어졌다
콘티에서 곡의 절(가사 덩어리)을 골라 순서를 정하는 “배치”는 절 번호를 줄지어 적은 목록으로 저장돼 있었다. 여기에 절 사이에 안내 문구를 끼우는 기능을 넣으려고, 목록의 한 칸에 절 번호뿐 아니라 텍스트도 들어갈 수 있게 넓혔다.
그러고 나니 따로 만들려고 계획해 둔 “그 콘티에서만 가사 고치기”가 저절로 됐다. 원래 절을 빼고 그 자리에 고친 가사를 텍스트로 넣으면 그 콘티에서만 바뀐다. 별도 칸과 별도 화면을 계획했는데 필요 없어졌다.
기능을 하나 더하기 전에 “지금 형식을 조금 넓히면 되나”를 먼저 보면 덜 만든다.
요약
- 규칙으로 계산되는 값은 저장하지 않고 계산되는 칸으로(백필·동기화 없음), 곡마다 사람이 정하는 값은 일반 칸에 저장한다.
- 드롭다운 옵션은 데이터에서 뽑되, 쓰는 사람이 익숙한 원래 순서로 세운다.
- 규칙에 걸린 요청은 화면과 서버에서 막고(앞선 TIL 2), 막을 때는 무엇을 빼야 통과하는지 목록으로 알려 준다.
- 닮은 곡 판정은 확실하지 않으니 막지 않고 묻는다(앞선 TIL 4·7). 기계는 후보만 보여 준다.
- 기능을 더하기 전에 형식을 넓히면 되는지 본다. 하나를 일반화하면 계획한 기능이 흡수되기도 한다.