document model versioning과 migration
사용자가 저장한 문서는 다음 버전의 앱에서도 열려야 합니다. 그래서 document schema에는 version이 필요합니다.
migration registry 코드
문서 로더는 저장된 version에서 현재 version까지 migration을 순서대로 적용합니다.
const CURRENT_VERSION = 3;
const migrations = {
1: (doc) => ({
...doc,
version: 2,
assets: doc.assets ?? {}
}),
2: (doc) => ({
...doc,
version: 3,
pages: doc.pages.map(addDefaultPageBackground)
})
};
function loadDocument(raw) {
let doc = JSON.parse(raw);
while (doc.version < CURRENT_VERSION) {
doc = migrations[doc.version](doc);
}
return validateDocument(doc);
}
migration 흐름
if (doc.version === 1) doc = migrateV1ToV2(doc);
if (doc.version === 2) doc = migrateV2ToV3(doc);
migration은 renderer가 아니라 document loader의 책임입니다.
migration 테스트를 반드시 둔다
test("v1 document is migrated to current schema", () => {
const v1 = JSON.stringify({
version: 1,
pages: [{ id: "page-1", nodes: [] }]
});
const doc = loadDocument(v1);
expect(doc.version).toBe(CURRENT_VERSION);
expect(doc.assets).toEqual({});
expect(doc.pages[0].background).toBeDefined();
});
문서 migration은 한 번 깨지면 사용자의 기존 파일을 못 여는 문제로 이어집니다. 예전 fixture 파일을 테스트에 남겨두는 것이 가장 현실적인 안전장치입니다.
오늘의 핵심
파일을 계속 열 수 있는 능력은 제품 신뢰의 핵심입니다. versioning은 나중에 붙이기 어렵습니다.