From d55d2583a71ae35fa8d0d1bfbec975e67e66aafa Mon Sep 17 00:00:00 2001 From: cashmere Date: Mon, 27 Jul 2026 01:21:20 +0200 Subject: feat: git-like project versioning (v1) Linear per-project history per notes/project-versioning.md: named checkpoints (thumbnail via renderer.captureFrame) plus auto-checkpoints on save (60s throttle, ring of 20, named never rotate). Restore writes a safety checkpoint first, then swaps the document outside undo/redo. Media assets referenced by any version are pinned against deletion. Migration v31-v32 stamps the schema; the version store lives in its own IDB database with an in-memory fallback for tests. Versions popover in the editor header for jump/rename/delete. 12 new tests. --- apps/web/src/commands/media/remove-media-asset.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'apps/web/src/commands/media') diff --git a/apps/web/src/commands/media/remove-media-asset.ts b/apps/web/src/commands/media/remove-media-asset.ts index 38ff79fe..ab267f36 100644 --- a/apps/web/src/commands/media/remove-media-asset.ts +++ b/apps/web/src/commands/media/remove-media-asset.ts @@ -1,5 +1,6 @@ import { Command, type CommandResult } from "@/commands/base-command"; import { EditorCore } from "@/core"; +import { toast } from "sonner"; import type { MediaAsset } from "@/media/types"; import { buildWaveformSourceKey } from "@/media/waveform-summary"; import { storageService } from "@/services/storage/service"; @@ -30,6 +31,21 @@ export class RemoveMediaAssetCommand extends Command { execute(): CommandResult | undefined { const editor = EditorCore.getInstance(); + + // Media pinning: a stored project version may still reference this + // asset; deleting it would break restores (notes/project-versioning.md). + if ( + editor.versions.isMediaIdPinned({ + projectId: this.projectId, + mediaId: this.assetId, + }) + ) { + toast.error("Media is used in a saved version", { + description: "Delete the checkpoints that reference it first.", + }); + return; + } + const assets = editor.media.getAssets(); this.savedAssets = [...assets]; -- cgit v1.3.1