세션 자식의 변경 행 저장 — D14
관련 이슈: #1533. 목적 release는 release/v0.18.0이다. 앱 PR #1551 · 576dae9b로 release 반영을 확인했다. Production 미배포이며 검증·비용은 작업 기록에 남긴다.
세션 메모만 바꾸거나 같은 내용을 새로 저장하면 종목·세부 종목·세트·세부 세트에 물리 쓰기를 하지 않는다. 무게 한 칸을 수정하면 해당 세부 세트만 바꾸고, 나머지 원본 ID·출처와 물리 행은 보존한다.
저장 계약
인증·기대 owner·revision·mutation 해시·자식 ID 소속 검사와 세션 잠금은 기존 v5 엔진의 책임이다. 변경 행 비교는 이 관문을 통과한 트랜잭션 안에서만 실행한다. 같은 mutation 재전송은 기존 영수증을 재사용한다. 동일 내용의 새 논리 저장은 기존처럼 revision과 영수증을 만들며, 완료 저장은 통계 요청 세대를 1 올린다. 계획 저장의 세대는 0이고 계획→완료 전환은 완료 저장 규칙을 따른다.
write_session_children_v5는 입력에서 빠진 자식을 세부 세트→세트→세부 종목→종목 순서로 삭제하고, 신규 행은 기존 INSERT 경로로 만든다. 기존 행은 테이블의 typed row에 후보를 담아 IS DISTINCT FROM으로 비교한다. 요청 JSON 문자열이나 해시는 행 변화의 대용이 아니다. full payload 읽기·검증 비용은 남는다.
실제 저장값 비교
| 대상 | 비교와 보존 규칙 |
|---|---|
| 종목·세트 | 위치·이름/세트 종류가 같은 행은 UPDATE하지 않는다. 실제 이동할 행을 먼저 비운 뒤 신규 행과 최종 위치를 저장한다. 임시 위치는 기존 위치와 요청 위치 모두를 피하는 양의 정수다. |
| 세부 종목 | note의 제목·review·본문을 구분한다. 종목의 계수·배율·기록 항목·상세 JSON은 기존 누락/null 의미, 카탈로그 기본값, 스냅샷 규칙으로 비교한다. |
| 세부 세트 | 테이블 숫자 정밀도를 적용한 뒤 단위·완료 반복수·통계 투영까지 비교한다. normalize_exercise_set_load_unit_core와 project_exercise_set_part_values_v1_core는 기존 트리거와 비교 경로가 같은 계산을 사용하게 한다. |
| 부모 변경의 파생값 | 체중·체중 계수·무게 배율·기록 항목이 바뀌면 실제 투영값이 다른 자식만 다시 계산해 저장한다. 숨겨진 입력 원본을 지우지 않는다. |
UPDATE의 열 목록은 기존 경로대로 유지한다. 특히 세부 세트 raw_payload는 단위 트리거의 결과이며 writer가 직접 SET하지 않는다. UPDATE OF 트리거 발화 의미와 canonical kg override, lb 출처의 보존 규칙을 바꾸지 않는다. 보호 트리거·이력을 비활성화하거나 데이터 컬럼을 추가하지 않는다.
원본과 검증
실제 원본 수정·삭제는 기존 보호 트리거가 이전 행과 행위자 이력을 남긴다. 값이 같은 저장과 순서가 같은 행의 불필요한 임시 위치 이력은 만들지 않는다. 재정렬에 필요한 임시 이동과 최종 위치의 이력은 유지한다. 인입 세션의 읽기 전용 정책과 소유자 복원 계약은 바뀌지 않는다.
scripts/performance/probe/session-write-delta.mjs는 격리 DB에서 트랜잭션을 롤백하는 고정 fixture다. 네 자식 테이블의 실제 I/U/D와 트리거 비용·WAL을 기록한다. tests/db/sessionWriteDelta.test.mjs는 변경 의도로 정한 행 ID 목록, 무관한 행의 전체 JSON·ctid, 원본 출처, 정규화 결과, 이력과 영수증 세대를 확인한다. 기존 성공 경로는 pre-D14 writer와 최종 값을 비교하며, 앞 삽입·큰 위치값의 기존 실패는 별도 회귀 조건으로 남긴다.
기기·Production 지연 개선율을 이 격리 fixture로 주장하지 않는다. R01/G05는 유지된 저장·영수증 계약을, R04는 전체 비용을, R05는 전체 release의 최신 populated upgrade·운영 전환을 이어받는다.
관련 정본: 세션 모델, 완료 기록 쓰기 파이프라인, 사용자 사실 불변.