본문으로 건너뛰기
Hooney
English

엔진과 모듈 · 제품에서 사용 중

kuery

필터 조건을 하나의 공통 형식으로 정의해, 화면의 필터 칩, 주소(URL), 앱 안의 걸러 내기, 데이터베이스 조회가 모두 같은 뜻으로 해석하게 한 필터 엔진입니다.

1필터 칩, 주소, 앱 안 걸러 내기, 데이터베이스 조회가 함께 쓰는 필터 형식

기간
2026.07 ~ 현재
소속
Firstage
역할
설계와 구현 (1인)
grids Storybook의 CRM 예제에 들어간 kuery 필터 빌더. 텍스트 조건 'status:churned (mrr:>=800 OR plan:Free)'가 상태 칩과, MRR 800 이상 또는 Free 요금제를 묶은 OR 그룹으로 풀려 있고, 머리글에 1만 명 중 1,189명이 표시된다.

핵심 가치

필터 칩에 보이는 조건 그대로 기록을 걸러 내고, 선택 때문에 작업 범위가 넓어지지 않습니다.

성과

  • 2026년 9월부터 Journey 공유 공간 갤러리 필터에 사용
  • 데이터베이스 조회는 미리 등록한 항목으로만 만들어 안전하게 유지
  • 'status:churned' 같은 글자 조건과 저장 형식(JSON)을 한 정의로 읽고 씀

기술 스택

  • TypeScript
  • React
  • Drizzle ORM

배경

목록 화면은 필터 UI, 서버의 WHERE 절, 새로고침해도 남는 URL을 저마다 따로 만들기 쉽습니다. 그러면 칩이 보여 주는 조건과 실제 쿼리, 공유한 링크가 여는 결과가 서로 어긋납니다. 필터의 의미를 한 곳에서 정의하고, 걸러 낸 기록에 실행할 작업의 범위까지 같은 방식으로 다루려고 만든 엔진입니다.

결정과 구현

  • 필터는 최상위 AND 아래에 OR 묶음을 두는 정규형(CNF) IR로 제한했습니다. 부정(not)은 모델에 넣지 않았고, 외부에서 들어온 조건에 들어 있으면 거부합니다.
  • 필드 타입마다 값 코덱과 허용 연산자를 정의하고, 같은 레지스트리로 텍스트 문법과 JSON을 읽고 씁니다.
  • Drizzle로 SQL 조건을 만드는 컴파일러는 IR에 없는 연산을 더하지 않고, 등록된 필드만 허용합니다. 필터 IR은 처음부터 신뢰할 수 없는 입력으로 다룹니다.
  • 선택은 필터 안이 아니라 필터 옆에서 컴파일합니다. 명시한 목록은 IN, 조건에 맞는 전체에서 일부를 뺀 선택은 NOT IN, 빈 목록은 항상 거짓인 조건이 되므로 선택 때문에 작업 범위가 넓어지지 않습니다.
  • 타이핑이 멈추거나 포커스가 빠지면 입력 중인 텍스트가 초안이 되고, 적용을 눌러야 호스트가 실행할 조건이 바뀝니다. 위젯 문구는 한국어, 영어, 일본어로 제공합니다.

현재 상태

2026년 9월부터 Journey 앱의 공유 공간 갤러리가 장소, 날짜, 내 사진만 보기 필터를 kuery-core 조건으로 만들어 사진 목록에 적용합니다. 커서로 페이지를 나누는 개인 갤러리는 기존처럼 서비스 요청에서 필터링합니다. 주소와 브라우저 기록 동기화가 다음 작업이고, grids와 함께 Dashboard에 연결하는 단계는 아직 진행하지 않았습니다.