Skip to content

feat(storage): add the motion score column (M1, schema v19) - #443

Merged
BerryUIKI merged 3 commits into
devfrom
feat/motion-score-schema
Nov 12, 2026
Merged

BerryUIKI merged 3 commits into
devfrom
feat/motion-score-schema

Conversation

@BerryUIKI

Copy link
Copy Markdown
Owner

First of the four packages in docs/MOTION_SCORE_DESIGN.md. This one is schema and plumbing only — nothing computes a score yet, so every existing row reads back as NULL.

What landed

v19 migration — a nullable files.motion_score REAL with idx_files_motion_score. Appended to MIGRATIONS; the eighteen applied entries are untouched and LATEST_VERSION follows the array length to 19.

Domain and TS mirror — ImageFile.motion_score: Option<f64> with #[serde(default)] so older payloads still deserialize, and the matching optional field in src/types.ts.

Read/write paths — both upsert variants carry the column, map_row reads it at index 9 (shifting is_favorite, is_nsfw, stack_id, stack_order), the seven SELECT lists that feed map_row insert it in the same position, and the two total_count readers move from index 13 to 14.

Upsert preservation — coalesce(excluded.motion_score, files.motion_score). A rescan re-reads container metadata and passes no score, so without this a scan would silently wipe a measurement.

Migration export — motion_score added to both MySQL and PostgreSQL DDL, the row reader, and the batched INSERT. The exporter builds its files table column by column, so a column missing here would be dropped on a real cross-database migration.

Why a column and not metadata JSON

The score is a derived measurement, not something the video container holds. Putting it in metadata would mix values the scanner writes with values the media writes, and it would force the future facet onto json_extract instead of an index.

Tests

Three new regressions:

  • v19_adds_a_nullable_indexed_motion_score — the column is nullable, the index exists, and an unmeasured row reads NULL rather than 0.
  • upsert_preserves_an_existing_motion_score — writes 42.5, rescans with None and a changed size, asserts the size updated but the score survived.
  • motion_score_exports_in_both_dialects — both DDLs carry the column, the measured value is written verbatim, and an unmeasured clip exports as NULL.

Existing coverage also holds: 49 ImageFile literals across the workspace gained the field, and the full suite passes.

Verification

  • cargo test --workspace — all green (101 storage tests, including the three new ones).
  • cargo clippy --workspace --all-targets -- -D warnings — clean.
  • cargo fmt --all -- --check — clean.
  • cargo doc -p omera-domain --no-deps — no broken-link warnings.
  • pnpm run test:stack — 356 passed, 0 failed, 2 skipped.
  • node scripts/generate-ipc-reference.mjs --check — 169 signatures verified (no IPC changes in this package).
  • node scripts/generate-release-notes.mjs --check — passes.

M2 (the scoring engine) and M4 (the facet and UI) can now proceed in parallel; M3 needs this package first.

🤖 Generated with Claude Code

BerryUIKI and others added 3 commits November 13, 2026 01:16
Groundwork for the last Milestone 15 facet. This package only adds the
column and threads it through the read and write paths; nothing computes
a score yet, so every existing row reads back as NULL.

Mirrors the aesthetic_score precedent rather than living in the metadata
JSON: the motion score is a derived measurement, not a value the video
container holds, and a real column keeps the future facet predicate on an
index instead of json_extract.

The upsert uses coalesce(excluded.motion_score, files.motion_score) for
the same reason the other derived fields do -- a rescan re-reads container
metadata and passes no score, which must not wipe a measurement that has
already been written.

The seven SELECT lists that feed map_row gain the column in the same
position it appears in the row mapper, and the two total_count readers
shift from index 13 to 14.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The migration exporter writes a self-contained DDL + data bundle for the
collaboration backends. Its files table is built column by column, so a
column that exists locally but not in the export would be silently
dropped on a real migration run.

Adds motion_score to both dialects' DDL, the row reader and the batched
INSERT. The value is written verbatim so a measured score survives the
cross-database move, and an unmeasured clip exports as NULL rather than 0
-- the same distinction the local schema makes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@BerryUIKI
BerryUIKI merged commit 9e6b963 into dev Nov 12, 2026
3 checks passed
@BerryUIKI
BerryUIKI deleted the feat/motion-score-schema branch November 12, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant