배경
Storm Parse 는 파일을 검색·추론에 사용할 수 있는 의미 단위로 파싱하는 서비스입니다.
내부 전용으로 개발되었지만, Parse 기능만 원하는 외부 고객이 생기면서 독립 API 상품 니즈가 생겼습니다.
kr,jpSaaS zone 과 고객사 On-Prem 환경을 함께 지원해야 했습니다- API spec 은 유지하면서 실행 환경에 따라 Auth, Model Provider, Storage, Prompt 구성을 다르게 조립할 수 있는 구조가 필요했습니다
성과
- 내부에서만 사용되던 파싱 기능을 외부 고객이 직접 사용할 수 있는 공개 API 상품으로 확장하고, Authn/Authz · Billing · Usage · Logs 흐름을 하나로 정리했습니다
- 250806 테디노트 공개 세션 일정이 잡힌 상태에서, 개발 시작 2주만에 대외 공개가 가능한 수준으로 개발했습니다
- 다양한 업체의 사용 문의가 들어왔고, 회사의 메인 상품인 Storm 솔루션 외에 처음으로 SaaS 매출이 발생했습니다
- SaaS 멀티 리전과 On-Prem 환경을 모두 고려한 실행 구조를 설계했습니다
kr,jp등 SaaS zone 분리와 동시에 N개의 On-Prem 환경을 최소한의 작업으로 지원할 수 있는 기반을 만들었습니다
상세
// 1. profile 그룹 분리
local, dev, live, jp-live => application-saas.yml
onprem, onprem_local => application-onprem.yml
// 2. profile config 로 실행 전략 주입
saas {
apiKeyStrategy = manager
modelProvider = gemini or vllm
storage = objectStorage + redis
}
onprem {
apiKeyStrategy = masterKey
modelProvider = vllm
prompt = sitePrompt + optionalInjection
storage = siteObjectStorage + redis
}
// 3. bootstrap 에서 config 기반 컴포넌트 조립
inferencer = resolve(app.modelProvider)
config = importBy(activeProfile)
// 4. Facade 에서 job lifecycle 제어
prepare -> preInfer -> infer -> afterInfer
jobResult -> credit.confirm() or credit.cancel()
- SaaS 멀티 리전과 On-Prem 환경에 따라 Auth, Model, Storage, Prompt 전략을 주입할 수 있도록 구성했습니다
- Facade 에서 job 상태 관리를 통해 parse lifecycle 과 Credit 확정/취소 흐름을 명시적으로 제어하고, 장애 지점 식별과 Billing 정합성 추적을 단순화했습니다
- API Key 부터 Account / Credit / Usage 집계까지 이어지는 end-to-end 흐름을 구현했습니다

