# Prototype — Test Notes

Follows the build order in `video-editor-app-plan.md`. Step 1 (bookmarks +
relink) is built and was validated on-device. Step 2 (draft/recipe model) is
built — test checklist at the bottom.

## Step 1: bookmark + relink system ✅ (device-validated)

## What's in the prototype

- **Source library** (`VideoEditor/Services/SourceLibrary.swift`) — clips are
  referenced, never copied: files via security-scoped bookmarks, Photos clips
  via PHAsset IDs. Persisted as JSON in the app's Documents folder.
- **Fingerprints** captured at import (duration, dimensions, file size,
  creation date) plus a stored thumbnail, so a broken clip can be re-found and
  visually confirmed later.
- **Relink flow** — grant a folder once, the app rescans it silently on demand,
  candidates are scored and shown with side-by-side thumbnails, a
  shorter-than-original file is flagged, and every relink is undoable
  (long-press the clip → "Undo relink").
- **Availability states** — each clip shows Available / Missing with a reason;
  stale bookmarks are transparently refreshed and re-saved.
- **Playback** — tapping play resolves the reference end-to-end, which is the
  real test that a bookmark still works.
- **Debug helper** — long-press a clip → "Simulate broken reference" to
  exercise the relink flow without touching real files.

## Running it

1. Open `VideoEditor.xcodeproj` in Xcode.
2. Select the VideoEditor target → Signing & Capabilities → pick your team
   (automatic signing).
3. Build to your iPhone. First run on device needs
   Settings → General → VPN & Device Management trust, and Developer Mode on.

## On-device test checklist (the actual point of this prototype)

Bookmark durability — external drive:
- [ ] Import a clip from a USB-C drive via "Import from Files". Play it.
- [ ] Force-quit the app, relaunch — clip still Available and plays.
- [ ] Eject the drive, refresh — clip shows Missing with a sensible reason.
- [ ] Reconnect the drive, refresh — clip recovers to Available on its own.
- [ ] **Rename** the file on the drive (on a Mac), reconnect, refresh — bookmark
      should survive (inode-based). This is the big claim to verify.
- [ ] **Move** the file to another folder on the same drive, refresh — should
      also survive.
- [ ] Restart the iPhone, relaunch — clip still resolves.

Photos references:
- [ ] Import a clip from Photos. Play it. Relaunch — still works.
- [ ] Delete the clip from Photos — shows "Photos asset no longer exists".

Relink flow (the Photos → drive scenario from the plan):
- [ ] Import a clip from Photos, then export that same video from Photos onto
      a drive folder (unmodified original).
- [ ] Delete it from Photos → clip goes Missing → tap "Locate…".
- [ ] Grant the drive folder — the exported file should appear as a match
      (strong match if the bytes were copied unmodified).
- [ ] Confirm via the thumbnail comparison. Clip becomes Available and plays.
- [ ] **Relaunch the app** — the relinked clip must still resolve. (The relink
      bookmark is created while holding the granted folder's security scope;
      this persistence across launches is the one API behavior I couldn't
      verify without a device. If it fails, the fallback is resolving relinked
      files relative to their granted folder — note it here and we'll adjust.)
- [ ] Long-press → "Undo relink" restores the old (broken) Photos reference.

## Known limits / deliberate omissions

- Drafts, timeline, and composition are step 2–3 — not in this prototype.
- Fingerprint has no content hash yet; a transcoded export (different bytes)
  scores lower and may only show as "Possible match". Fine for now — the
  thumbnail confirmation is the backstop.
- Relink scan fingerprints every video in granted folders serially; big
  folders will be slow. Optimize later if it matters.

---

# Step 2: draft/recipe model

The app now has a Drafts tab. A draft is a JSON file in Documents/Drafts —
an ordered list of `{sourceClipID, trimStart, trimEnd, mute, volume,
textOverlays}` instructions. No video data is ever stored; the editor footer
shows the actual recipe size in bytes to make the point.

What's implemented:
- Create / rename / delete drafts; **Save As New Draft** duplicates the recipe
  (context menu on a draft row, or the ••• menu inside the editor).
- Add clips from the source library (multi-select), reorder (••• → Edit or
  drag), delete, and per-clip detail editing: trim sliders bounded by the
  source's fingerprint duration, mute + volume, text overlays (auto-centered,
  font size, background flag — rendering is step 3).
- **Linear undo/redo** per editing session: structural actions (add, delete,
  reorder) are one step each; a clip-detail session counts as one step; a
  detail session with no changes costs nothing.
- Every change auto-saves the recipe JSON.
- **Graceful degradation**: a clip whose source is missing (or was deleted from
  the library) shows as a placeholder with all trims/overlays intact and still
  editable; the draft row and editor footer flag that export would be blocked.

## Step 2 test checklist

- [ ] Create a draft, add 3+ clips, trim them, reorder, add text overlays.
      Force-quit and relaunch — everything restored.
- [ ] "Save As New Draft", change trims in the copy — original untouched.
      Check Documents via Files app if curious: two small JSON files, no video.
- [ ] Undo/redo walks back add/reorder/delete and detail-edit sessions.
- [ ] Break a source (eject drive or "Simulate broken reference" in Library) —
      draft shows the orange placeholder, other clips stay editable, trims on
      the broken clip still adjustable.
- [ ] Relink the source in the Library tab — draft heals with edits intact.
- [ ] Delete a source clip from the library that a draft uses — draft keeps
      metadata, shows "Missing source".

## Deliberate omissions (step 3+)

- No preview, no export, no timeline thumbnails-strip UI — next step wires
  recipes into `AVMutableComposition`.
- Text overlay position editing (drag on preview) needs the preview surface;
  overlays default to centered for now.
- Music tracks / multi-song audio config comes with the audio-mix work.
