본문으로 건너뛰기

Pipeline Studio GUI 빌더

범위 (P3a 빌더 코어 + P3b 배포·실행·히스토리): 화면에서 노드를 드래그해 적재 파이프라인 그래프를 작성하고 드래프트 저장/로드 → 배포(리비전) → 실행 → 실시간 노드 상태·버전/실행 히스토리까지 수행합니다. 연결은 데이터 타입(포트) 호환성으로 가드되고, 실행 실패 시 노드별 에러 메시지가 표시됩니다. 커넥터 CRUD·스텝 라이브러리·메타소스 바인딩·이름변경/삭제는 P3c입니다. REST API로 동일 파이프라인을 코드로 조립·배포·실행하려면 Pipeline Studio API 가이드를 참고하세요.

GUI 빌더는 Pipeline Studio API가 다루는 동일한 {nodes, edges} 그래프를 화면에서 직접 그릴 수 있게 합니다. 작성한 그래프는 편집용 드래프트(Draft) 로 저장되며, 드래프트를 배포해 불변 리비전(Revision)으로 동결하는 단계는 P3b에서 추가됩니다.

1. Pipeline Studio 진입

좌측 사이드바에서 데이터 엔지니어링 > 파이프라인 스튜디오(/pipeline-studio)를 엽니다. 목록 화면에는 현재 워크스페이스에 등록된 파이프라인이 표시됩니다.

2. 파이프라인 생성

  1. 목록 화면 우측 상단의 새 파이프라인 버튼을 클릭합니다.
  2. 다이얼로그에서 파이프라인 이름(필요 시 설명)을 입력하고 생성을 누릅니다.
  3. 빈 드래프트가 자동 생성되며, 곧바로 빌더 화면(/pipeline-studio/<id>)으로 이동합니다.

3. 빌더 레이아웃

빌더 화면은 세 영역으로 구성됩니다.

영역위치역할
팔레트(Palette)좌측추가할 수 있는 노드 타입 목록. 드래그해서 캔버스에 떨어뜨립니다
캔버스(Canvas)가운데노드·엣지를 배치·연결하는 그래프 편집 영역(미니맵·줌 컨트롤 포함)
우측 패널(Right Panel)우측선택한 노드/엣지의 설정 폼. 노드 선택 시 설정 탭, 엣지 선택 시 조건 편집기

상단 툴바에는 저장 버튼과(드래프트가 변경되면 활성화) 검증 오류 표시줄이 있습니다.

사용 가능한 노드 타입

팔레트에는 활성 노드 8종이 표시됩니다. (shell/python은 코드 샌드박스(P2) 단계이므로 비활성 상태로 표시되며 드래그할 수 없습니다.)

  • 소스: s3_op (S3/SeaweedFS pull), db_source (DB/Federation SELECT — 아래 §3.1)
  • 변환(빌트인): builtin.parsebuiltin.chunkbuiltin.embed (이 순서를 지켜야 합니다)
  • 적재(싱크): builtin.vector (Weaviate), builtin.graph (Arango)
  • 통합: http_api커스텀 전처리 — 내 서비스 호출. 외부 HTTP 서비스(AIM/EAI 등)를 호출해 전처리하는 일급(featured) 노드입니다. 커스텀 코드 실행이 필요할 때 shell/python 대신 이 노드를 사용합니다.
  • 유지보수: retention (멀티스토어 보존)

