Source: Controllers/DevController.cs

using Backend.Services;
using PublicAPI.Models;
using Dapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Backend.Extensions;
using System.Data;
using System.Xml.Linq;
using System.Diagnostics;

namespace PublicAPI.Controllers {

    [Authorize]
    [ApiController]
    [Route("api/[controller]")]

/**
    * Dev controller - methods for development
    @module DevController
*/
    [AllowAnonymous]
    public class DevController : Controller {
        private readonly AppOptions _options;
        private readonly Db _db;
        private readonly IDistributedCache _cache;
        private readonly ILogger<HomeController> _logger;
        private readonly AuthService _authService;
        private readonly CurrentUserInfo _currentUserInfo;

        public DevController(IOptions<AppOptions> options, Db db, IDistributedCache cache, ILogger<HomeController> logger, AuthService authService, CurrentUserInfo currentUserInfo) {
            this._options = options.Value;
            this._db = db;
            this._cache = cache;
            this._logger = logger;
            this._authService = authService;
            _currentUserInfo = currentUserInfo;
        }

/**
*Add i18n keys (called from dev script which finds all keys in the code and adds them to the database)
*@param {Dictionary<string, string>} d - Keys
*@return {ActionResult} - Result of the operation
*/
        [HttpPost("AddI18NKeys")]
        public async Task<ActionResult> AddI18NKeys([FromBody] Dictionary <string, string> d) {
            if (!Debugger.IsAttached) {
                return Unauthorized();
            }
            await _db.ExecuteAsync("meta.add_i18n_keys", new { Keys = d["keys"] }, _options.ConnectionString);
            return Ok();
        }

        [HttpGet("GetDbSchema")]
        public async Task<ActionResult> GetDbSchema() {
            if (!Debugger.IsAttached) {
                return Unauthorized();
            }
            var ret = await _db.QueryJsonAsync("meta.get_db_schema", null, _options.ConnectionString);
            return Ok(ret);
        }

        [HttpGet("GetDbProcedures")]
        public async Task<ActionResult> GetDbProcedures(string schemaName, string procName) {
            if (!Debugger.IsAttached) {
                return Unauthorized();
            }
            var ret = await _db.QueryJsonAsync("meta.get_db_procedures", new {SchemaName = schemaName, ProcName = procName }, _options.ConnectionString);
            return Ok(ret);
        }

        [HttpPut("UpdateDbProcedure")]
        public async Task<ActionResult> UpdateDbProcedure(Dictionary<string,string> d) {
            if (!Debugger.IsAttached) {
                return Unauthorized();
            }
            var ret = await _db.QueryJsonAsync(d["definition"], null, _options.ConnectionString, cmdType:CommandType.Text);
            return Ok(ret);
        }

        [HttpPost("CRUD")]
        public async Task<ActionResult> CRUD([FromBody] Dictionary<string,object> d) {
            var ret = await _db.QueryAsync("meta.crud", new { SchemaName = d["schemaName"].ToString(), TableName = d["tableName"].ToString()  }, _options.ConnectionString);
            return Ok(ret);
        }
    }
}