Skip to content

feat(etl): enforce immutable field set on track/playlist update (parity 2D)#245

Open
raymondjacobson wants to merge 1 commit intoetl/parity-2c-pending-routesfrom
etl/parity-2d-immutable-fields
Open

feat(etl): enforce immutable field set on track/playlist update (parity 2D)#245
raymondjacobson wants to merge 1 commit intoetl/parity-2c-pending-routesfrom
etl/parity-2d-immutable-fields

Conversation

@raymondjacobson
Copy link
Copy Markdown
Contributor

Summary

Stack 2D. Adds apps' `immutable_fields` / `immutable_track_fields` / `immutable_playlist_fields` sets and applies them in track_update + playlist_update before merging metadata. Without this, a malicious or buggy client could rewrite `owner_id`, `track_id`, `is_album`, etc. via an Update.

Immutable on Update (mirrors apps' metadata.py):

  • Common: `blocknumber`, `blockhash`, `txhash`, `created_at`, `updated_at`, `slot`, `metadata_multihash`, `is_current`, `is_delete`
  • Tracks add: `track_id`, `owner_id`, `is_available`, `ddex_app`
  • Playlists add: `playlist_id`, `playlist_owner_id`, `is_album`, `ddex_app`

`stripImmutableFields()` deletes these keys from `params.Metadata` before `mergeTrackFromMetadata` / `mergePlaylistFromMetadata` runs.

Stack context

Stacked on #244 (2C — same-block route audit).

Test plan

  • `TestStripImmutableFields_RemovesKeys` — unit test for the helper.
  • `TestTrackUpdate_IgnoresImmutableMetadataKeys` — Update trying to set `owner_id` to a different user leaves it unchanged; `title` (mutable) still updates.
  • `TestPlaylistUpdate_IgnoresImmutableIsAlbum` — `is_album=true` in Update metadata is silently ignored after a non-album create.
  • `go build ./...` clean.

🤖 Generated with Claude Code

…ty 2D)

Stack 2D. Adds the immutable_fields / immutable_track_fields /
immutable_playlist_fields sets from
apps/packages/discovery-provider/src/tasks/metadata.py and applies them
in track_update + playlist_update before merging metadata.

Immutable on Update:
- common: blocknumber, blockhash, txhash, created_at, updated_at, slot,
  metadata_multihash, is_current, is_delete
- tracks add: track_id, owner_id, is_available, ddex_app
- playlists add: playlist_id, playlist_owner_id, is_album, ddex_app

stripImmutableFields() deletes these keys from params.Metadata in place
before mergeTrackFromMetadata / mergePlaylistFromMetadata sees them.

Tests: unit test for the strip helper; DB-backed test that an Update
trying to mutate owner_id leaves it unchanged (while title still mutates);
DB-backed test that is_album cannot be flipped after create.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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