veza/apps/web/src/components/library
senke 8a4681643c refactor(web): migrate playlistService to orval-generated playlist client (v1.0.8 B4)
Second feature-service migration after B3 (profileService → user). Replaces
raw apiClient calls in @/features/playlists/services/playlistService.ts
with the orval-generated functions from services/generated/playlist/playlist.ts.
All 19 public function signatures preserved — no callers touched.

Functions migrated (19):
- createPlaylist           → postPlaylists
- getPlaylist              → getPlaylistsId
- getPlaylistByShareToken  → getPlaylistsSharedToken
- updatePlaylist           → putPlaylistsId
- deletePlaylist           → deletePlaylistsId
- importPlaylist           → postPlaylistsImport
- getFavorisPlaylist       → getPlaylistsFavoris
- listPlaylists            → getPlaylists (orval)
- addCollaborator          → postPlaylistsIdCollaborators
- removeCollaborator       → deletePlaylistsIdCollaboratorsUserId
- updateCollaboratorPermission → putPlaylistsIdCollaboratorsUserId
- searchPlaylists          → getPlaylistsSearch
- createShareLink          → postPlaylistsIdShare
- reorderPlaylistTracks    → putPlaylistsIdTracksReorder
- removeTrackFromPlaylist  → deletePlaylistsIdTracksTrackId
- duplicatePlaylist        → postPlaylistsIdDuplicate
- getPlaylistRecommendations → getPlaylistsRecommendations
- getCollaborators         → getPlaylistsIdCollaborators
- addTrackToPlaylist       → postPlaylistsIdTracks

Functions still on raw apiClient (endpoints lack swaggo annotations,
deferred v1.0.9):
- followPlaylist          → POST /playlists/{id}/follow
- unfollowPlaylist        → DELETE /playlists/{id}/follow
- getPlaylistFollowStatus → derives from getPlaylist (no dedicated endpoint)

Two helpers normalize envelope shapes returned by the backend:
- unwrapPayload<T>(raw)    → strips `{ data: ... }` envelope when present.
- pickPlaylist(raw)        → also unwraps `{ playlist: ... }` for single-resource
                             responses.

listPlaylists keeps its sortBy/sortOrder params in the public signature
for forward-compat, but the orval call drops them — the backend swaggo
annotation on GET /playlists (playlist_handler.go:230-242) declares only
page/limit/user_id, and the handler ignores any sort args silently. To
be revisited when the backend annotation is extended (v1.0.9).

Test file rewritten to mock the generated module
(@/services/generated/playlist/playlist) for all migrated functions.
The orval mocks delegate back to the existing apiClient mock so the 43
existing assertions on `expect(apiClient.X).toHaveBeenCalledWith(...)`
continue to pass without rewriting 800+ LOC of test bodies. Same shim
pattern as B3.

Consumer-side fix: PlaylistsView.tsx setPlaylists call cast to
`Playlist[]` (the component imports Playlist from `@/types`, while the
service exposes Playlist from `@/features/playlists/types` — they have
slightly divergent `tracks` shapes, an existing types/api drift to be
unified in B9).

Tests: 332/332 green (43 in playlistService.test.ts + 289 in adjacent
playlists tests). npm run typecheck: clean.

Bisectable: revert this commit → service returns to apiClient pattern,
PlaylistsView reverts to its untyped setPlaylists call. No interceptor
changes, no data-shape drift.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 21:07:49 +02:00
..
playlists refactor(web): migrate playlistService to orval-generated playlist client (v1.0.8 B4) 2026-04-25 21:07:49 +02:00
AutoMetadataDetectionModal.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
WatermarkSettingsModal.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00