화면에서는 두 건을 찾았는데 내려받은 결과에는 다른 자료가 섞이면 어느 쪽이 맞을까. 나는 내보내기 버튼보다 먼저 같은 조건이라는 말의 범위를 정하고 싶었다.
기존 보고서 제작기는 집계와 출력 범위를 설명했다. 이번에는 그 설명에서 더 들어가 정규화한 조건 하나로 페이지·내보내기·요약을 만드는 독립 합성 코드를 작성했다. 실제 회사 자료를 조회하지 않는다.
검색어보다 먼저 회사 범위를 정한다
새 모듈의 조회 조건은 company_id, status와 q다. 회사는 사용자의 임의 입력이 아니라 실제 서버라면 인증된 문맥에서 정해야 한다. 이 예제는 이미 읽어 온 합성 행을 받으며 마지막에도 회사 조건을 적용한다. 어떤 회사의 자료를 볼 수 있는지와 어떤 검색어로 좁힐지는 다른 결정이다. 검색 편의를 위해 권한 범위를 넓히지 않는다.
행에는 식별자, 시간 순서를 설명하는 합성 tick, 수량과 상태가 있다. 제목이나 고객 이름을 실제로 가져온 것이 아니다. 검색은 ID의 대소문자 구분 없는 부분 일치로 제한했다. 이 작은 규칙을 복잡한 전문 검색 기능으로 부르지 않고 어떤 조건을 모든 읽기 경로가 공유해야 하는지 시험하는 데 집중했다.
조건을 한 번 해석하고 같은 결과를 보게 했다
make_snapshot은 알려진 조회 키만 받아 기본 상태와 검색어를 정리한다. 정의하지 않은 키를 조용히 무시하지 않는다. 같은 입력이 화면에서는 다른 뜻이고 내보내기에서는 다른 뜻이 되는 일을 피하기 위해서다. 필요한 행을 고르고 정해진 순서로 복사해 불변 조회 결과를 만든다. 나머지 함수는 조건을 다시 해석하지 않고 이 결과를 읽는다.
page는 일부 행을, export_rows는 전체 선택 행을, summary는 같은 선택 행의 개수와 수량 합을 읽는다. 내보내기에 별도 필터 함수를 두지 않았다. 화면의 현재 한 페이지만 내보낼지 모든 조건 결과를 내보낼지도 기능의 약속이다. 이번 코드는 전체 조건 결과를 반환하며 실제 파일 생성이나 다운로드는 구현하지 않았다.
보여 주지 않을 열은 결과에서도 빼 둔다
원본에 추가 필드가 있더라도 반환 행은 ID·tick·수량·상태만 갖는다. 화면에서 감추기만 하고 내보내기에는 내부 메모가 나오는 구조를 피한 것이다. 독립 테스트는 합성 원본에 secret 필드를 넣어도 출력에 없는지 확인한다. 실제 민감한 자료를 테스트에 사용하지 않고도 허용 목록의 방향을 확인할 수 있다.
이 필드 선택이 모든 역할의 권한 정책을 완성한 것은 아니다. 회사별·사용자별로 어떤 필드를 볼 수 있는지 실제 서버에서 먼저 정하고 필요한 투영을 적용해야 한다. 현재 모듈은 신뢰할 호출자가 올바른 회사 범위를 넘긴다는 전제를 갖는다. 검색 함수가 있기 때문에 로그인과 API 권한도 구현됐다고 말하지 않는다.
두 페이지를 이어 붙여 내보내기와 비교했다
합성 자료에서 회사 A의 draft를 검색하면 두 행이 남고 수량 합은 9다. 페이지 크기를 1로 두고 첫 페이지와 다음 페이지를 연결하면 export_rows의 전체 결과와 정확히 같아야 한다. 같은 tick을 가진 행은 ID까지 함께 정렬해 순서가 흔들리지 않게 했다. 단순히 총 개수만 맞추는 대신 어떤 행이 포함됐는지 대조한다.
원본 배열이 바뀌어도 이미 만든 조회 결과는 변하지 않는다. 다만 이 코드는 데이터베이스에서 일관된 읽기를 얻는 기능은 아니다. 처음 전달받는 배열이 이미 서로 다른 시점의 자료라면 복사로 고칠 수 없다. 실제 저장소에서 어떤 읽기 경계를 가져와야 하는지는 별도로 구현해야 한다. 확인된 결과와 그 입력 전제도 함께 남겼다.
버튼 문구도 출력의 범위를 말해야 한다
현재 검색 결과 전체를 반환한다면 그 약속을 사용자에게 보여 주어야 한다. 한 페이지만 내보내는 기능이라면 다른 말과 확인이 필요하다. 선택 행만 보내는 기능을 더할 때도 공통 조회 범위의 안에서 어떤 선택을 적용하는지 정해야 한다. 같은 조건이라는 말 뒤에 페이지·선택·권한이 몰래 달라지지 않도록 점검한다.
공유 패키지는 동일 조건의 모든 페이지와 내보내기, 필드 제한, 빈 결과와 잘못된 조건을 검사한다. 실제 파일 내려받기나 실브라우저 검수는 아니다. 나는 검색창과 다운로드 버튼을 따로 만드는 것보다 두 결과가 같은 질문의 답인지 확인하는 방법을 노하우로 공개하고 싶었다. 코드와 고정 합성 실행 기록을 함께 볼 수 있다.