원문이 의도한 확장점은 SnapshotSource와 ChanceModel 두 개다. 다만 이를 Java 인터페이스 전체 수라고 쓰면 sealed ChanceState와 Spring Data 저장소·조회 인터페이스가 빠진다. 의도한 확장점 수와 실제 인터페이스 선언 수를 나눠 써야 한다.
@ConditionalOnProperty는 기본적으로 애플리케이션 시작 시 설정을 고르는 기능이지 빌드 시점 선택이 아니다.
API 패키지의 JPA 엔티티 선언이 0이어도 persistence unit이 다른 패키지의 RouteForecast 메타데이터를 읽으면 JPQL은 실행된다. 이 경우에도 classpath·persistence unit 결합은 남으므로 “import 0”과 “결합 0”을 같은 뜻으로 쓰면 안 된다.
이 항목은 아키텍처 취향과 무관한 원문 내부 정합성 문제다. 정확한 타입 목록·선택 시점·조회 구현을 다시 적기 전에는 확인 불가로 둔다.
먼저 결정할 것
간결한 구조는 장점이지만, 객체 수만으로 채택할 수는 없다. 현재 모델 규격과 공공 API 명세를 기준으로 유지·수정·보류를 나눴다.
그림 1 · 설계 v3 판정 — 구조는 유지하고 의미 계약은 보강한다
프로세스 분리수집·학습·발행의 쓰기 책임과 후속 조회 책임을 나눈다.유지
단일 쓰기 주체같은 물리 DB를 써도 테이블·스키마의 소유자는 하나여야 한다.유지
명시적 미추정값 없음, 지원 밖, 표본 부족을 확률 0으로 바꾸지 않는다.유지
모델 입력 계약노선 버전, 연속 시각, 모델별 특징, 산출물 참조가 빠져 있다.수정
라벨과 시간 증거정류장 출발 상태, 인접 응답, 회차, 공백·오류 경계가 필요하다.수정
모델 출력 의미만석확률, 그 수학적 여집합, 화면에 표시할 백분율을 한 타입으로 섞지 않는다.수정
구현 기술 선결JPA, 마이크로서비스, 모델별 서버 분리는 실제 규모와 부하 증거 뒤에 정한다.보류
판정 기준은 현재 코드·평가 규격·공공 API가 요구하는 의미를 보존하는지다.
확인한 사실설계 v3의 SnapshotSource, 처리·API 분리, Estimated | NotEstimated는 변화 방향과 실패 상태를 드러낸다.
검토 판단“패키지 import 0”이나 “JPA 엔티티 0”은 경계가 지켜졌다는 증거가 아니다. 스키마 소유권, 권한, 직렬화 계약과 회귀 검사가 함께 있어야 한다.
권장안물리 구조는 모듈러 모놀리스와 배치 프로세스를 기준으로 시작한다. 후속 조회 경계를 분리하고, 업무 경계 사이의 직접 엔티티 참조와 교차 쓰기를 금지한다.
현재 데이터가 답이 되기까지
공공 API 응답을 곧바로 모델 입력으로 쓰지 않는다. 보존이 허용된 수신 증거, 관측 사실, 통과 근거, 라벨, 특징, 학습·평가 산출물을 순서대로 구분해야 같은 결과를 다시 설명할 수 있다.
그림 2 · 증거 흐름 — 실선은 현재 확인한 책임, 점선 상자는 도입할 계약이다
공공 API 수신 증거정책이 허용한 본문·필드·수신 시각·해시·호출 결과
→
표준 관측노선·차량·정류장 위치·좌석·상태
→
통과 근거회차·인접 응답·점 라벨 또는 짧은 구간
→
평가 자료날짜 순방향 분할·고정 평가 구간
↓ 운영 발행을 위해 보강
특징 스냅샷예측 시점까지 이용 가능했던 입력
→
모델 산출물학습 실행·파라미터·파일 해시
→
예측만석확률 또는 명시적 미추정
→
만석 위험 발행승인된 모델 버전과 p_full 또는 미추정 사유
현재 공개 평가는 수집·라벨·모델 비교를 수행하지만, 운영에 올릴 모델 파일과 활성 발행본을 아직 고정하지 않는다.
라벨은 좌석 0 한 칸으로 끝나지 않는다
확인한 사실: 현재 정답은 “목표 정류장을 출발한 뒤 잔여석이 0”인 사건이다. 점 근거는 같은 수집 전략·노선의 인접 성공 응답에서 같은 차량·회차·KST 날짜가 이어지고, 경과가 0초 초과 90초 이하이며, 파생 last_passed가 정확히 1 늘고 현재 좌석이 유효한 출발 뒤 상태일 때 생긴다. 목표 정류장을 S라 하면 유효한 (stateCd, stationSeq)는 (2,S), (0,S), (1,S+1)이고, 도착 상태인 (1,S)는 라벨이 아니다. 순번을 건너뛰었거나 90초를 넘긴 관측쌍도 후보 last_passed가 1~6개이면 별도 구간 근거로 남긴다.
검토 판단:BusObservation(vehicleId, stationSeq, remainingSeats, crowded)에는 출발 상태인 stateCd와 각 응답의 성공·무차량·실패 경계가 없다. 공식 무차량 응답이나 실패를 지운 뒤 성공 행끼리 연결하면 실제로 없던 통과 라벨을 만들 수 있다.
권장안: 관측과 라벨 사이에 JourneyKey, PassageEvidence(POINT | INTERVAL), LabelPolicy를 둔다. 정상 차량 있음, 정상 차량 없음, 수집 실패를 서로 다른 CollectionOutcome으로 남긴다.
공공 API 변화는 변환 경계에서 막는다
공급자 응답 키와 오류 코드를 핵심 도메인에 바로 넣지 않는다. 원문을 보존할지, 어떤 필드를 얼마 동안 남길지는 공급자·필드별 정책으로 정한다. 보존하도록 승인한 증거만 비공개 계층에 두고, 공급자별 변환기가 장기간 유지할 표준 관측과 기준정보로 바꾼다.
그림 3 · 공급자 경계 — 호출 모양은 달라도 내부 계약은 일정하게 유지한다
GBIS 실시간 위치노선 한 건의 차량 목록·좌석·혼잡·운행 상태
경기데이터드림페이지 단위 수요·수송실적·차량 이력·정원·노선·정류장 자료
앞으로의 공급자도시·호출 단위·식별자·결측 규칙이 다를 수 있음
↓ 공급자별 호출 기록 + 승인된 원문·증거 + 버전별 변환기
승인된 비공개 증거정책이 허용한 본문·필드·해시·요청 범위·수신 시각·결과 코드
→
표준 관측차량 있음 / 차량 없음 / 실패를 구분
+
버전 기준정보공급자 키 매핑·노선 버전·페이지 완전성
↓ 핵심 도메인과 모델은 공급자 필드명을 모른다
원문·필드의 보존 여부와 기간은 공급자마다 따로 정한다. 보존하는 증거는 공개하지 않고 접근권한과 보존기간을 좁힌 비공개 계층에 둔다.
이 상태를 모두 Snapshot(buses=[])로 바꾸면 수집 장애를 “그 시각에 운행 차량이 없었다”는 사실로 오인한다. 호출 기록에는 receivedAt, queryTimeRaw, 원문 해시, 공급자·변환기 버전도 남긴다.
기술 상세 · 좌석·혼잡도·기준정보를 잃지 않는 법
잔여석은 0, -1, 필드 없음, null, 잘못된 타입·음수를 구분한다. 0은 만석이고 -1은 정보 없음이다.
혼잡도의 공식 코드는 문자열 1~4다. 프로젝트 GBIS 호환성 명세는 실응답 정수 0을 ‘혼잡도 미산출’로 기록한다. 둘은 같은 권위의 값이 아니다. 0을 ‘여유’로 해석하지 말고, 수신 시각·변환기 버전과 함께 실측 호환값으로 남긴 뒤 ‘미산출’로 정규화한다.
RawBus는 원문이 아니라 이미 필드를 고른 전달 객체다. 원문 본문과 필드 존재 여부를 별도 증거로 유지한다.
실시간 위치 주기 수집과 페이지형 기준정보 수집은 별도 경계다. 페이지 누락과 취득 중 전체 건수 변화는 page_drift(페이지 일관성 확인 필요) 상태로 남긴다.
경기데이터드림은 JSON 형식을 명시해 요청하고 응답 모양과 결과 코드를 함께 판정한다. INFO-000은 성공, INFO-200은 결과 없음, INFO-300과 ERROR-*는 업무 오류다. 성공의 head/row와 최상위 RESULT 모양, 페이지별 수신 시각, api_version, list_total_count, 수집 범위를 그대로 남긴다. HTTP 200만으로 성공 처리하지 않는다.
GBIS의 노선·정류장 기준정보에는 공급자가 따로 주는 여러 버전 번호가 있다. Flyway로 처음 넣었다는 사실을 외부 기준정보가 영구 불변이라는 근거로 쓰지 않는다.
공식 교차표나 검증된 대응표가 없으면 GBIS와 경기데이터드림의 같은 숫자 ID를 같은 객체로 결합하지 않는다.
경기데이터드림 호환성 명세의 PLATE_NO·AUTOMB_NO는 저장·노출 금지 대상이다. 필요한 목적별 연결값은 정규화 전에 HMAC으로 만들고 원본 번호판은 즉시 버린다. AUTOMB_ID·VEH_ID도 공급자 이름공간 안의 비공개 식별자로만 다룬다.
도입 전 해결할 충돌: 현재 GBIS 수집 계열은 원문과 정규화 행을 대조하지만, 프로젝트 GBIS 호환성 명세는 plateNo·vehId를 정규화 전에 HMAC 처리하고 원문을 저장하지 않는다고 적는다. 두 정책을 동시에 지킬 수는 없다. 목표 도메인을 승인하기 전에 보존 정책 하나를 정하고 수집기·명세·기존 저장 자료를 같은 기준으로 맞춰야 한다.
확인한 사실GBIS는 실시간 관측이고, 경기데이터드림 기준정보는 여러 데이터셋과 페이지로 들어온다. 한 번에 호출하는 범위와 버전을 매기는 기준이 다르다.
검토 판단SnapshotSource.collect(routeId, now) 하나는 GBIS 위치 수집 경계로는 쓸 수 있지만, 모든 공급자의 기준정보 수집을 대표하는 공통 인터페이스로 쓰기에는 좁다. 고정 costPerCall도 계정·환경별 호출 정책과 분리해야 한다.
권장안호출 시도와 결과를 먼저 저장하는 CollectionAttempt를 두고, 실시간 관측 소스와 기준정보 소스를 나눈다. 모든 외부 식별자는 SourceKey(source, namespace, rawValue)로 한정한다.
현재 7개 역할이 요구하는 모델 계약
다섯 운영 후보는 같은 만석 사건을 예측하지만 입력과 학습 상태가 다르다. 보정층은 기본 모델의 확률을 다시 조정하고, 비운영 참조는 운영 선택 대상이 아니다.
그림 4 · 모델 역할 — 같은 목록에 있어도 실행 책임은 세 갈래다
운영 후보 5같은 사건, 다른 계산구간 검열 · 상호작용 로지스틱 · GAM · 경험 베이즈 · 계층 로지스틱
보정층 1기본 확률 뒤에 적용기본 모델 산출물과 이전 날짜 예측·라벨이 있어야 동작
비운영 참조 1복잡도 상한 비교같은 평가 규격으로 보되 자동으로 운영 발행하지 않음
등록된 모델과 실제 운영 중인 모델은 다른 상태다. 2026-08-15 기준 평가 산출물은 일곱 역할 모두 잠정이며, 채택된 운영 모델은 없다.
현재 제안: estimate(stopOrder, timeBand, CellRisk) → ChanceState 실제 평가 입력: 노선 · 정류장 순번 · 연속 시각 · 출근/퇴근/그 외 · 평일/주말 권장 학습: 점·구간 근거를 가진 TrainingDataset → Trainer → ModelArtifact 권장 예측: 노선 버전·정류장·기준 시각·특징 고정본을 가진 PredictionPoint + 불러온 ModelArtifact → Estimated(pFull) | NotEstimated(reason) 권장 보정: 기본 예측·기본 모델 파일 참조 + CalibratorArtifact → 보정된 pFull
설계 v3의 TimeBand는 출근과 그 외만 구분해 현재의 퇴근 구간을 잃는다. CellRisk는 여러 수준의 집계, 연속 시각, 평일·주말, 구간 근거, 기본 모델 예측 가운데 어느 것도 공통으로 대신할 수 없다.
현재 노선 특징은 3330이면 1, 그 외이면 0이므로 미등록 노선은 1650과 같은 값으로 접힌다. 또한 미등록 노선은 임시 정류장 범위를 만들고, 범위 밖 순번은 0~1 사이로 잘라 계산한다. 이 동작들을 정식 지원 규칙으로 둘지 미추정으로 막을지 정하고, 노선 개편은 새 축 버전으로 분리해야 한다.
노선·정류장·시간 셀의 적은 표본을 전역·노선·노선×시간·노선×정류장 평균 쪽으로 단계적으로 당긴다.
시간·라벨
학습 마감 전 확정된 통과 라벨만 집계한다. 빈 셀의 상위 평균 사용은 결측 대입과 다른 통계 규칙이다.
버전
각 수준의 양성·전체 수, 사전분포, 축소 강도, 학습 마감을 한 산출물로 저장한다.
실패·변경
현재 선언 파일은 route_stop_time → route_stop → route_time → route → global 순서를 적었지만 코드는 이를 읽지 않는다. 실제 코드는 전역 → 노선 → 노선×시간·노선×정류장 평균 → 세부 셀의 고정 계층으로 계산한다. 선언과 구현을 하나의 검증 가능한 계약으로 맞춰야 한다.
노선, 정규화 정류장 위치, 연속 시각, 시간대, 평일·주말을 얕은 트리 묶음으로 계산한다.
시간·라벨
다른 후보와 같은 순방향 평가 자료를 쓰지만, 운영 발행 경로에는 들어가지 않는다.
버전
특징 순서, 정류장 범위, 트리 파일, 난수 초기값과 학습 마감을 함께 고정한다.
실패·변경
학습 라벨이 한 종류뿐이면 트리 대신 Beta(0.5, 0.5) 평활 상수확률을 쓴다. 현재 노선 특징은 3330과 그 외 둘로만 나뉘므로 새 노선도 1650과 같은 값이 되며, 정류장 축은 GAM과 같은 임시 범위·0~1 절단 규칙을 쓴다. 이 참조 모델을 운영 후보로 바꾸려면 이 대체 규칙들부터 다시 설계해야 한다.
확인한 사실GAM과 비운영 참조는 연속 시각이 필요하고, 비운영 참조는 평일·주말도 입력으로 쓴다. 보정층은 기본 확률과 기본 산출물 참조가 필요하다.
검토 판단현재 ChanceModel 서명은 7개 전부의 전체 계약을 표현하지 못한다. 특히 GAM, 비운영 참조, 보정층은 입력 모양부터 맞지 않는다.
권장안공통 출력은 FullnessProbability로 좁히고, 입력은 모델별 특징 스냅샷을 참조하게 한다. 보정은 별도 ProbabilityCalibrator로 조합한다.
모델 출력은 만석확률 p_full로 고정한다
현재 평가 모델이 계산하는 값은 목표 정류장 출발 뒤 만석확률 p_full이다. 도메인 안에서는 0과 1 사이의 확률값과 미추정 사유를 보존하고, 화면용 이름·퍼센트·상태는 별도 표현 경계에서 정한다.
그림 5 · 모델 출력 경계 — 계산 결과와 후속 표현을 분리한다
FullRiskForecastEstimated(p_full) 또는 Unavailable(reason)
→
도메인에서 보존0 ≤ p_full ≤ 1 · 모델 발행본 · 특징 스냅샷 · 판단 시각
수학적 여집합1 − p_full은 같은 사건의 비만석확률이다. 실제 탑승확률이라고 단정하지 않는다.
표현 경계에서 설계화면 표시 비율·상태·서비스 응답
설계 v3의 percent(화면 표시 비율)가 만석과 비만석 중 무엇을 뜻하는지 먼저 고정한다. 표시 요구가 모델의 기본 출력을 바꾸게 하지 않는다.
확인한 사실: 설계 v3는 ChanceState를 percent(표시 비율) 또는 reason(미추정 사유)으로 발행한다. 그러나 응답만 보고 어떤 사건을 예측했는지, 어떤 자료·특징·모델 파일을 썼는지 거슬러 확인할 수 없다.
검토 판단: 모델 결과를 하나의 정규화된 만석 위험 예보로 먼저 발행하는 방향은 타당하다. 단, 이 결과를 어떤 사용자 표현으로 바꿀지는 이번 도메인 검토의 근거가 아니다.
권장안:FullRiskForecast에 예측 대상인 노선 버전·정류장·기준 시각, p_full | UnavailableReason, 실제 ActiveModelRelease, 특징·자료 참조를 둔다.
기술 상세 · JPA 엔티티 0의 정확한 뜻
조회 패키지 안에 영속 JPA 엔티티를 선언하지 않는 선택은 가능하다. 설계 원문의 JPQL from RouteForecast를 쓰려면 persistence unit이 다른 패키지의 관리 엔티티 메타데이터를 읽어야 하므로 classpath와 persistence unit 결합이 생긴다.
그 결합을 허용하고 읽기 권한만 제한할지, JDBC·jOOQ·SQL 직접 조회 같은 방식으로 분리할지를 명시한다. 조회 행을 서비스 응답으로 바꾸는 규칙도 별도 계약과 테스트로 정한다.
권장 업무 경계
바뀌는 이유, 쓰기 책임, 보존 규칙이 다를 때만 객체를 분리한다.
그림 6 · 권장 도메인 — 사실, 학습 산출물, 발행 결과의 소유권을 나눈다
1 · 수집 증거CollectionAttempt · ExternalDatasetSnapshot · 비공개 원문 · 표준 관측 · RouteVersion · VehicleSpec · 비공개 VehicleIdentityLink. 공급자 결과와 시간·식별 경계를 소유한다.
2 · 모델 수명주기PassageEvidence · 라벨 정책 · 특징·데이터 고정본 · 5+1+1 정의 · 학습·평가 산출물과 운영 승인 기록을 소유한다.
3 · 만석 위험 발행ActiveModelRelease · FullRiskForecast · UnavailableReason. 승인된 만석 위험 완성본만 한 번에 공개한다.
운영·거버넌스호출 예산, 원문 보존기간, 권한·암호화, 키 회전, 감사 로그와 완성본 전환 관문은 세 경계를 가로지른다.
처음부터 각 경계를 별도 서비스로 나눌 필요는 없다. 코드 경계와 저장 소유권을 먼저 고정하고, 실제 독립 배포 필요가 생길 때 분리한다.
같은 PostgreSQL을 쓸 때의 조건
원문·식별정보, 모델링, 예보 발행을 스키마와 DB 역할로 나눈다.
한 테이블의 쓰기 주체는 하나다. 후속 서비스 계정은 발행 스키마만 읽는다.
업무 경계 사이에 JPA 관계나 연쇄 저장을 두지 않고, 다른 경계의 표를 직접 갱신하지 않는다.
새 예보 버전을 모두 쓴 뒤 현재 발행본을 가리키는 포인터를 한 트랜잭션으로 바꾼다.
후속 조회 서비스의 부하와 연결 풀이 수집·라벨 처리의 시간 경계를 흔들지 않게 격리한다.
차량 식별정보는 세 구역으로 나눈다
그림 7 · 식별 경계 — 원본 ID, 내부 연결값, 공개 참조는 서로 다른 값이다
정책 충돌GBIS 보존 기준 통일현재 수집기의 원문 대조와 호환성 명세의 식별자 HMAC·원문 폐기 방침 중 하나를 정하고, 수집기·명세·기존 자료를 함께 맞춘다.
내부 연결GGDream 번호판 폐기PLATE_NO·AUTOMB_NO는 HMAC 입력 뒤 즉시 버린다. AUTOMB_ID·VEH_ID는 별도 이름공간에서 검증된 대응표로만 잇는다.
후속 공개 조회본차량 원본값 제외도메인 확정 뒤 필요한 최소 필드만 새 계약으로 정한다. 내부 장기 연결값을 전달하지 않는다.
번호판 원본은 정규화·학습 계층으로 넘기지 않는다. GBIS 보존 정책의 충돌은 도입 전에 해소하고, 경기데이터드림 번호판은 현재 호환성 명세대로 폐기한다. 해시는 익명화 보증이 아니며, 반복 관측을 잇는 가명값에는 목적·키 수명·접근권한·보존기간이 필요하다.
모델 파일과 활성 발행본을 구분한다
공개 확률 하나를 재현하려면 모델 이름만으로 부족하다. 어떤 원자료 범위와 라벨·특징 규격으로 학습했고, 어떤 평가와 선택을 거쳐 어느 채널에서 활성화됐는지 이어져야 한다.
그림 8 · 한 예측의 계보 — 숫자에서 원자료와 결정까지 거슬러 갈 수 있어야 한다
데이터 고정본원문 범위·정규화 버전·정확한 관측·사건 목록
라벨·특징LabelPolicy · FeatureSpec · 예측 시점 정보 상한
학습 실행코드·파라미터·난수 초기값·환경·학습 마감과 실제 산출물 해시
평가 실행같은 사건·라벨·분할·평가 구간에서 만든 지표와 상태
선택 결정운영 후보만 대상으로 한 승인·보류·기각 기록
모델 발행본어느 노선·채널에서 어떤 산출물을 쓰는지 정한 불변 결정
만석 위험 예보실제 사용한 발행본과 특징을 참조한 p_full 또는 미추정
현재 공개 계열현재 공개 결과에는 현재 수집 자료와 그 파생물만 입력으로 쓴다.
내부 연구 계열과거 자료·프로토타입·탐색 결과를 보존하되 공개 평가의 실행 입력으로 쓰지 않는다.
내부 연구 자료를 현재 수집 자료를 바탕으로 한 공개 평가의 입력으로 연결하지 않는다
확인한 사실: 현재 평가 결과는 데이터·평가 규격·구간·모델 버전을 기록하지만, 학습된 계수·트리·보정기 파일과 운영 활성 상태는 아직 없다.
검토 판단: 한 번에 활성 모델 하나만 쓰는 운영 방침은 가능하다. 그러나 빌드 설정 한 칸만으로는 과거 결과 재현, 선택 근거, 되돌릴 대상을 설명할 수 없다.
권장안: 불변 ModelArtifact와 불변 ModelRelease, 현재 발행본을 가리키는 작은 포인터를 둔다. 이것은 실행 중 임의 모델 교체를 뜻하지 않는다. 프로세스가 시작할 때 승인된 하나의 발행본만 읽도록 해도 된다.
앞으로 바뀌는 항목별 영향 범위
변경은 해당 소유 경계 안에서 끝나야 하며, 과거 결과의 의미도 유지돼야 한다.
그림 9 · 변경 영향 지도 — 권장 경계가 동시 수정을 줄이는 방식
새 후보 모델모델 구현 + 특징 요구 + 불변 계약을 등록한다. 과거 평가 파일은 고치지 않는다.
새 입력 특징특징 규격과 추출기, 사용하는 모델 계약만 새 버전으로 만든다.
새 공공 API공급자 변환기와 키 매핑을 추가한다. 모델 계약은 그대로 둔다.
노선 개편새 RouteVersion을 발효한다. 과거 관측을 현재 순번으로 다시 연결하지 않는다.
평가 구간 변경평일·주말·출근·퇴근 정의를 새 구간 규격으로 발행한다. 과거 지표와 한 계열로 합치지 않는다.
새 서비스 응답도메인 확정 뒤 표현 계약을 추가한다. 새 예측 의미가 필요할 때만 모델 출력 계약의 새 버전을 만든다.
모델을 추가해도 기존 모델은 바꾸지 않는다. 공급자가 바뀌어도 모델은 유지하고, 화면 요구가 바뀌어도 원문 관측은 고치지 않는다.
미래 변경이 설계 v3와 권장 경계에 미치는 영향 및 과거 재현 조건
변경
설계 v3 그대로
권장 경계 적용 뒤
과거 재현 조건
GAM 입력에 새 시간 특징
ChanceModel, 호출부, 예보 생성부를 함께 수정
새 FeatureSpec과 GAM 산출물만 추가
이전 특징 스냅샷 보존
보정 방식 교체
독립 모델인지 장식자인지 불명확
기본 산출물 + 보정 산출물의 새 조합
적용·미적용 상태와 두 해시 보존
GBIS 응답 키·코드 변경
Snapshot.from과 후속 처리의 의미가 함께 흔들림
해당 변환기와 계약 검증용 고정 예제만 수정
원문·변환기 버전 보존
세 번째 노선·새 도시
상수·시간 규칙·마스터가 코드로 퍼질 수 있음
도시 정책·노선 버전·공급자 매핑을 데이터로 등록
유효기간 있는 기준정보
같은 모델 여러 버전
빌드별 단일 문자열로만 구분
산출물은 불변, 범위별 활성 포인터만 변경
예측마다 실제 발행본 참조
전면 재작성 없이 옮기는 순서
현재의 원문 무결성 검사, 순방향 평가, 고정 평가 구간, 완성된 정적 사이트만 한 번에 교체하는 발행 방식은 유지한다. 새 계약을 옆에 추가하고 같은 자료에서 결과를 대조한 뒤 읽기 경로를 바꾼다.
그림 10 · 이행 순서 — 계약 고정, 이중 기록, 대조, 발행 전환, 정리
사건과 출력 계약 고정
예측 대상을 출발 뒤 만석 사건으로 고정한다. 차량이 있는 정상 응답이 아니면 관측 연결을 끊고, stateCd·인접 응답·회차·KST 날짜·90초 초과 규칙과 p_full 의미를 테스트로 맞춘다.
버전 개념 추가
CollectionOutcome, RouteVersion, FeatureSpec, DatasetSnapshot, ModelArtifact를 기존 경로 옆에 추가한다.
같은 원문에서 이중 생성
기존 수집 행과 새 표준 관측·라벨·특징을 함께 만들고 행·사건·결과를 전건 대조한다. 과거 행을 덮어쓰지 않는다.
평가와 예보 발행 전환
7개 역할을 새 계약으로 평가하고, 승인된 발행본만 FullRiskForecast 생성 경로에 연결한다.
권한·보존·기존 경로 정리
발행 자료 조회 전용 권한, 원문 보존 기간, 가명 키 회전, 감사 로그와 되돌릴 수 있는 기간을 검증한 뒤 중복 경로를 제거한다.
관측이 없던 과거 구간을 복원된 것처럼 채우거나, 과거 관측을 최신 노선 순번에 다시 연결하지 않는다. 원문이 없는 범위는 복구했다고 표시하지 않는다.
도입 전 완료 조건
모델의 목표 사건, p_full, 미추정 사유가 문서와 계약 테스트에서 일치한다.
정상 차량 있음·정상 차량 없음·실패가 저장과 집계에서 끝까지 구분된다.
점·구간 라벨은 stateCd, 인접 응답, 회차, KST 날짜와 90초 초과 규칙을 보존한다. 차량이 있는 정상 응답이 아니면 관측 연결을 끊는다.
7개 역할이 모델별 특징과 실제 산출물 참조로 재현되며, 보정층과 비운영 참조가 운영 후보와 섞이지 않는다.
한 예측에서 데이터 고정본·라벨·특징·학습·평가·선택·발행본을 거슬러 확인할 수 있다.
원본 차량 값은 비공개 구역에만 있고, 발행 조회 역할은 읽을 수 없으며, 보존·파기·키 회전이 검증된다.
노선·정류장 기준정보가 공급자와 유효기간별 버전으로 남아 과거 순번 의미가 바뀌지 않는다.
도메인 확정 뒤 새 서비스 스키마와 API를 설계한다. 아직 확정하지 않은 화면 응답을 근거로 도메인 객체를 미리 고정하지 않는다.
이 결론은 2026-08-15에 확인한 설계 v3, 현재 평가 코드·산출물과 공공 API 명세에 한정한다. 설계 v3는 구현 완료 증거가 아니라 제안서로 읽었다. 이 페이지는 법적 개인정보 판단이나 특정 DB·프레임워크 선택을 확정하지 않는다. 모델·공공 API·라벨 정책이 바뀌면 관련 판정을 새 버전으로 다시 검토해야 한다.