발행일

심사가 끝난 신청서를 보며 등록하는 화면을 만들고 끝까지 돌려 봤다 — QA 소견 12건 중 새 화면 자체 문제는 셋이었다

심사가 끝난 신청서를 보며 등록하는 화면을 만들고 끝까지 돌려 봤다

이 시스템에서 표준데이터를 새로 올리는 길은 신청 → 심사 → 등록입니다. 신청자가 데이터 엘리먼트·프레임·메시지를 신청서에 적고, 일곱 단계 심사를 거친 뒤, 등록관리자가 실제 데이터(원장)로 등록해요.

이 글은 그 마지막 단계에 화면 하나를 만든 이야기(f9f111b5, 9/15)와, 그 화면을 포함해 흐름 전체를 실제로 끝까지 돌려 본 뒤 고친 이야기(7883fb08·3cadd522, 9/15~9/30)입니다.

왜 이 화면이 필요했나

배경은 팀원이 정한 두 가지입니다.

  • 9월 2일, 신청서를 원장과 분리했습니다. 8월 말까지는 신청 중에 작성분을 초안이나 인스턴스로 두었다가 승인 때 원장으로 올리는 구조였어요(8월에 쓴 승인될 때까지 아무것도 만들지 않기가 그 시기 이야기입니다). 9월 2일부터는 신청서가 값 스냅샷 한 덩어리로만 저장되고, 심사가 끝나도 원장에는 아무것도 자동으로 생기지 않습니다.
  • 9월 9일, 등록관리자(Registrar)가 완료 신청서를 보고 손으로 등록하도록 권한을 연결했습니다. 정책 문서는 "신청 심사와 데이터 등록은 별도 작업"이라고 적었고, 신청서와 원장의 연결이나 등록 완료 여부는 추적하지 않는다고 범위를 그었어요.

그러면 등록관리자가 하는 일은 이렇게 됩니다. 심사 완료 신청서를 열고, 신청서 팝업을 새 창으로 띄우고, 다른 창에서 표준데이터 관리 화면을 열어 클래스를 고르고, 칸마다 팝업을 보며 옮겨 적어요. 신청서에 항목이 다섯 개면 이걸 다섯 번 하고, 값 집합처럼 하위 데이터가 여러 건이면 그만큼 더 합니다. 그리고 어느 항목까지 등록했는지는 어디에도 남지 않아요.

9월 15일에 이 왕복을 화면 하나로 모았습니다. 자동 생성은 여전히 하지 않고 권한도 그대로입니다. 다만 9월 9일 문서가 범위 밖에 둔 "등록 여부 추적"은 이번에 들였어요. 어느 항목을 등록했는지 기록하는 것이고, 문서의 그 문장도 새 절이 대신한다고 고쳐 적었습니다.

화면이 하는 일

목록은 배포 단계까지 끝난 신청만 보여 주고 N건 중 M건 등록을 붙입니다. 상세에서는 신청 항목마다 등록 상태와 [등록]·[수정]이 있어요.

입력 모달은 관리자 인스턴스 폼을 그대로 씁니다. 필수 검증, 참조 연결, OID 자동 부여가 관리 화면과 같아야 해서 폼을 새로 만들지 않았어요. 대신 칸마다 아래에 신청자가 적은 값을 회색 상자로 보여 주고, 옮기는 방법을 칸 종류마다 나눴습니다.

  • 글자 칸은 [가져오기]로 옮깁니다. 여러 줄 값도 줄바꿈과 들여쓰기를 그대로 옮겨요.
  • 신청자가 기존 데이터를 골라 뒀으면 [선택], 아직 없는 이름을 적어 뒀으면 그 이름을 채운 [추가]로 새 데이터를 만듭니다.
  • 신청서가 받지 않는 칸(값 집합·상태·생성일 등)에는 관리자 입력 배지를 붙였습니다.

값을 처음부터 채워 넣지는 않았습니다. 모달이 열리면 폼은 비어 있고, 신청값은 옆에 보이기만 해요. 9월 29일에 [신청값 모두 가져오기]를 붙일 때도 빈 글자 칸만 채우고 이미 입력한 값은 덮어쓰지 않게 했습니다.

등록한 항목은 신청서에 묶어 둡니다. 기존 연결 표(RequestInstance)에 후속 등록 역할과 신청서 스냅샷의 항목 id(item_id)를 더해서, [등록]으로 만든 인스턴스를 그 항목에 연결해요. 같은 항목을 두 번 등록하려 하면 409를 돌려줍니다.