3.1 DB 소스 노드 (db_source, #2134)

DB 연결 페이지에 등록된 federation 커넥터(Oracle/PostgreSQL/MySQL 등 Trino 카탈로그)에서 SELECT 결과를 파이프라인으로 적재합니다.

설정설명
데이터 소스(커넥터)DB 연결 페이지에 등록된 커넥터를 선택 (등록은 DB 연결 페이지에서)
SELECT 쿼리SQL 에디터(전체화면 토글 지원). 단일 SELECT/WITH 문만 허용 — 아래 제약 참고
max_rows행 상한 (기본 10,000 / 최대 100,000). 초과분은 절단되고 truncated 플래그가 표시됩니다

출력은 records(행 dict 배열)·columns·row_count 로, python/shell 변환 노드나 store 싱크로 연결합니다. (builtin.parse 는 파일 입력 전용이라 연결이 차단됩니다 — 포트 가드.)

보안
  • 실행은 서버측(gend-api)에서 Trino 로 위임되며 SELECT-only 가드를 거칩니다.
  • public security level 데이터 소스만 지원합니다 — 파이프라인 실행은 사용자 컨텍스트 없이 돌기 때문에, row-filter/컬럼 마스킹이 적용될 수 있는 비-public 소스는 ABAC 우회가 되어 거부됩니다(403). 비-public 소스의 사용자-컨텍스트 enforced 읽기는 후속 과제입니다.

SQL 제약 (서버측 강제)

파이프라인 실행은 사용자 컨텍스트 없이 돌기 때문에, 여기 적는 SQL 이 사실상 서버가 볼 수 있는 전부입니다. 다음은 422/403 으로 거부됩니다 (#2706).

거부되는 것응답
DML/DDL — 주석으로 가려도 동일/* x */ INSERT INTO t …, -- c 다음 줄의 DELETE422
여러 문장SELECT 1; DROP TABLE t422
CTE 본문의 변경WITH c AS (…) DELETE FROM t422
시스템 카탈로그·스키마system.runtime.queries, information_schema.tables, pg_catalog.*422
선택한 커넥터 밖 카탈로그커넥터가 sales 인데 FROM iceberg.silver.t403

마지막 항목이 중요합니다 — 승인된 것은 선택한 커넥터이므로, 세 부분 이름 (카탈로그.스키마.테이블)으로 다른 카탈로그를 참조할 수 없습니다. 커넥터 안의 테이블은 public.orders 처럼 두 부분으로 쓰거나 커넥터 이름을 붙여 sales.public.orders 로 쓰면 됩니다. 큰따옴표로 감싼 형태 ("iceberg"."silver"."t")도 동일하게 막힙니다.

커넥터 이름을 pg_ 로 시작하게 지으면 세 부분 이름이 시스템 스키마 규칙에 걸려 거부됩니다. 두 부분 이름으로 쓰거나 커넥터 이름을 바꾸십시오.

점이 두 번 들어간 표현은 위치와 무관하게 검사합니다. 예를 들어 ROW 타입 필드를 SELECT f(a.b.c) FROM t 처럼 세 단계로 파고들면, 이것이 테이블 참조가 아니어도 a 를 카탈로그로 보고 403 을 냅니다. 검사 범위를 좁히면 우회 경로가 생기기 때문에 막는 쪽으로 실패하도록 두었습니다.

이 경우 403 메시지가 문제의 표현(a.b.c)을 그대로 알려주므로, 별칭을 쓰거나 단계를 줄여 다시 실행하십시오.

4. 노드 추가 (드래그)

좌측 팔레트에서 원하는 노드를 캔버스로 드래그 앤 드롭하면 노드가 추가됩니다. 노드는 드롭한 위치에 배치되며, 좌표는 드래프트에 함께 저장되어 다시 열어도 동일한 배치가 유지됩니다.

5. 노드 연결

노드 우측의 출력 핸들에서 다른 노드 좌측의 입력 핸들로 드래그하면 엣지(연결선)가 생성됩니다.

  • 그래프는 비순환(acyclic) 이어야 합니다(순환 연결은 저장 시 차단).
  • 빌트인 변환 노드는 builtin.parsebuiltin.chunkbuiltin.embed 순서를 지켜야 합니다(역방향 연결은 검증 오류).

6. 노드 설정

캔버스에서 노드를 클릭하면 우측 패널에 타입별 설정 폼이 표시됩니다. 주요 예시:

  • builtin.parse (파싱 — 파일 바이트 → 텍스트+메타): processor(auto=외부 등록 시 우선 / local=내장 파서만) — 기본 필드. 고급 설정: page_range(PDF, 예 1-20·5, 1-based·미입력 시 전체), extract_images(PDF 임베디드 이미지 추출 on/off), ocr_lang(이미지 OCR, 기본 kor+eng), vlm_caption(이미지 VLM 캡션 on/off, 가용 provider 필요·실패 시 OCR only). 단계별 화면은 파싱 노드 QA 가이드 참고.
  • builtin.chunk: chunk_size(숫자), overlap(숫자), strategy(recursive / fixed_size)
  • http_api (커스텀 전처리 — 내 서비스 호출): 커넥터(필수), method, body_template(JSON, $input.<key> 치환), response_mapping(JSON, 예 {out: "$.a.b"})
  • retention: stores(vector/graph/table 다중 선택), retention_days, retention_column

http_api커넥터 선택지는 공유 커넥터 카탈로그에서 가져옵니다. 커넥터 등록은 파이프라인 스튜디오 목록 화면 → 커넥터 탭에서 합니다 (사이드바에 별도 "공유 리소스" 메뉴는 없습니다).

7. 엣지 조건 (분기)

엣지를 클릭하면 우측 패널에서 조건(condition) 을 편집할 수 있습니다. 조건이 비어 있으면 항상 통과(always)하고, 조건이 있으면 참일 때만 다음 노드로 진행합니다.

조건 편집은 두 가지 모드를 제공합니다.

  • 가이드(guided) 모드: 필드 · 비교 연산자 · 값을 선택해 조건을 조립합니다. 예) meta.doc_type == "invoice"
  • 고급(advanced) 모드: 조건식을 직접 입력합니다. 비교(==, !=, >, <), 논리(and, or, not), in만 허용되며 산술·함수 호출·인덱싱은 지원하지 않습니다. 클라이언트가 사전 검증하지만 최종 판정은 백엔드(422)가 수행합니다.

예시 조건식:

meta.doc_type == "invoice"
meta.pages > 10 and doc_type != ""

8. 드래프트 저장

상단 툴바의 저장 버튼을 누르면 현재 캔버스 그래프가 백엔드 드래프트로 직렬화되어 저장됩니다(PUT /api/v1/ps/pipelines/{id}/draft). 저장 전 클라이언트가 그래프를 사전 검증하며, 백엔드가 유효하지 않은 그래프를 받으면 422로 거절합니다. 다음에 같은 파이프라인을 다시 열면 저장된 그래프(노드 좌표 포함)가 그대로 복원됩니다.

9. 배포 · 롤백 · 실행 (P3b)

P3b부터 드래프트를 불변 리비전(Revision) 으로 동결해 배포하고, 배포된 리비전을 실행(run)하며, 실행 진행 상황을 캔버스에서 실시간으로 확인할 수 있습니다. 우측 패널에는 설정 / 버전 / 실행 탭이 추가됩니다.

9.1 배포 (드래프트 → 리비전 스냅샷)

상단 툴바의 배포 버튼을 누르면 현재 드래프트 그래프가 검증 후 불변 리비전으로 동결됩니다(POST /api/v1/ps/pipelines/{id}/deploy).

  • 배포 시점의 {nodes, edges} 그래프가 그대로 스냅샷되어 리비전 번호(rev N)로 보존됩니다.
  • 이후 드래프트를 더 편집해도 이미 배포된 리비전은 변하지 않습니다.
  • 배포에 성공하면 배포됨 (rev N) 토스트가 표시되고, 해당 리비전이 현재 리비전으로 설정됩니다.

9.2 롤백

버전 탭에서 과거 리비전 목록을 확인하고, 임의의 리비전으로 롤백 할 수 있습니다 (POST /api/v1/ps/pipelines/{id}/rollback).

  • rev N 항목의 롤백 버튼을 누르면 확인 후 해당 리비전이 현재 리비전으로 전환됩니다.
  • 현재 리비전에는 현재 배지가 표시됩니다.
  • 롤백은 새 리비전을 만들지 않고 현재 포인터만 과거 스냅샷으로 이동시킵니다.

9.3 실행 (Run Dialog)

배포된 리비전이 있으면 툴바의 실행 버튼이 활성화됩니다(배포 전에는 비활성 — 툴팁 배포 먼저). 실행을 누르면 실행 다이얼로그가 열립니다(POST /api/v1/ps/pipelines/{id}/runs).

  • file_path: 소스(s3_op) 노드에 uri 가 설정돼 있으면 생략 가능합니다. uri 가 없으면 s3:// 형식의 파일 경로가 필수 이며, 형식이 맞지 않으면 다이얼로그가 제출을 막습니다. 경로는 아래 §9.3.1 의 허용 버킷 안이어야 합니다.

9.3.1 S3 경로는 허용된 버킷만 (보안)

s3_op(읽기) · store(쓰기) · 폴더 감시(watch_json.uri_prefix) 가 다루는 S3 경로는 지정된 버킷 안으로 제한됩니다. 기본 허용 버킷은 gend-ingestion 입니다.

파이프라인 노드는 데이터 레이크(gend-iceberg)나 웨어하우스 같은 다른 버킷의 객체를 읽거나 쓸 수 없습니다. 이 경로는 SQL 엔진을 거치지 않으므로 카탈로그 접근제어·행 필터·컬럼 마스킹이 적용되지 않기 때문입니다.

막혔을 때 보이는 문구

시점메시지
저장/배포s3_op 노드 'src': 허용되지 않은 S3 버킷 'gend-iceberg' — 허용: gend-ingestion
폴더 감시 설정watch_json.uri_prefix: 허용되지 않은 S3 버킷 'gend-iceberg' — 허용: gend-ingestion
실행 중해당 노드가 실패하고 실행 탭에 같은 사유가 표시됩니다

대처 — 읽으려는 파일을 gend-ingestion 으로 옮기거나, 파일·CSV 업로드 화면으로 적재한 뒤 그 경로를 쓰십시오. 데이터 레이크의 테이블을 읽어야 한다면 s3_op 이 아니라 db_source 노드(Federation SELECT) 를 쓰는 것이 맞습니다 — 그쪽은 카탈로그 권한과 마스킹이 정상 적용됩니다.

관리자

허용 버킷은 환경변수 GEND_PS_S3_ALLOWED_BUCKETS(쉼표 구분)로 조정합니다. gend-api 와 Dagster 양쪽에 동일하게 설정해야 합니다 — 한쪽만 바꾸면 저장은 되는데 실행에서 실패합니다. 빈 문자열은 "전부 허용" 이 아니라 전면 거부 입니다.

  • 고급 옵션: filename, join_value(메타데이터 소스 바인딩 시에만 사용 — 미입력 시 filename), seed(JSON) 를 추가로 지정할 수 있습니다. seed 가 유효한 JSON 이 아니면 seed JSON 형식 오류 로 거절합니다.
  • 실행이 시작되면 실행을 시작했습니다 토스트가 뜨고, 실행 탭에 새 run 이 추가됩니다.

9.4 실시간 노드 상태

실행이 시작되면 캔버스의 각 노드가 진행 상황에 따라 색으로 갱신됩니다(run 의 node_status_json 폴링).

상태의미
주황(running)running해당 노드가 실행 중
초록(ok)ok노드가 성공적으로 완료
빨강(failed)failed노드가 실패 — 아래 9.6 참고

run 이 종료(succeeded / failed)되면 폴링이 멈춥니다.

9.5 버전 · 실행 히스토리 탭

우측 패널의 두 탭에서 이력을 확인합니다.

  • 버전 탭: 배포된 리비전 목록(rev N · 상태 · 배포 시각)과 현재 리비전 배지, 롤백 버튼.
  • 실행 탭: 최신순 run 목록과 상태 배지(성공 / 실패 / 실행중 / 대기중), 시작·종료 시각. run 을 클릭하면 캔버스가 해당 run 의 노드 상태로 재채색됩니다.

9.6 연결 가드레일 (포트 타입 호환)

엣지를 연결할 때 소스 노드의 출력 포트 타입과 대상 노드의 입력 포트 타입이 호환 되어야 합니다 (연결은 데이터 타입이 맞아야 합니다). 호환되지 않는 연결은 캔버스에서 차단됩니다.

예) s3_op(출력 file_bytes) 를 builtin.vector(입력 chunks) 에 직접 연결하면 중간 parse → chunk 단계가 빠져 chunks 가 누락되므로 차단됩니다. 올바른 경로는 s3_op → builtin.parse → builtin.chunk → builtin.vector 입니다. 입력 포트가 비어 있는 노드(예: retention)는 임의의 소스를 받을 수 있습니다.

