검토 결과를 구현 구조로 옮긴 제안
업무를 네 영역으로 나누고, 결과가 만들어진 과정도 남긴다.
기준정보, 관측, 모델 수명주기, 발행을 서로 다른 책임으로 둔다. 수집한 사실은 바꾸지 않고, 라벨과 특징은 버전으로 고정하며, 공개 결과에서는 사용한 모델과 근거까지 거슬러 올라갈 수 있게 한다.
한 줄 결론
처음에는 기존 두 프로세스와 한 데이터베이스를 유지한다. 배치 프로세스가 네 업무 영역의 쓰기를 맡고, 조회 프로세스는 완성된 공개본만 읽는다. 같은 PostgreSQL을 써도 스키마·역할·쓰기 주체는 나눈다.
권장 전체 도메인 구조
전체 그림에는 네 업무 경계와 데이터가 넘어가는 방향만 남겼다. 필드와 메서드는 아래 영역별 클래스 그림에서 확인한다. 동료 문서처럼 큰 그림과 상세 그림을 분리해 한 화면의 글자 수를 줄였다.
- 기준정보 · catalog
RouteVersion과SourceKey가 당시의 노선 축과 공급자 키를 고정한다. - 관측 · observation
CollectionAttempt와ObservationBatch가 호출 결과와 실제 관측을 나눈다. - 모델 수명주기 · modeling
DatasetSnapshot부터ModelRelease까지 학습·평가·선택 근거를 잇는다. - 예보 발행 · publication
PublicationBundle이 승인된 결과를 묶고PublicationQuery가 현재 공개본만 읽는다.
이 그림은 처리 순서와 업무 경계만 보여준다. 클래스의 소유 관계나 데이터베이스 외래키를 뜻하지 않는다. 새 데이터베이스 스키마와 API 응답 형식은 도메인 합의 뒤 정한다.
먼저, 무엇이 어떻게 바뀌는가
동료안은 29개 타입을 한 장에 넣지 않고 수집 7개, 집계·예측 17개, 조회 API 5개로 나눴다. 권장안도 같은 형식으로 기준정보, 관측, 모델 수명주기, 예보 발행을 각각 그렸다. 본문 그림은 전체 구조를 한눈에 보도록 축소했다. 필드는 각 그림 아래의 ‘SVG 크게 보기’에서 읽을 수 있다.
- 호출 결과와 실제 관측을 나눈다.
CollectionAttempt는 호출 결과를,ObservationBatch는 검증된 관측을 맡는다. - 기준정보에 적용 기간과 개정 이력을 더한다.
RouteVersion,CatalogRevision,SourceKey로 당시 노선과 공급자 키를 남긴다. - 모델 버전 뒤에 학습·평가·승인 근거를 잇는다.
DatasetSnapshot → TrainingRun → ModelArtifact → EvaluationRun → SelectionDecision → ModelRelease를 연결한다. - 화면·API 응답 모양을 업무 객체에서 분리한다.
PublicationBundle과PublicationQuery까지만 합의하고 새 API DTO는 그 뒤에 설계한다.
두 도메인 구조가 실행 프로세스와 저장소에서 만나는 방식 보기
SnapshotSource → Snapshot · BusObservationAggregationJob → CellRisk → ChanceModel → RouteForecastForecastRepository가 예보를 조회해 응답으로 바꿈- 처리·조회 분리와 미추정 상태는 그대로 살릴 강점이다.
- 정상 응답·차량 없음과 호출 실패, 불완전 페이지를 별도 결과로 남길 자리가 부족하다.
- 라벨·특징·학습·평가·선택·모델 발행의 연결 기록이 빠져 있다.
기록 보강
- 정상 빈 응답·오류·불완전 기준정보를 서로 다른 기록으로 남긴다.
- 모델별 입력·파일·평가·승인 기록을 분리해 다시 확인할 수 있게 한다.
- 현재 공개용 자료와 과거 내부 연구 자료는 서로 다른 계열로 분리해 관리한다.
비포의 29개는 class, record, enum, interface, Spring Data repository를 같은 단위로 센 동료안의 목록이다. 권장안 59개 가운데 핵심 51개는 위 그림에 표시했다. 반복되는 규격·저장·평가 객체 8개는 아래 객체 지도와 계약 설명에 남겨 그림의 밀도를 낮췄다. 59는 목표 클래스 수가 아니며, 구현에서는 독립 규칙이 없는 얇은 타입을 합칠 수 있다.
SnapshotSource · 위치 수집에 맞춘 하나의 입구RealtimeObservationSource · 기존 변화 지점의 역할을 더 분명하게 한다.ReferenceDatasetSource · 완결성과 공급자 버전을 별도 규칙으로 다룬다.CallBudget · 호출당 비용을 수집 객체가 판단ProviderCallPolicy · 계정·환경별 한도를 관리해 과도한 호출을 막는다.Snapshot에 두 의미가 함께 들어 있음CollectionAttempt · ObservationBatch로 차량 없음·오류·정상 행을 구분한다.BusObservation · 실제로 본 위치·좌석 사실BusObservation + PrivateVehicleRef · 공개 예보에 차량 식별값이 섞이지 않게 한다.CellRisk 하나로 모델 차이를 감춤FeatureSpec → FeatureSnapshot · 없는 값을 0이나 다른 노선 값으로 대신하지 않는다.ChanceModel의 한 입력·출력 모양을 모든 모델에 적용FullRiskPredictor · ModelRecipe · ModelArtifact · ModelBundle · ModelReleaseChanceState가 Estimated | NotEstimated를 나눔Estimate + UnavailableReason · 확률 0과 계산 불가를 구분하고 생성 이력을 함께 남긴다.ChanceModel.version()을 RouteForecast에 남기지만 실제 파일·학습 자료·평가 근거까지 재현할 정보는 없다.ModelRelease → ForecastRun → FullRiskForecast → PublicLineage → PublicationBundle로 어떤 모델로 언제 만든 예보인지 남긴다.RouteVersion · PassageEvidence · LabelPolicy · TrainingRun · EvaluationRun · SelectionDecision · PublicationBundle로 판단 근거를 다시 확인할 수 있게 한다.이 대응표는 클래스 이름을 일괄 치환하라는 목록이 아니다. 먼저 오른쪽 책임과 상태 전이를 합의한 뒤, 실제 언어와 저장 방식에 맞춰 타입 수를 줄이거나 합친다. 설계 v3의 ForecastResponse와 StopResponse는 도메인에 옮기지 않는다. 새 응답 계약은 도메인 합의가 끝난 뒤 읽기 어댑터에서 설계한다.
전체 지도
각 경계가 소유하는 말과 기록을 한눈에 표시했다. 다른 경계의 사실을 다시 해석하거나 직접 고치지 않고, 버전이 붙은 참조로 이어 준다.
공급자 필드명은 표준 관측과 후속 경계로 넘기지 않는다. 원래 결과 코드와 원문은 승인된 비공개 증거에만 머문다. 공개 조회는 발행 경계에서 끝나며 차량 연결값과 학습 내부 상태를 거슬러 읽지 않는다.
네 업무 경계가 소유하는 것
업무 영역마다 쓰는 말과 실패 조건이 다르다. 다른 영역의 테이블을 직접 고치거나 객체 관계로 강하게 묶지 않는다.
- 소유
- 노선 버전, 정류장 순번, 외부 키 대응, 차량 규격 이력
- 입력
- 완결된 공공 기준정보 취득본
- 출력
RouteAxisRef, 유효시점이 붙은 참조- 쓰기
- 기준정보 수집 작업만
- 소유
- 호출 결과, 수신 증거, 표준 관측, 회차, 통과 근거
- 입력
- 실시간 공급자 응답과 기준정보 참조
- 출력
ObservationBatch,PassageEvidence- 쓰기
- 수집기·정규화기·통과 파생기만
- 소유
- 라벨·특징 정책, 데이터 고정본, 학습·평가 실행, 산출물, 선택
- 입력
- 통과 근거, 기준정보 버전, 현재 수집 계열
- 출력
ModelRelease, 재현 가능한 예측·지표- 쓰기
- 학습기·평가기·승인 작업만
- 소유
- 예보 실행, 만석 위험, 공개 평가 요약, 발행 묶음, 현재 공개본 표시
- 입력
- 활성 모델 발행본과 발행용 특징
- 출력
PublicationBundle과 읽기 계약- 쓰기
- 발행 작업만, API는 읽기 전용
한 번에 함께 저장할 범위
- 같이 저장할 때 반드시 함께 맞아야 하는 값만 한 묶음으로 둔다. 업무 영역 사이는 바뀌지 않는 ID와 내용 목록으로 연결한다.
ObservationBatch가 모든 행을 한 객체 안에 들고 있을 필요는 없다. 묶음 전체를 검증한 뒤 관측 행을 한 번에 저장해도 같은 책임 범위다.- 현재값을 고치는 대신 새 버전·새 실행·새 결정을 추가한다. 과거 예측의 계보는 활성 모델이 바뀌어도 그대로 남는다.
권장 객체 지도
아래 이름은 책임을 고정하기 위한 설계 어휘다. 클래스 수 목표가 아니다. 값의 범위나 상태 전이를 지키지 않는 얇은 포장은 만들지 않는다.
기준정보 · catalog
노선 버전 · 정류장 순서 · 노선 축 참조 · 적용 기간 · 기준정보 개정RouteVersion · RouteStop · RouteAxisRef · ValidityWindow · CatalogRevision
기준정보 취득 · 공급자 계약 참조 · 변환기 버전 · 공급자 키ReferenceDatasetAcquisition · SourceContractRef · AdapterVersion · SourceKey
차량 규격 개정 · 비공개 차량 연결VehicleSpecRevision · VehicleIdentityLink
공급 자료 범위 · 호출 허용과 재시도 규칙SourceCapability · ProviderCallPolicy
기준정보 수집 창구 · 기준정보 저장소ReferenceDatasetSource · CatalogStore
관측 · observation
공급자 호출 시도 · 호출 결과 분류CollectionAttempt · CollectionOutcome
관측 묶음 · 차량 관측 · 잔여석 판독 · 차량 위치ObservationBatch · BusObservation · SeatReading · BusPosition
같은 회차의 연속 관측 구간TripSegment · 같은 차량·노선·회차 안에서 이어지는 관측을 묶는다.
정류장 통과 증거PassageEvidence · 정확한 한 정류장 또는 가능한 정류장 구간을 파생 사실로 남긴다.
판정에 쓴 관측 참조EvidenceRef · 직전과 현재 관측을 각각 배치 ID·관측 ID로 가리켜 판정을 다시 확인할 수 있게 한다.
비공개 차량 참조PrivateVehicleRef
보존 정책 · 관측 변환 · 통과 증거 생성 · 실시간 관측 수집 창구RetentionPolicy · ObservationNormalizer · PassageDeriver · RealtimeObservationSource
모델 수명주기 · modeling
점 라벨 · 구간 학습 예시 · 라벨 규칙 · 특징 규격 · 특징 요구 조건 · 특징 고정본PointLabel · IntervalTrainingExample · LabelPolicy · FeatureSpec · FeatureRequirement · FeatureSnapshot
학습 자료 고정본 · 학습 실행 · 모델 학습법 · 모델 파일 · 보정 파일DatasetSnapshot · TrainingRun · ModelRecipe · ModelArtifact · CalibratorArtifact
평가 실행 · 평가 규칙 · 구간별 지표 · 선택 결정EvaluationRun · EvaluationProtocol · CohortMetric · SelectionDecision
모델 조합 · 승인 조건 · 승인 모델 발행본ModelBundle · ReleasePolicy · ModelRelease
만석 위험 예측 창구 · 사용한 모델과 입력이 연결된 개별 예측FullRiskPredictor · Prediction
예보 발행 · publication
예보 계산 실행 · 예보 대상ForecastRun · ForecastTarget
만석 위험 예보 · 추정 상태 · 예측 불가 사유FullRiskForecast · Estimate · UnavailableReason
공개 평가 요약 · 공개 결과 생성 이력ModelEvaluationView · PublicLineage
공개 묶음 · 현재 공개본 표시 · 공개본 조회 창구PublicationBundle · ActivePublication · PublicationQuery
공용 모듈에는 시각·내용 확인·직렬화처럼 업무 판단을 하지 않는 공통 기능만 둔다. Route·Vehicle 같은 도메인 객체를 공용 모듈에 몰아넣지 않는다.
수집 결과와 원문 보존을 먼저 분리한다
빈 차량 목록과 실패는 같은 값이 아니다. 호출 결과를 확정한 뒤에만 표준 관측을 만들고, 원문 보존은 공급자·데이터셋·필드별 정책으로 제한한다.
source + operation + endpointVersion + adapterVersion + route SourceKey + poll key
- 현재 위치 조회는
format=json을 요청에 명시한다. JSON을 요청했는데 게이트웨이의 XML 오류 봉투가 오면 정상 응답으로 읽지 않고 실제 형식과 오류 내용을 따로 남긴다. - 결과 코드 0의 행 있음·행 없음과 결과 코드 4를 서로 다른 지속 상태로 남긴다.
- 알 수 없는 코드·필드 존재 여부·원래 자료형은 정규화 결과와 함께 증거에 보존한다.
source + dataset + pIndex + pSize≤1000 + head.api_version + adapterVersion
Type을 생략하면 공식 기본값은 XML이다. 프로젝트는 JSON을 명시하고 실제 형식을 검증한다.- 정상 페이지의
head[].RESULT에서INFO-000을 확인한다. 정상 봉투 없이 최상위RESULT만 온 응답은 업무 오류 봉투로 따로 기록한다. - 모든 페이지와 전체 건수·API 버전이 맞아야 취득 완료 후보가 된다.
- 공급자 스냅샷 토큰이 없으므로 완료 뒤에도
SOURCE_CONSISTENCY_UNKNOWN을 남긴다. 페이지 사이 변동 징후가 있으면PAGE_DRIFT_SUSPECTED로 막는다.
AUTOMB_ID와 VEH_ID는 근거·검증 상태·유효기간·대응 버전이 있는 비공개 VehicleIdentityLink가 있을 때만 잇는다. 없으면 공급자별 식별자로 남긴다.기본 분리구체적인 단기 격리 기간은 이 문서에서 임의로 정하지 않는다. 소유자가 기간·삭제·백업 반영을 승인하고 자동 파기 시험이 통과해야 한다. 기간이 지나 원문을 지우면 미래의 새 필드를 과거 응답에서 다시 해석할 수 없다. 이 손실까지 알고 승인해야 한다.
비공개 식별값과 원문 보관의 구현 조건
serviceKey와KEY실제값은 URL·로그·수신 증거에 남기지 않는다. 요청 전에 비밀 참조로 주입하고 기록 전에 가린다.- 복구할 수 없는 연결값이 필요하면 목적·공급자·필드별로 분리한 HMAC을 쓴다. 정규화 규칙, 알고리즘,
key_id, 토큰 버전과 128비트 이상의 출력 길이를 기록하고, 키 접근·회전·폐기를 감사한다. - HMAC 키 원문은 코드·평문 환경변수·데이터베이스·수집 자료와 분리된 관리형 KMS/HSM에 둔다. 수집 역할에는 지정 키의 MAC 생성 권한만 주고 키 반출·복호화·다른 키 사용 권한은 주지 않는다.
- 원본값이 없으면 임의 연결값을 만들지 않고
UNTRACKED로 둔다. 해시나 HMAC을 익명화의 보증으로 표현하지 않는다. - 격리 원문은 승인된 수집·감사 역할만 읽는다. 조회 API와 학습기는 읽지 못하며, 읽기·키 사용·삭제와 백업 사본 파기를 모두 감사한다.
변환 경계의 정확한 규칙
- 잔여석
0은 만석이다.-1은 공급자 정보 없음 값, 필드 누락은FIELD_ABSENT,null은NULL_VALUE, 자료형·파싱 실패는PARSE_ERROR로 따로 남긴다. 이후 화면에서 모두 ‘정보 없음’으로 보여도 근거는 합치지 않는다. - 혼잡도 공식 코드는 문자열 1~4다. 실응답 정수 0은 프로젝트 호환값인 ‘미산출’로만 다루며 ‘여유’로 해석하지 않는다.
- 외부 식별자는
SourceKey(source, namespace, value)범위 안에서만 같다고 본다. 검증된 대응표 없이 공급자 사이 숫자를 결합하지 않는다. RouteVersion은 내부 노선축의 유효기간이다. GBIS API 주소 버전, 변환기 버전, 경기데이터드림head.api_version, 내부 기준정보 개정 번호를 각각 다른 값으로 기록한다.- GBIS 기반정보가 주는
areaVersion·routeVersion·routeLineVersion·routeStationVersion·stationVersion·vehicleVersion도 한 값으로 합치지 않고 취득본에 각각 보존한다. - 경기데이터드림 기준정보는 모든 페이지와 전체 건수·API 버전이 맞을 때
ReferenceDatasetAcquisition을 완료한다. 스냅샷 토큰이 없으므로 공급자 일관성은 ‘알 수 없음’으로 남기고, 페이지 변동 징후가 있으면 기준정보로 승격하지 않는다. - 공급자가 기록한 원문 시각
queryTimeRaw, 서버 수신 시각, 처음 사용할 수 있게 된 시각을 따로 둔다. 늦게 온 정정은 과거 행을 고치지 않고 새 관측이 이전 관측을 가리키게 한다.
통과 근거와 만석 라벨을 다른 객체로 둔다
PassageEvidence는 무엇을 관측했는지 말하고, LabelPolicy는 그 근거를 어떤 정답으로 읽을지 결정한다. 라벨 규칙이 바뀌어도 관측 사실은 고치지 않는다.
- 같은 노선·차량·회차·한국 표준시(KST) 날짜
- 인접한 성공 응답, 경과시간 0초 초과 90초 이하
last_passed가 정확히 1 증가- 정류장 S 출발
(2,S), 출발 뒤 교차로 통과(0,S), 다음 정류장 도착(1,S+1) - S에 막 도착한
(1,S)는 출발 뒤 라벨이 아님
- 같은 차량 연결은 유효하지만 순번을 건너뜀
- 또는 90초를 넘어 정확한 점을 확정할 수 없음
- 후보 정류장 1~6개와 전체 가중치 1을 보존
- 점 근거로 승격하지 않고 검열된 근거로 유지
PassageEvidence · 관측 근거와 후보 정류장LabelPolicy · 목표 사건 · 시간 상한 · 검열 규칙 · 버전PointLabel · Full · NotFull · UnknownFull | NotFull은 운영 후보 5개와 비운영 참조 1개의 기본 학습에 쓴다. Unknown은 학습에서 뺀다.Full | NotFull, 후보 정류장 1~6개, 각 후보 가중치 1/n을 묶는다. 구간 검열 모델에만 넣고 다른 5개 기본 모델과 Platt 보정에는 넣지 않는다.공통 목표는 ‘목표 정류장 출발 뒤 잔여석이 0인 사건’이다. 이 사건의 확률을 p_full로 부른다. 그 여집합은 비만석 확률이지 실제 탑승 성공률이 아니다.
모델은 구현 하나가 아니라 수명주기로 관리한다
현재 5개 운영 후보, 1개 보정층, 1개 비운영 참조는 역할이 다르다. 공통 예측 규칙은 만석 위험이라는 결과만 맞추고, 필요한 특징·실제 모델 파일·지원 범위·예측 불가 사유는 모델별로 보존해야 한다.
- 학습 자료 확정
DatasetSnapshot· 포함한 행 전체와 사용 목적 - 학습
TrainingRun· 코드·난수 초기값·환경·학습 구간 - 파일 보관
ModelArtifact· 실제 바이트와 호환 계약 - 평가
EvaluationRun· 고정 미래구간과 같은 라벨 - 선택
SelectionDecision· 승인·보류·기각 근거 - 배포 승인
ModelRelease· 범위·채널별 승인 뒤 변경 금지
개발 계약 보기
FullRiskPredictor
requires() → FeatureRequirement
supports(RouteAxisRef, ModelBundle) → boolean
predict(ForecastTarget, FeatureSnapshot, ModelBundle)
→ Prediction(
estimate = Estimated(p_full, lineage) | NotEstimated(reason),
modelBundleRef,
featureSnapshotRef)
ModelBundle =
BaseBundle(baseArtifactRef@version/digest)
| CalibratedBundle(
baseArtifactRef = logistic_interactions@version/digest,
calibratorArtifactRef,
rawFallback = FORBIDDEN)
Every bundle
featureSpec + labelPolicy + supportedScope
FeatureSnapshot.availableAt ≤ ForecastTarget.atlogistic_interactions의 동일 버전·파일 내용 확인값과 더 앞선 날짜의 교차검증 밖 예측을 참조한다. 단독 후보가 아니며 보정 실패 때 원래 확률로 돌아가지 않는다.Full | NotFull과 각 모델의 FeatureSnapshot이 운영 후보 5개와 비운영 참조 1개로 간다.1/n 가중치는 interval_censored에만 간다. 다른 기본 모델과 Platt 보정으로 가는 선은 없다.ModelRelease로 넘어간다.logistic_interactions@version/digest + 더 앞선 날짜의 OOF 원래 p_full + 점 라벨
CalibratorArtifact를 만든다. 미달이면 NotEstimated(CALIBRATOR_INELIGIBLE)로 끝내며 원래 확률을 대신 내보내지 않는다.자료 목적을 명시하고 혼합을 검사 단계에서 막는다
DatasetSnapshot, 실행, 산출물은 public_current 또는 internal_research 중 하나만 가진다. 공개 계열이 내부 연구 계열을 부모로 참조하면 생성 단계에서 오류로 기록한다.
| 역할 | 실제 필요한 입력 | 산출물에 고정할 것 | 발행 조건 |
|---|---|---|---|
| 구간 검열 추정 | 점 라벨과 최대 6개 후보 정류장의 구간 근거, 노선·정류장·시간대 | 계층별 건수·사전확률·축소 강도·상위값 사용 규칙 | 구간 규칙과 실제 집계 계층이 선언과 일치 |
| 상호작용 로지스틱 | 노선, 시간대, 노선×정류장, 노선×시간대, 노선×정류장×시간대. 독립 정류장 주효과는 없음 | 계수·특징 순서·처음 보는 범주의 처리 | 지원 범위 밖과 효과 0을 구분 |
| GAM | timing.response_received_at을 한국 표준시의 연속된 시간으로 바꾼 값과 노선축 정류장 위치 | 시간의 sin/cos 주기항·축 범위·기저함수·계수·처음 보는 노선의 처리 | 시간대를 연속 시각 대신 넣지 않고, 노선 개편 때 새 축 버전을 사용 |
| 경험 베이즈 | 점 라벨, 노선·정류장·시간대와 계층별 집계 | 계층별 건수·사전확률·축소 강도·상위값 사용 규칙 | 실제 집계 순서와 선언이 일치 |
| 계층 로지스틱 | 절편+정규화 정류장 위치, 시간대, 노선, 노선×정류장 범주, 노선×시간대. 평일/주말 입력은 없음 | 계수·특징 순서·노선별 범위·수준별 규제값 | 처음 보는 노선을 다른 노선으로 대신 처리하지 않음 |
| Platt 보정층 | logistic_interactions 동일 버전·파일 내용 확인값의 원래 p_full, 더 앞선 날짜의 OOF 예측, 점 라벨 | 기본 모델 참조·보정 파일·50/5/20 적격 조건·원래 확률 대체 금지를 한 조합으로 고정 | 조건 미달이면 CALIBRATOR_INELIGIBLE. 원래 확률을 대신 반환하지 않음 |
| 그래디언트 부스팅 참조 | 노선·정류장 위치, response_received_at의 한국 표준시 연속 시간, 별도 평일/주말·시간대 | 트리 전체·한 종류 라벨만 있을 때의 처리·지원 범위 | 평가까지만 수행하고 비운영 비교용 상태를 유지 |
예측, 평가, 공개 발행을 한 계보로 연결한다
모델 파일 이름만 남기면 재현할 수 없다. 공개 확률과 성능 지표는 각각 어떤 자료·규칙·실행·결정에서 왔는지 중간 기록이 빠지지 않은 연결 정보를 가져야 한다.
ModelRelease · 사용할 모델 조합과 범위ForecastRun · 시작할 때 승인 모델을 고정PublicationBundle · 예보·평가 요약·생성 기록을 함께 교체현재 공개본 표시(ActivePublication)는 채널별 완성본 하나를 가리킨다. 새 묶음을 모두 쓴 뒤 한 번의 DB 변경으로 표시를 바꾸며, 이전 묶음은 그대로 남긴다.
성능 숫자와 선택 관문을 분리한다
표본이 작아도 실제 측정값은 표본 수·기간·상태와 함께 공개할 수 있다. 다만 그 숫자를 모델 선택 근거로 쓸 수 있는지는 별도 상태로 판정한다.
MEASURED · 값·표본·기간을 공개한다. 선택 조건은 별도 검사한다.LOW_SAMPLE · 측정값은 보이되 작은 표본 경고와 불확실성을 붙인다.EMPTY · 해당 평일·주말·출근·퇴근 구간에 평가 사건이 없다.NOT_COMPARABLE · 라벨·모델·구간 버전이 달라 같은 순위표에 놓지 않는다.새 표본이 쌓이면 새 EvaluationRun과 지표를 추가한다. 모델·라벨·구간 정의가 바뀌면 새 계열을 시작해 성능 변화의 원인을 구분한다.
처음에는 두 프로세스로 충분하다
업무 경계와 배포 단위를 같은 수로 맞출 필요는 없다. 쓰기 경로는 배치에 모으고, 조회 프로세스는 발행 스키마만 읽게 한다.
- 기준정보·실시간 수집
- 정규화·통과 근거 생성
- 학습·평가·선택
- 예보 계산·발행본 생성
- 보존·감사 작업
publication스키마만 읽기- 활성 묶음 조회·캐시
- 새 API 계약으로 변환
- 관측·모델 테이블 직접 조회 금지
- 원본 차량값 권한 없음
catalog · observation · modeling · publication 스키마와 역할 분리. 스키마 내부 FK만 기본 허용.메시지 브로커, 모델별 서버, 경계별 물리 DB는 지금 도입하지 않는다. 병렬 팀 소유·독립 확장·장애 격리 요구가 실제로 생길 때 분리한다.
| 역할 | 읽기 | 쓰기 | 금지 |
|---|---|---|---|
collector · 수집 | 공급자 설정·기준정보 참조 | 수집 시도·격리 증거 | 라벨·모델·발행 |
normalizer · 정규화 | 승인된 증거·기준정보 | 표준 관측·비공개 연결값 | 공개 조회본 |
trainer · 학습/평가 | 표준 관측·통과 근거·기준정보 | 모델 수명주기 산출물 | 원문·번호판·활성 발행 포인터 |
publisher · 발행 | 승인된 모델 발행본·발행용 특징 | 공개 묶음·포인터 | 모델 선택 결정 수정 |
api_reader · 조회 | 활성 공개 묶음 | 없음 | 그 밖의 내부 스키마·수신 증거·차량 연결값 |
변경 영향을 가능한 한 한 업무 영역에 가둔다
새 공급자나 모델을 추가할 때 기존 관측과 과거 평가를 고치지 않는다. 새 버전과 대응표를 추가하고, 같은 기존 기능 유지 검사를 통과시킨다.
| 변경 | 바꾸는 곳 | 그대로 두는 곳 | 필수 증거 |
|---|---|---|---|
| 새 공공 API | 공급자 변환기·보존 정책·SourceKey 대응표 | 라벨·모델·발행 의미 | 고정 입력 예시와 오류 분류 |
| 새 후보 모델 | ModelRecipe·FeatureSpec·예측 구현 | 관측·라벨·공개 발행 | 실제 모델 파일을 사용한 동일 평가 |
| 노선 개편 | 새 RouteVersion·RouteAxisRef | 과거 관측·라벨·예측 | 유효기간과 정류장 대응 |
| 평가 구간 변경 | CohortDefinition·EvaluationProtocol | 모델 파일·기존 지표 계열 | 새 비교 계열 ID |
| 새 서비스 API | 공개 묶음을 응답으로 바꾸는 계약 | 수집·모델 내부 객체 | 도메인 합의 뒤 계약 시험 |
| 보존 정책 변경 | RetentionPolicy·삭제 작업·권한 | 공개 예보 의미 | 만료·백업 사본 전파·감사 시험 |
현재 경로를 버리지 않고 옮기는 순서
전면 재작성 대신 같은 수집 자료에서 기존 결과와 새 결과를 함께 만들고 전건 대조한다. 단계마다 되돌릴 수 있는 지점을 남긴다.
- 뜻과 규칙 합의
만석 위험의 뜻과 호출 결과·노선 변경·통과 근거·라벨 규칙을 사례로 합의한다.
- 원문 정책 결정과 변환 경계 도입
GBIS 단기 격리·장기 증거 정책, 경기데이터드림 번호판 폐기, 역할 권한과 구체적인 보존 기간을 승인한다.
- 관측·통과 근거 이중 생성
같은 응답에서 기존 행과 새 ObservationBatch·PassageEvidence를 만들고 오류·무차량·회차·90초 경계를 전건 대조한다.
- 데이터 고정본과 실제 모델 산출물 생성
FeatureSpec·DatasetSnapshot·TrainingRun·ModelArtifact를 만들고 5+1+1 역할을 실제 파일 내용 확인값으로 묶는다.
- 평가·선택·비공개 병행 발행
고정 미래구간과 평일·주말·출근·퇴근 지표를 만들고, SelectionDecision을 통과한 모델 발행본으로 비공개 예보를 함께 계산한다.
- 발행본 전환 뒤 새 API 설계
PublicationBundle 동등성과 권한을 확인해 현재 공개본 표시를 바꾼다. 그다음 공개 조회본에 맞춰 새 스키마와 API를 설계한다.
구현 시작 전 승인 관문
- GBIS 원문 보존과 기존 호환성 명세의 충돌을 기간·필드·권한·삭제 시점을 정한 하나의 정책으로 해소했다.
- 정상 차량 있음·정상 차량 없음·업무 오류·전송 오류가 저장과 라벨에서 구분된다.
- 점·구간 근거, 회차·한국 표준시 날짜·90초·응답 단절 규칙이 고정 시험 예시와 일치한다.
public_current계열이internal_research부모를 참조할 수 없다.- 학습·평가·발행이 같은 ModelBundle 파일 내용 확인값과 LabelPolicy를 가리킨다.
- 운영 후보 5개만 선택 대상이며 보정층과 비운영 참조의 역할이 타입으로 분리된다.
- API 역할이 수신 증거·차량 연결·모델 수명주기 스키마와 원본 차량값을 읽지 못한다.
- 도메인 합의 전에는 새 서비스 스키마와 HTTP 응답 필드를 확정하지 않는다.
이번 제안에서 의도적으로 만들지 않는 것
- 모델마다 별도 서버를 두지 않는다.
- 경계마다 물리 DB나 메시지 브로커를 두지 않는다.
- 실행 도중 모델을 임의로 바꾸는 기능을 만들지 않는다. 작업 시작 때 승인된 모델 발행본 하나를 고정한다.
- 공급자 응답용 객체, 화면 응답용 객체, DB 저장용 객체를 업무 객체와 같은 것으로 취급하지 않는다.
근거와 적용 범위
- 모델·공공 API 기준 설계 검토 — 이 제안의 판정 근거와 결손 분석
- 현재 후보 모델 7개 — 운영 후보 5, 보정층 1, 비운영 참조 1
- GBIS 프로젝트 호환성 명세 · 공식 버스위치정보 · 공식 기반정보
- 경기데이터드림 프로젝트 호환성 명세 · 공식 OpenAPI 이용 안내
- 동료의 객체 설계 v3 원문 — 유지할 구조와 수정할 의미 계약의 출발점