if (
    instance is None
    and item
    and RequestInstance.objects.filter(
        request=req, role=ROLE_REGISTERED, item_id=item["id"]
    ).exists()
):
    return JsonResponse({"error": _("이미 등록한 항목입니다.")}, status=409)

기존 역할(작성·참조)을 재사용하지 않은 데는 이유가 있습니다. 9월 2일 이후 현행 신청서는 이 연결을 만들지 않지만, 복구용으로 남겨 둔 옛 심사 전이 코드와 정리 명령(purge_std_data_requests)이 작성·참조 연결을 옮기거나 지웁니다. 여기에 얹으면 등록 기록이 심사 코드의 부작용으로 바뀌거나 사라질 수 있어요.

하위 데이터 여러 건은 표로 받고, 한 줄이라도 틀리면 아무것도 저장하지 않습니다. 값 집합처럼 부모를 되가리키는 칸이 있는 클래스는 [여러 건 추가]로 표를 열고, 엑셀에서 복사한 여러 줄을 붙여 넣을 수 있어요. 저장할 때는 모든 행을 먼저 검증하고, 틀린 행이 있으면 그 칸만 표시한 채 400을 돌려줍니다. 다 통과하면 생성과 부모 연결을 한 트랜잭션에서 만듭니다. 한 번에 200건까지입니다.

테스트는 이 화면 몫으로 17건(진행률, 칸별 신청값, 중복 409, 한 줄 오류 시 전체 미저장, 배포 전·없는 항목 404 등)을 붙였고, 기존 등록관리자·신청서·관리자 인스턴스·심사 테스트와 합쳐 137건이 통과했습니다.

끝까지 돌려 봤다

단위 테스트는 화면 하나를 봅니다. 그런데 이 화면은 일곱 단계 심사 뒤에 있어서, 앞 단계가 남긴 데이터와 문구가 그대로 들어옵니다. 그래서 같은 날 흐름 e2e를 하나 더 만들었어요(7883fb08).

  • 역할별 계정 넷(신청자·데이터 스튜어드·변경통제위원회·등록관리자)으로 신청 한 건을 일곱 단계 심사까지 실제로 저장하며 진행합니다. dev는 역할 엄격 모드라 신청자와 심사자가 같은 계정이면 처리할 수 없거든요.
  • 배포 직후 공개 검색이 0건인 것을 먼저 확인하고, 신청서 기반 등록으로 다섯 건과 값 집합 붙여넣기 두 건을 넣은 뒤, 로그인하지 않은 상태에서 검색·상세에 공개되는 것까지 봅니다.
  • 단계별 캡처 29장과 보고서 HTML을 남깁니다.

9월 29일에 이 흐름을 다시 돌린 v2 보고서에는 통과 결과와 함께 QA 소견 12건이 붙었습니다. 높음·중간·낮음으로 등급을 매겼어요.

12건 중 새 화면 자체의 문제는 셋이었다

소견을 화면별로 나눠 보면 이렇습니다.

어디소견
새 화면 안신청 코드(JSON·ASN.1)를 손으로 복사해 붙여야 함 · 목록 칸이 붙어 읽힘 · OID 칸 안내가 "승인되면 부여"라고 함(이미 승인 뒤인데)
앞 화면(신청·심사)신청 상세 안내가 옛 절차를 말함 · 확인 화면 칩이 "작성 중" · 신청자의 제출이 이력에 "승인"으로 찍힘 · 심사 결정 화면에서 신청 내용을 못 봄 · 화면 이름이 역할마다 다름 · 여백과 0건 쪽 번호
뒤(등록 이후)신청자가 등록 여부를 알 길이 없음
원인 미상등록 뒤 메시지·프레임·엘리먼트가 서로 이어지지 않음
여러 화면항목 목록에 한글 표제가 없음

등급이 높음인 건은 둘이었습니다. 하나는 원인을 아직 모르는 데이터 연결 문제(아래 한계)이고, 다른 하나는 신청 상세의 안내가 "관리자가 배포단계 심사 상세의 신청서 팝업을 참고해 표준데이터 관리 화면에서 직접 등록합니다"라는 9월 9일 절차를 그대로 말하고 있던 것이에요. 바로 위 배너는 새 화면을 안내하는데, 한 화면 안에서 두 절차가 같이 보였습니다. 화면을 새로 만들면서 그 화면을 가리키던 옛 문장은 찾지 않았던 거예요.