9.7 실행 실패 시 노드별 에러 메시지

run 이 failed 로 끝나면 실행 탭에서 실패한 노드의 에러 메시지 가 인라인으로 표시됩니다. 이는 per-node 이벤트(GET /api/v1/ps/runs/{run_id}/nodes)에서 해석됩니다.

  • run 레벨 센티넬(__run__)은 실제 노드가 아니므로 제외하고, failed_node_id 에 해당하는 노드의 error_msg 를 우선 표기합니다.
  • 노드 이벤트를 가져오지 못해도 목록 자체는 깨지지 않습니다(best-effort).

P3c. 공유 리소스 관리 · 메타소스 · 이름변경/삭제

P3c는 화면에서 공유 리소스(커넥터·스텝) 를 등록하고, 파이프라인에 메타데이터 소스를 바인딩 하며, 파이프라인을 이름변경/삭제 할 수 있게 해 GUI 풀스위트를 완성합니다. 목록 페이지에는 커넥터 / 스텝 라이브러리 탭이 활성화되고, 빌더 우측 패널에는 메타소스 탭이 추가됩니다.

P3c.1 커넥터 등록 (http_api 노드용)

목록 페이지의 커넥터 탭에서 http_api 노드가 호출할 외부 서비스 커넥터를 등록합니다 (GET / POST /api/v1/ps/connectors).

  • + 커넥터 버튼으로 다이얼로그를 열고 다음을 입력합니다.
    • name(필수), base_url(필수): 커넥터 식별자와 호출 베이스 URL.
    • auth_vault_ref(선택): 인증 시크릿의 Vault 참조 경로.
    • egress_allow(선택, 쉼표 구분): 허용 egress 호스트 목록. 목록 행에는 egress N 으로 개수가 표시됩니다.
    • default_headers / request_template / response_mapping(선택, JSON): 잘못된 JSON 은 JSON 형식이 올바르지 않습니다 로 거절됩니다.
  • 생성에 성공하면 커넥터 생성됨 토스트가 뜨고 목록이 갱신됩니다.

