private async Task <IActionResult> PostGoodPractices(string projectId, int version, string hubId, string rvt, string guid)
        {
            // basic input validation
            string activityName = "cyBnhhxpfsbhGC1jv4CdyDSLwj912JA4.UpdateRVTParamActivity+dev";
            //var projectId = (string)rvt.projectId;
            //var version = (int)rvt.version;

            // OAuth token
            dynamic oauth = await OAuthController.GetInternalAsync();

            // upload file to OSS Bucket
            // 1. ensure bucket existis
            string     bucketKey = NickName.ToLower() + "-designautomation";
            BucketsApi buckets   = new BucketsApi();

            buckets.Configuration.AccessToken = oauth.access_token;
            try
            {
                PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey, null, PostBucketsPayload.PolicyKeyEnum.Transient);
                await buckets.CreateBucketAsync(bucketPayload, "US");
            }
            catch { };

            // prepare workitem arguments
            // 1. input file
            //var guid = (string)rvt.guid;
            var rvtName = rvt;//(string)rvt.rvtName;
            XrefTreeArgument inputFileArgument = new XrefTreeArgument()
            {
                Url       = $"https://developer.api.autodesk.com/oss/v2/buckets/wip.dm.prod/objects/{guid}",
                LocalName = "myzip",
                PathInZip = rvtName,
                Headers   = new Dictionary <string, string>()
                {
                    { "Authorization", "Bearer " + oauth.access_token }
                }
            };

            // 2. input json
            dynamic inputJson = new JObject();

            inputJson.HubId     = hubId;
            inputJson.ProjectId = projectId;
            inputJson.Version   = version;
            var inputJsonArgument = new XrefTreeArgument()
            {
                Url = "data:application/json, " + ((JObject)inputJson).ToString(Formatting.None).Replace("\"", "'")
            };

            // 3. output file
            string           outputFileNameOSS  = string.Format("{0}_output_{1}", DateTime.Now.ToString("yyyyMMddhhmmss"), Path.GetFileName("OutputFile.json")); // avoid overriding
            XrefTreeArgument outputFileArgument = new XrefTreeArgument()
            {
                Url     = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, outputFileNameOSS),
                Verb    = Verb.Put,
                Headers = new Dictionary <string, string>()
                {
                    { "Authorization", "Bearer " + oauth.access_token }
                }
            };

            // prepare & submit workitem
            // the callback contains the connectionId (used to identify the client) and the outputFileName of this workitem
            string   callbackUrl  = string.Format("{0}/api/forge/callback/mongo?id={1}&outputFileName={2}", Credentials.GetAppSetting("FORGE_WEBHOOK_URL"), "", outputFileNameOSS);
            WorkItem workItemSpec = new WorkItem()
            {
                ActivityId = activityName,
                Arguments  = new Dictionary <string, IArgument>()
                {
                    { "inputFile", inputFileArgument },
                    { "inputJson", inputJsonArgument },
                    { "outputFile", outputFileArgument },
                    { "onComplete", new XrefTreeArgument {
                          Verb = Verb.Post, Url = callbackUrl
                      } }
                }
            };

            WorkItemStatus workItemStatus = await _designAutomation.CreateWorkItemAsync(workItemSpec);

            return(Ok(new { WorkItemId = workItemStatus.Id }));
        }