package playback import ( "context" "errors" "github.com/google/uuid" "github.com/jackc/pgx/v5" "pipu/api/internal/api/gen" "pipu/api/internal/platform/apperr" ) // Repeated sharing preserves the existing URL. After revocation a fresh UUID is allocated. func (st *Store) sharePlaylist(ctx context.Context, owner, id uuid.UUID) (uuid.UUID, error) { var shareID uuid.UUID err := st.pool.QueryRow(ctx, `UPDATE playlists SET share_id=COALESCE(share_id,$3) WHERE id=$1 AND user_id=$2 RETURNING share_id`, id, owner, uuid.New()).Scan(&shareID) if errors.Is(err, pgx.ErrNoRows) { return uuid.Nil, apperr.NotFound("playlist.not_found", "playlist not found") } return shareID, err } func (st *Store) revokePlaylistShare(ctx context.Context, owner, id uuid.UUID) error { result, err := st.pool.Exec(ctx, `UPDATE playlists SET share_id=NULL WHERE id=$1 AND user_id=$2`, id, owner) if err != nil { return err } if result.RowsAffected() == 0 { return apperr.NotFound("playlist.not_found", "playlist not found") } return nil } func (h *Handler) SharePlaylist(ctx context.Context, req gen.SharePlaylistRequestObject) (gen.SharePlaylistResponseObject, error) { user, err := principal(ctx) if err != nil { return nil, err } shareID, err := h.store.sharePlaylist(ctx, user.UserID, req.Id) if err != nil { return nil, err } return gen.SharePlaylist200JSONResponse{ShareId: shareID}, nil } func (h *Handler) RevokePlaylistShare(ctx context.Context, req gen.RevokePlaylistShareRequestObject) (gen.RevokePlaylistShareResponseObject, error) { user, err := principal(ctx) if err != nil { return nil, err } if err = h.store.revokePlaylistShare(ctx, user.UserID, req.Id); err != nil { return nil, err } return gen.RevokePlaylistShare204Response{}, nil } func (h *Handler) GetSharedPlaylist(ctx context.Context, req gen.GetSharedPlaylistRequestObject) (gen.GetSharedPlaylistResponseObject, error) { user, err := principal(ctx) if err != nil { return nil, err } p, err := h.readPlaylist(ctx, user.UserID, req.ShareId, true) if err != nil { return nil, err } return gen.GetSharedPlaylist200JSONResponse(p), nil }