이 화면은 목록 + 생성 만 제공합니다. 커넥터 편집·삭제는 백엔드 엔드포인트가 아직 없어 후속 단계입니다 (cascade 안전성 설계 필요).

P3c.2 스텝 라이브러리 등록 + 승인 상태

목록 페이지의 스텝 라이브러리 탭에서 재사용 가능한 스텝을 등록합니다 (GET / POST /api/v1/ps/steps).

  • + 스텝 다이얼로그에서 name(필수), type(필수), config(선택, JSON 객체), description(선택)을 입력합니다. config 가 JSON 객체가 아니면 config 는 JSON 객체여야 합니다 로 거절됩니다.
  • 각 스텝 행에는 승인 상태 배지 가 표시됩니다.
    • 승인됨(초록): 즉시 사용 가능한 스텝.
    • 대기중(주황): 승인 대기. shell / python 타입 스텝은 임의 코드 실행 위험이 있어 등록 시 자동으로 대기 상태가 됩니다.
  • 생성에 성공하면 스텝 생성됨 토스트가 뜨고 목록이 갱신됩니다.

P3c.3 메타데이터 소스 바인딩 (메타소스 탭)

빌더 우측 패널의 메타소스 탭에서 파이프라인에 메타데이터 소스를 바인딩합니다 (GET / POST /api/v1/ps/pipelines/{id}/metadata-source).

  • 바인딩 전에는 입력 폼이 표시됩니다. 미바인딩 상태는 오류가 아니라 정상 상태이므로 GET200 과 함께 null 을 반환합니다.
  • 입력 필드:
    • table_ref(필수): catalog.schema.table 형식의 대상 테이블.
    • join_key(필수): 문서와 메타데이터를 잇는 조인 키.
    • field_map(선택, JSON 객체): 필드 매핑. 객체가 아니면 field_map 는 JSON 객체여야 합니다 로 거절됩니다.
    • retention_column(선택): 보존 정책 기준 컬럼.
  • 바인딩에 성공하면 메타소스를 저장했습니다 토스트가 뜨고, 탭이 조회(view) 모드로 전환됩니다. 편집 버튼으로 다시 폼을 열어 갱신할 수 있습니다.