"제출이 승인으로 찍힌다"도 비슷합니다. 심사 절차에서 기록 단계를 나가는 동작의 이름이 승인이라 이력에 그대로 찍혔는데, 신청자는 [제출]을 눌렀을 뿐입니다. DB의 동작 이름은 그대로 두고 표시만 기록 단계에서 나가는 승인을 제출로 바꿨어요. 이 공용 표시 함수를 OID 신청 이력도 쓰니 같이 바뀝니다.

새 화면 안의 코드 소견은 구조를 조금 바꿨습니다. 9월 29일 판에서는 신청 코드를 창 맨 아래 코드 상자와 [코드 복사]로만 보여 주고 "데이터 표현 [추가]에 붙여 넣으라"고 안내했어요. 항목이 다섯이면 복사·창 열기·붙여넣기를 다섯 번 합니다. 데이터 표현은 코드 한 건이니 신청 코드는 곧 새 데이터 표현 후보라고 보고, 코드를 데이터 표현 칸의 신청값 목록으로 옮겨 [이 코드로 추가] → 정의 구문 [가져오기]로 이었습니다. 신청자가 기존 데이터 표현을 골라 뒀다면 바로 위 [선택]과 나란히 놓여 어느 쪽을 쓸지 한 칸에서 정해요.

12건 중 10건을 9월 30일에 고쳐 3cadd522로 합쳤습니다(작업 브랜치 커밋 13개, 파일 87개). 고친 뒤 이용안내와 작성 예시 캡처도 다시 찍었어요. 바뀐 문구가 캡처 안에 옛 모습으로 남아 있었거든요.

그 뒤

이 절은 10월 중순에 그 뒤 일까지 묶어 덧붙였습니다. 남긴 두 건 중 하나와, 첫 커밋에서 한계로 적어 둔 것 몇 가지는 10월 13일에 팀원이 이어서 풀었습니다(675bfaee·45c8512e).

  • 첫 커밋은 모달 위에서 [추가]로 만든 하위 데이터가, 바깥 [등록]을 취소해도 남았습니다. 팀원이 중첩·일괄 입력을 임시 보관했다가 최상위에서 한 트랜잭션으로 저장·취소하게 바꿨어요.
  • "신청자가 등록 여부를 알 길이 없다"는 화면 쪽(신청 상세의 N건 중 M건·항목별 등록됨 배지)만 9월 30일에 고치고, 메일은 완료 기준(전부 등록 시 자동 / 첫 건 / 관리자가 [등록 완료])부터 정해야 해서 남겼습니다. 9월 30일 문서에 세 기준의 장단점을 비교해 [등록 완료] 버튼을 추천안으로 적어 뒀고, 팀원이 그 방식으로 완료 확정과 완료 메일·재발송 이력을 붙였습니다.
  • 여러 건 저장에서 OID 부여는 트랜잭션 밖이라 실패하면 경고만 돌려줬는데, OID 발급 실패 안내와 재시도도 그때 들어갔습니다.

10월 15일에는 등록 상세의 버튼 배치와 팝업의 중복 [닫기]를 정리했습니다(4467864a). 메뉴 항목은 9월 16일에 사이드바에서 잠시 뺐다가 9월 29일에 같은 자리로 되살렸는데, 뺀 사유는 커밋에 적지 않았습니다.

한계

  • "등록 뒤 메시지·프레임·엘리먼트가 서로 이어지지 않는다"는 아직 원인을 모릅니다. v2 흐름이 구조 칸(프레임·메시지 필드)을 비워 둔 탓도 있어서, 그 칸을 채운 흐름으로 다시 돌려 원인부터 가려야 해요. 보고서에 다음 회차 1순위로 적어 두었습니다.
  • 항목당 등록 연결 한 건은 첫 커밋에서 코드(409)로만 막았습니다. 10월 13일 팀원 작업에서 중복 요청은 작업 번호와 revision 검사로 더 막았지만, (request, item_id) DB 제약은 지금도 없어서 셸에서 직접 넣으면 여러 건이 생길 수 있어요. 이 제약은 문서에 미결로 남아 있습니다.
  • 모달에서 기존 데이터를 고치는 기능은 넣지 않았습니다. 표준·상태처럼 여러 곳이 쓰는 공용 데이터를 한 항목 등록 중에 고치면 사용처 전체가 바뀌어서, 하위 데이터만 허용할지는 선임 확인 뒤 정하기로 했습니다.
  • 흐름 e2e는 dev DB에 신청 한 건과 인스턴스·OID·역할 계정을 남깁니다. 치우는 명령을 스펙 머리 주석에 두었지만, 돌릴 때마다 기억해야 하는 일입니다.

12건 중 9건은 단위 테스트가 볼 수 없는 새 화면 바깥에 있었습니다.