public ApiResponse CreateRule([FromQuery] string project, [FromQuery(Name = "app")] string appName, [FromQuery] string file, [FromBody] Newtonsoft.Json.Linq.JObject json)
        {
            try
            {
                if (!ControllerHelper.GetProjectAndApp(project, appName, out var proj, out var app, out var resp))
                {
                    return(resp);
                }

                var    type  = (RuleType)int.Parse(json["Type"].ToString());
                string value = json["Value"].ToString();


                if (file == null)
                { // DB-level
                    var ret = app.AddRule(type, value);

                    if (ret.IsSuccess)
                    {
                        SettingsInstance.SaveSettingsToFile();

                        WorkSpawner.SetRulesDirty(app);

                        return(ApiResponse.Success());
                    }
                    else
                    {
                        return(ApiResponse.ExclamationModal(ret.userErrorVal));
                    }
                }
                else
                {
                    var jsFile = app.GetJsFile(file);

                    if (jsFile == null)
                    {
                        return(ApiResponse.ExclamationModal("The specified output file was not found."));
                    }

                    var ret = jsFile.AddRule(type, value);

                    if (ret.IsSuccess)
                    {
                        SettingsInstance.SaveSettingsToFile();

                        WorkSpawner.SetRulesDirty(app, jsFile);

                        return(ApiResponse.Success());
                    }
                    else
                    {
                        return(ApiResponse.ExclamationModal(ret.userErrorVal));
                    }
                }
            }
            catch (Exception ex)
            {
                return(ApiResponse.Exception(ex));
            }
        }
        public ApiResponse UpdateRule([FromQuery] string project, [FromQuery(Name = "app")] string appName, [FromQuery] string file, [FromRoute] string ruleId, [FromBody] Newtonsoft.Json.Linq.JObject json)
        {
            try
            {
                if (!ControllerHelper.GetProjectAndApp(project, appName, out var proj, out var app, out var resp))
                {
                    return(resp);
                }

                var    type  = (RuleType)int.Parse(json["Type"].ToString());
                string value = json["Value"].ToString();

                CommonReturnValue ret;
                JsFile            jsFile = null;

                if (file == null)
                { // DB-level
                    ret = app.UpdateRule(ruleId, value);
                }
                else
                {
                    jsFile = app.GetJsFile(file);

                    // TODO: Move check and error message down to App api?
                    if (jsFile == null)
                    {
                        return(ApiResponse.ExclamationModal("The specified output file was not found."));
                    }

                    ret = jsFile.UpdateRule(ruleId, value);
                }

                if (ret.IsSuccess)
                {
                    SettingsInstance.SaveSettingsToFile();

                    if (jsFile == null)
                    {
                        WorkSpawner.SetRulesDirty(app);
                    }
                    else
                    {
                        WorkSpawner.SetRulesDirty(app, jsFile);
                    }

                    return(ApiResponse.Success());
                }
                else
                {
                    return(ApiResponse.ExclamationModal(ret.userErrorVal));
                }
            }
            catch (Exception ex)
            {
                return(ApiResponse.Exception(ex));
            }
        }
        public ApiResponse DeleteRule([FromQuery] string project, [FromQuery(Name = "app")] string appName, [FromQuery] string file, [FromRoute] string ruleId)
        {
            try
            {
                if (!ControllerHelper.GetProjectAndApp(project, appName, out var proj, out var app, out var resp))
                {
                    return(resp);
                }

                if (file == null)
                { // DB level
                    var ret = app.DeleteRule(ruleId);

                    if (ret.IsSuccess)
                    {
                        WorkSpawner.SetRulesDirty(app);
                        SettingsInstance.SaveSettingsToFile();
                        return(ApiResponse.Success());
                    }
                    else
                    {
                        return(ApiResponse.ExclamationModal(ret.userErrorVal));
                    }
                }
                else
                {
                    var jsFile = app.GetJsFile(file);

                    if (jsFile == null)
                    {
                        return(ApiResponse.ExclamationModal("The specified output file was not found."));
                    }

                    var ret = jsFile.DeleteRule(ruleId);

                    if (ret.IsSuccess)
                    {
                        WorkSpawner.SetRulesDirty(app, jsFile);
                        SettingsInstance.SaveSettingsToFile();
                        return(ApiResponse.Success());
                    }
                    else
                    {
                        return(ApiResponse.ExclamationModal(ret.userErrorVal));
                    }
                }
            }
            catch (Exception ex)
            {
                return(ApiResponse.Exception(ex));
            }
        }