Skip to content

feat(etl): port handle_user/track/playlist triggers (parity 1C)#240

Open
raymondjacobson wants to merge 1 commit intoetl/parity-1b-social-triggersfrom
etl/parity-1c-content-triggers
Open

feat(etl): port handle_user/track/playlist triggers (parity 1C)#240
raymondjacobson wants to merge 1 commit intoetl/parity-1b-social-triggersfrom
etl/parity-1c-content-triggers

Conversation

@raymondjacobson
Copy link
Copy Markdown
Contributor

Summary

Stack 1C of the trigger-port plan. Migration 0019 adds:

  • `aggregate_user.total_track_count` column (apps#0143).
  • `handle_user` — creates `aggregate_user` row on user insert. Other triggers (handle_playlist, handle_track, handle_follow) depend on this row existing.
  • `handle_track` — maintains `aggregate_track` + `aggregate_user.{track_count, total_track_count}`, plus subscriber-create / remix / remix-contest notifications. Verbatim port; fires on INSERT OR UPDATE.
  • `handle_playlist` — maintains `aggregate_playlist` + `aggregate_user.{playlist_count, album_count}`, plus subscriber-create and track-added-to-playlist notifications.

Deferred

`handle_play` — apps' trigger fires on a `plays` table matching apps' schema, but go-openaudio currently has only `etl_plays` (different schema). A follow-up PR will add the apps-shaped `plays` table and wire the play processor before the trigger lands.

Stripped (no reorg support per scoping)

`handle_playlist`'s `revert_blocks` lookup was removed (go-openaudio doesn't track reverts). With `old_row` treated as null:

  • INSERT of public playlist (`is_private=false`) → delta=1 ✓
  • INSERT of private playlist → delta=0 ✓

The private→public publish path in apps fires the trigger via INSERT of a new `is_current` row; go-openaudio's `playlist_update.go` does in-place UPDATE so this trigger won't fire on publish today. That's tracked in Stack 4A (`publish_scheduled_releases`).

Stack context

Stacked on #239 (1B — social triggers).

Test plan

Six DB-backed tests in content_triggers_test.go:

  • `TestTrigger_HandleTrack_InitializesAggregates` — aggregate_track row + user track counts increment
  • `TestTrigger_HandleTrack_UnlistedDoesNotIncrementTrackCount` — unlisted track only ticks total_track_count
  • `TestTrigger_HandleTrack_RemixCreatesNotification` — remix-of triggers a parent-owner notification
  • `TestTrigger_HandlePlaylist_InitializesAggregates` — aggregate_playlist row + user playlist_count increments
  • `TestTrigger_HandlePlaylist_AlbumIncrementsAlbumCount` — `is_album=true` ticks album_count instead
  • `TestTrigger_HandlePlaylist_PrivateDoesNotIncrement` — `is_private=true` suppresses delta
  • All 6 trigger tests + 1B's 6 tests pass together (no regressions)

🤖 Generated with Claude Code

Stack 1C of the trigger-port plan. Migration 0019 adds:

- aggregate_user.total_track_count column (apps#0143).
- handle_user: creates aggregate_user row on user insert. Other triggers
  depend on this row existing.
- handle_track: maintains aggregate_track + aggregate_user.{track_count,
  total_track_count}, plus subscriber-create / remix / remix-contest
  notifications. Verbatim port; fires on INSERT OR UPDATE.
- handle_playlist: maintains aggregate_playlist + aggregate_user.{playlist_count,
  album_count}, plus subscriber-create and track-added-to-playlist
  notifications.

handle_play deferred to a follow-up: apps' trigger fires on a `plays` table
matching apps' schema, but go-openaudio currently has only `etl_plays` (its
own staging schema). A separate PR will add the apps-shaped `plays` table
and wire the play processor before the trigger lands.

handle_playlist's `revert_blocks` lookup was stripped: go-openaudio doesn't
track reverts (chain doesn't reorg), so old_row is treated as null. On
INSERT this gives correct delta semantics. The private→public publish path
in apps fires the trigger via INSERT of a new is_current row; go-openaudio's
playlist_update.go does in-place UPDATE so this trigger won't fire on
publish today. That's tracked in Stack 4A (publish_scheduled_releases).

Six DB-backed tests cover aggregate_track init, public/unlisted track count
behavior, remix notification, playlist aggregate init, album_count
increment, and is_private suppression.

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