Skip to content

Commit 47dde70

Browse files
committed
feat: add storage migration rules and guidelines for project data changes
1 parent e6a2a1a commit 47dde70

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
---
2+
description: Enforce storage migration scripts when project save format changes
3+
alwaysApply: true
4+
---
5+
6+
# Storage Migration
7+
8+
When a code change modifies the persisted project data shape (fields in `TProject`, `TScene`, `TProjectMetadata`, `TProjectSettings`, `TimelineTrack`, or `TimelineElement` types), you **must** also implement a storage migration so existing saved projects upgrade automatically.
9+
10+
## When a Migration is Required
11+
12+
- Adding, removing, or renaming a field on any persisted type
13+
- Changing the semantics or default of an existing persisted field
14+
- Restructuring nested data (e.g. moving a field from root to `metadata`)
15+
16+
## Checklist
17+
18+
1. **Bump version** — increment `CURRENT_PROJECT_VERSION` in `services/storage/migrations/index.ts`
19+
2. **Transformer** — create `transformers/vN-to-vM.ts` with pure transform logic
20+
3. **Migration class** — create `vN-to-vM.ts` extending `StorageMigration` (`from = N`, `to = M`)
21+
4. **Register** — add the new migration instance to the `migrations` array in `index.ts`
22+
5. **Tests** — add `__tests__/vN-to-vM.test.ts` with fixture data covering normal, edge-case, and already-migrated scenarios
23+
24+
## File Structure
25+
26+
```
27+
services/storage/migrations/
28+
├── index.ts # CURRENT_PROJECT_VERSION + migrations array
29+
├── base.ts # StorageMigration abstract class
30+
├── runner.ts # Migration executor
31+
├── vN-to-vM.ts # Migration class
32+
├── transformers/
33+
│ ├── vN-to-vM.ts # Pure transform function
34+
│ ├── types.ts # ProjectRecord, MigrationResult
35+
│ └── utils.ts # getProjectId, isRecord, etc.
36+
└── __tests__/
37+
├── vN-to-vM.test.ts
38+
└── fixtures/
39+
└── vN.ts # Fixture data for version N
40+
```
41+
42+
## Migration Pattern
43+
44+
```typescript
45+
// transformers/vN-to-vM.ts
46+
export function transformProjectVNToVM({
47+
project,
48+
}: {
49+
project: ProjectRecord;
50+
}): MigrationResult<ProjectRecord> {
51+
const projectId = getProjectId({ project });
52+
if (!projectId) {
53+
return { project, skipped: true, reason: "no project id" };
54+
}
55+
56+
if (isAlreadyMigrated({ project })) {
57+
return { project, skipped: true, reason: "already vM" };
58+
}
59+
60+
const migratedProject = {
61+
...project,
62+
/* apply changes */
63+
version: M,
64+
};
65+
66+
return { project: migratedProject, skipped: false };
67+
}
68+
```
69+
70+
## Key Rules
71+
72+
- Transformers must be **pure functions** — no side-effects, no DB access
73+
- Always guard with an `isAlreadyMigrated` check so re-runs are safe
74+
- Never delete data without first copying it to the new location
75+
- Keep each migration small and single-purpose

0 commit comments

Comments
 (0)