P3c.4 파이프라인 이름변경 / 삭제 (D7)

목록 페이지의 각 파이프라인 행 끝과 빌더 상단 툴바에 작업 메뉴(⋯)가 있습니다.

  • 이름변경: 다이얼로그에서 새 이름을 입력합니다(PATCH /api/v1/ps/pipelines/{id}). 워크스페이스 안에서 이름이 중복되면 409 로 거절됩니다.
  • 삭제: 확인 후 파이프라인을 삭제합니다(DELETE /api/v1/ps/pipelines/{id}).
    • 실행 이력이 없으면 하드 삭제됩니다(204). 드래프트·리비전·메타소스는 DB cascade 로 함께 정리됩니다.
    • 실행 이력이 있으면 삭제가 차단되어 409 가 반환됩니다(실행 원장 무결성 보존). 이때 UI 는 실행 이력이 있어 삭제할 수 없습니다. 대신 비활성화하시겠습니까? 로 안내하고, 비활성화(PATCH enabled=false)를 권장합니다. 비활성화는 삭제와 분리된 경로라 409 가 부수효과로 데이터를 변경하지 않습니다.
  • 빌더 툴바에서 삭제에 성공하면 목록(/pipeline-studio)으로 돌아갑니다.

스케줄 (cron 자동 실행) — #2050

파이프라인에 cron 스케줄을 설정하면 Dagster pipeline_studio_cron_sensor 가 주기적으로 평가해 자동으로 실행을 트리거합니다.

  • 설정: PATCH /api/v1/ps/pipelines/{id} body {"schedule_cron": "..."}.
    • 프리셋 키: 5m / 15m / 1h / 6h / 12h / daily(매일 02:00).
    • 5-field cron 표현식: 예 */10 2-4 * * 1-5. 형식이 프리셋도 5-field 도 아니면 422 로 거절됩니다.
    • 해제: 명시적 {"schedule_cron": null} 로 스케줄을 지웁니다(manual-only 복귀). 키를 생략한 PATCH 는 기존 값을 건드리지 않습니다.
  • 평가: 센서가 60초 간격으로 스케줄을 평가합니다. enabled=true 이고 배포된 리비전(current_revision_id)이 있는 파이프라인만 대상이며, 최신 run 이 running/queued 상태면 중복 트리거를 건너뜁니다.
  • 시간 기준: croniter 는 UTC 기준으로 평가합니다(KST 아님). 예컨대 daily 프리셋(02:00 UTC)은 KST 11:00 에 해당합니다.
  • 실행 전제: 스케줄 실행은 사용자 입력 없이(POST /runs body {}) 활성 리비전 그래프를 그대로 실행하므로, s3_op 등 입력 노드의 uri 가 그래프 config 에 구성되어 있어야 합니다.

10. 범위와 후속 단계

단계내용
P3aGUI 빌더 코어 — 노드 드래그·연결·설정·엣지 조건·드래프트 저장/로드
P3b배포 / 롤백 / 실행 트리거 / 실행(run) 이력 / 라이브 노드 상태
P3c (현재)커넥터·스텝 라이브러리 등록 · 메타소스 바인딩 · 파이프라인 이름변경/삭제(D7)
후속커넥터·스텝 편집/삭제(백엔드 + cascade 안전성 설계 필요)

REST API 기반 작성·배포·실행 흐름과 데이터 모델은 Pipeline Studio API 가이드를 참고하세요.