diff --git a/src/Hless.Api/Controllers/ApplicationController.cs b/src/Hless.Api/Controllers/ApplicationController.cs new file mode 100644 index 0000000..0909ddc --- /dev/null +++ b/src/Hless.Api/Controllers/ApplicationController.cs @@ -0,0 +1,55 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Hless.Common.Repositories; +using Hless.Api.Models.Dto; +using Hless.Api.Extensions.Models; +using Hless.Data.Models; + +namespace Hless.Api.Controllers +{ + [Route("[controller]/[action]")] + public class ApplicationController : BaseController + { + public IApplicationRepository _repository; + + public ApplicationController(IApplicationRepository repository) + { + _repository = repository; + } + + [HttpGet] + public async Task> GetApplicationsAsync() + { + var application = (await _repository.GetApplicationsAsync()) + .Select(app => app.AsDto()); + return application; + } + + [HttpPost] + public async void CreateApplicationAsync(ApplicationCreateDto application) + { + await _repository.CreateApplicationAsync(application.Name, application.OwnerId); + } + + [HttpGet] + public async Task GetApplicationAsync(long applicationId) + { + return await _repository.GetApplicationAsync(applicationId); + } + + [HttpPut] + public async Task UpdateApplicationAsync(ApplicationDto application) + { + return await _repository.UpdateApplicationAsync(application.ApplicationId, application.Name, application.OwnerId); + } + + [HttpDelete] + public async Task DeleteApplicationAsync(long applicationId) + { + return await _repository.DeleteApplicationAsync(applicationId); + } + } +} diff --git a/src/Hless.Api/Controllers/SchemaController.cs b/src/Hless.Api/Controllers/SchemaController.cs index 7bde7c5..c1a3ca3 100644 --- a/src/Hless.Api/Controllers/SchemaController.cs +++ b/src/Hless.Api/Controllers/SchemaController.cs @@ -10,7 +10,7 @@ namespace Hless.Api.Controllers { - [Route("[controller]")] + [Route("[controller]/[action]")] public class SchemaController : BaseController { readonly ISchemaRepository _repository; @@ -18,7 +18,7 @@ public SchemaController(ISchemaRepository repository) { _repository = repository; } - + [HttpGet] public async Task> GetSchemasAsync() { @@ -26,5 +26,42 @@ public async Task> GetSchemasAsync() .Select(schema => schema.AsDto()); return schemas; } + [HttpGet] + public async Task GetSchemaAsync(long schemaId) + { + return await _repository.GetSchemaAsync(schemaId); + } + [HttpPost] + public async Task CreateSchemaAsync(SchemaCreateDto schema) + { + Schema newSchema = new Schema() + { + Name = schema.Name, + DraftDefinition = schema.DraftDefinition, + ApplicationId = schema.ApplicationId, + }; + + return await _repository.CreateSchemaAsync(newSchema); + } + [HttpPut] + public async Task UpdateSchemaAsync([FromBody] Schema schema) + { + return await _repository.UpdateSchemaAsync(schema); + } + [HttpGet] + public async Task PublishSchemaAsync(long schemaId) + { + return await _repository.PublishSchemaAsync(schemaId); + } + [HttpDelete] + public async Task DeleteSchemaAsync(long schemaId) + { + return await _repository.DeleteSchemaAsync(schemaId); + } + [HttpGet] + public async Task Test([FromBody] Schema schema) + { + return await Task.FromResult(schema); + } } } \ No newline at end of file diff --git a/src/Hless.Api/Extensions/Models/DtoExtensions.cs b/src/Hless.Api/Extensions/Models/DtoExtensions.cs index bede3f3..22a5d4d 100644 --- a/src/Hless.Api/Extensions/Models/DtoExtensions.cs +++ b/src/Hless.Api/Extensions/Models/DtoExtensions.cs @@ -16,5 +16,15 @@ public static SchemaDto AsDto(this Schema schema) SchemaId = schema.SchemaId }; } + + public static ApplicationDto AsDto(this Application application) + { + return new ApplicationDto + { + ApplicationId = application.ApplicationId, + OwnerId = application.OwnerId, + Name = application.Name, + }; + } } } \ No newline at end of file diff --git a/src/Hless.Api/Extensions/ServiceCollectionExtensions.cs b/src/Hless.Api/Extensions/ServiceCollectionExtensions.cs index 6b902b9..9d7285a 100644 --- a/src/Hless.Api/Extensions/ServiceCollectionExtensions.cs +++ b/src/Hless.Api/Extensions/ServiceCollectionExtensions.cs @@ -9,9 +9,9 @@ public static class ServiceCollectionExtensions public static IServiceCollection AddDependencies(this IServiceCollection services) { services.AddSingleton(); + services.AddSingleton(); return services; } - } } \ No newline at end of file diff --git a/src/Hless.Api/Models/Dto/ApplicationDto.cs b/src/Hless.Api/Models/Dto/ApplicationDto.cs new file mode 100644 index 0000000..9d9a7d4 --- /dev/null +++ b/src/Hless.Api/Models/Dto/ApplicationDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Hless.Api.Models.Dto +{ + public record ApplicationDto + { + public long ApplicationId { get; init; } + public string Name { get; init; } + public string OwnerId { get; init; } + } + + public record ApplicationCreateDto + { + public string Name { get; init; } + public string OwnerId { get; init; } + } +} diff --git a/src/Hless.Api/Models/Dto/SchemaDto.cs b/src/Hless.Api/Models/Dto/SchemaDto.cs index 57eded9..a8b9023 100644 --- a/src/Hless.Api/Models/Dto/SchemaDto.cs +++ b/src/Hless.Api/Models/Dto/SchemaDto.cs @@ -1,12 +1,23 @@ +using Hless.Data.Models; +using System; +using System.Collections.Generic; + namespace Hless.Api.Models.Dto { public record SchemaDto { public long SchemaId { get; init; } public string Name { get; init; } - public string Definition { get; init; } - public string DraftDefinition { get; init; } + public Dictionary Definition { get; init; } + public Dictionary DraftDefinition { get; init; } public string CreatedBy { get; init; } + public long ApplicationId { get; init; } + } + public record SchemaCreateDto + { + public string Name { get; init; } + public Dictionary DraftDefinition { get; init; } + public long ApplicationId { get; init; } } } \ No newline at end of file diff --git a/src/Hless.Api/Startup.cs b/src/Hless.Api/Startup.cs index 07cbe40..0e37d4e 100644 --- a/src/Hless.Api/Startup.cs +++ b/src/Hless.Api/Startup.cs @@ -37,6 +37,8 @@ public void ConfigureServices(IServiceCollection services) var xmlFile = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = System.IO.Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); + + c.ResolveConflictingActions(ApiDescriptions => ApiDescriptions.First()); }); } diff --git a/src/Hless.Common/Repositories/IApplicationRepository.cs b/src/Hless.Common/Repositories/IApplicationRepository.cs new file mode 100644 index 0000000..9c735c0 --- /dev/null +++ b/src/Hless.Common/Repositories/IApplicationRepository.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hless.Data.Models; + +namespace Hless.Common.Repositories +{ + public interface IApplicationRepository + { + Task> GetApplicationsAsync(); + Task GetApplicationAsync(long applicationId); + Task CreateApplicationAsync(string name, string OwnerId); + Task UpdateApplicationAsync(long applicationId, string name, string OwnerId); + Task DeleteApplicationAsync(long applicationId); + } +} diff --git a/src/Hless.Common/Repositories/ISchemaRepository.cs b/src/Hless.Common/Repositories/ISchemaRepository.cs index c61b021..4b6c7ea 100644 --- a/src/Hless.Common/Repositories/ISchemaRepository.cs +++ b/src/Hless.Common/Repositories/ISchemaRepository.cs @@ -8,8 +8,9 @@ public interface ISchemaRepository { Task> GetSchemasAsync(); Task GetSchemaAsync(long schemaId); - Task CreateSchemaAsync(Schema schema); - Task UpdateSchemaAsync(Schema schema); - Task PublishSchemaAsync(long schemaId); + Task CreateSchemaAsync(Schema schema); + Task UpdateSchemaAsync(Schema schema); + Task PublishSchemaAsync(long schemaId); + Task DeleteSchemaAsync(long schemaId); } } \ No newline at end of file diff --git a/src/Hless.Data.InMemory/Repositories/InMemoryApplicationRepository.cs b/src/Hless.Data.InMemory/Repositories/InMemoryApplicationRepository.cs new file mode 100644 index 0000000..7435f9b --- /dev/null +++ b/src/Hless.Data.InMemory/Repositories/InMemoryApplicationRepository.cs @@ -0,0 +1,90 @@ +using Hless.Common.Repositories; +using Hless.Data.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hless.Data.InMemory.Repositories +{ + public class InMemoryApplicationRepository : IApplicationRepository + { + private readonly List applications = new() + { + new Application + { + ApplicationId = 0, + Name = "FirstApp", + OwnerId = "ownerId here", + CreatedBy = "creatorId here", + CreatedAt = new DateTime(01, 02, 03, 04, 05, 06), + LastModified = new DateTime(01, 02, 03, 04, 05, 06) + } + }; + + public async Task CreateApplicationAsync(string name, string OwnerId) + { + await Task.Run(() => + { + Application application = new Application() + { + ApplicationId = applications.Count, + Name = name, + OwnerId = OwnerId, + CreatedBy = "CreatedBy", // TODO: Change to logged in user + CreatedAt = DateTime.Now, + LastModified = DateTime.Now, + }; + + applications.Add(application); + }); + } + + public async Task DeleteApplicationAsync(long applicationId) + { + return await Task.Run(() => applications.Remove(applications.SingleOrDefault(app => app.ApplicationId == applicationId))); + } + + public async Task GetApplicationAsync(long applicationId) + { + return await Task.Run(() => applications.Where(app => app.ApplicationId == applicationId).SingleOrDefault()); + } + + public async Task> GetApplicationsAsync() + { + return await Task.FromResult(applications); + } + + public async Task UpdateApplicationAsync(long applicationId, string name, string OwnerId) + { + return await Task.Run(() => + { + Application oldApp = applications.SingleOrDefault(app => app.ApplicationId == applicationId); + + if (oldApp != null) + { + Application newApp = new Application() + { + ApplicationId = oldApp.ApplicationId, + Name = name, + OwnerId = OwnerId, + CreatedBy = oldApp.CreatedBy, // TODO: Change to logged in user + CreatedAt = oldApp.CreatedAt, + LastModified = DateTime.Now, + }; + + var indexOldApp = applications.IndexOf(oldApp); + + applications[indexOldApp] = newApp; + + return true; + } + else + { + return false; + } + }); + } + } +} diff --git a/src/Hless.Data.InMemory/Repositories/InMemorySchemaRepository.cs b/src/Hless.Data.InMemory/Repositories/InMemorySchemaRepository.cs index 4701e37..2df2648 100644 --- a/src/Hless.Data.InMemory/Repositories/InMemorySchemaRepository.cs +++ b/src/Hless.Data.InMemory/Repositories/InMemorySchemaRepository.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -12,17 +13,71 @@ public class InMemorySchemaRepository : ISchemaRepository { private readonly List schemas = new() { - new Schema { SchemaId = 1, Name = "HomePage", Definition = "{\n\"fields\":[\n{\n\"name\":\"Title\",\n\"type\":\"text\"\n}\n]\n}" } + new Schema { + SchemaId = 1, + Name = "Users", + DraftDefinition = new Dictionary { + { "Id", "number" }, + { "Title", "text" }, + { "Firstname", "text" }, + { "Surname", "text" } + }, + CreatedBy = "Admin", + CreatedAt = DateTime.Now, + }, + new Schema + { + SchemaId = 2, + Name = "Car", + DraftDefinition = new Dictionary { + { "Id", "number" }, + { "UsersId", "number" }, + { "Name", "text" }, + { "Licence", "text" } + }, + CreatedBy = "Admin", + CreatedAt = DateTime.Now, + } }; - public Task CreateSchemaAsync(Schema schema) + public async Task CreateSchemaAsync(Schema schema) { - throw new System.NotImplementedException(); + return await Task.Run(() => + { + try + { + Schema newSchema = new Schema() + { + SchemaId = schemas.Count + 1, + Name = schema.Name, + Definition = null, + DraftDefinition = schema.DraftDefinition, + CreatedBy = "CreatedBy", // Update with logged in user + CreatedAt = DateTime.Now, + LastModified = DateTime.Now, + FirstPublished = null, + LastPublished = null, + ApplicationId = schema.ApplicationId, + }; + schemas.Add(newSchema); + + return newSchema; + } + catch + { + return null; + } + }); + } + + public Task DeleteSchemaAsync(long schemaId) + { + return Task.Run(() => schemas.Remove(schemas.Find(s => s.SchemaId == schemaId))); } public async Task GetSchemaAsync(long schemaId) { - var schema = schemas.Where(schema => schema.SchemaId == schemaId).SingleOrDefault(); + var schema = schemas.Find(schema => schema.SchemaId == schemaId); return await Task.FromResult(schema); } @@ -31,14 +86,57 @@ public async Task> GetSchemasAsync() return await Task.FromResult(schemas); } - public Task PublishSchemaAsync(long schemaId) + public Task PublishSchemaAsync(long schemaId) { - throw new System.NotImplementedException(); + return Task.Run(() => { + try + { + int i = schemas.IndexOf(schemas.Find(s => s.SchemaId == schemaId)); + + if (i == -1) + return false; + + schemas[i].Definition = schemas[i].DraftDefinition; + schemas[i].LastPublished = DateTime.Now; + + if (schemas[i].FirstPublished == null) + schemas[i].FirstPublished = schemas[i].LastPublished; + + return true; + } + catch { return false; } + }); } - public Task UpdateSchemaAsync(Schema schema) + public Task UpdateSchemaAsync(Schema schema) { - throw new System.NotImplementedException(); + return Task.Run(() => + { + try + { + if(schema.SchemaId == 0) + return false; + + int i = schemas.IndexOf(schemas.Find(s => s.SchemaId == schema.SchemaId)); + + if (i == -1) + return false; + + if(schema.Name != null) + schemas[i].Name = schema.Name; + + if(schema.DraftDefinition != null) + schemas[i].DraftDefinition = schema.DraftDefinition; + + if(schema.ApplicationId != 0) + schemas[i].ApplicationId = schema.ApplicationId; + + schemas[i].LastModified = DateTime.Now; + + return true; + } + catch { return false; } + }); } } } \ No newline at end of file diff --git a/src/Hless.Data/Models/Application.cs b/src/Hless.Data/Models/Application.cs new file mode 100644 index 0000000..0ee35f5 --- /dev/null +++ b/src/Hless.Data/Models/Application.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Hless.Data.Models +{ + public record Application + { + public long ApplicationId { get; init; } + public string Name { get; init; } + public string OwnerId { get; init; } + public string CreatedBy { get; init; } + public DateTime CreatedAt { get; init; } + public DateTime LastModified { get; init; } + } +} diff --git a/src/Hless.Data/Models/Schema.cs b/src/Hless.Data/Models/Schema.cs index 9f07931..8d28acf 100644 --- a/src/Hless.Data/Models/Schema.cs +++ b/src/Hless.Data/Models/Schema.cs @@ -1,12 +1,20 @@ +using System; +using System.Collections.Generic; + namespace Hless.Data.Models { public record Schema { public long SchemaId { get; init; } - public string Name { get; init; } - public string Definition { get; init; } - public string DraftDefinition { get; init; } + public string Name { get; set; } + public Dictionary Definition { get; set; } + public Dictionary DraftDefinition { get; set; } public string CreatedBy { get; init; } + public DateTime CreatedAt { get; init; } + public DateTime LastModified { get; set; } + public DateTime? FirstPublished { get; set; } + public DateTime? LastPublished { get; set; } + public long ApplicationId { get; set; } } diff --git a/src/HlessApi.sln b/src/HlessApi.sln index 419d738..881052e 100644 --- a/src/HlessApi.sln +++ b/src/HlessApi.sln @@ -3,11 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hless.Api", "Hless.Api\Hless.Api.csproj", "{688F5106-1613-49DA-BF73-BB29A25D8D4C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hless.Api", "Hless.Api\Hless.Api.csproj", "{688F5106-1613-49DA-BF73-BB29A25D8D4C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hless.Common", "Hless.Common\Hless.Common.csproj", "{0B960661-19F2-4CF6-9BD1-6A9D086AE1E7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hless.Common", "Hless.Common\Hless.Common.csproj", "{0B960661-19F2-4CF6-9BD1-6A9D086AE1E7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hless.Data", "Hless.Data\Hless.Data.csproj", "{06C30E8F-87FB-42C1-AFDC-3A39AA82AD66}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hless.Data", "Hless.Data\Hless.Data.csproj", "{06C30E8F-87FB-42C1-AFDC-3A39AA82AD66}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hless.Data.InMemory", "Hless.Data.InMemory\Hless.Data.InMemory.csproj", "{096D6545-66D0-4ABB-B4FF-0D284B65CE23}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,9 +20,6 @@ Global Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {688F5106-1613-49DA-BF73-BB29A25D8D4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {688F5106-1613-49DA-BF73-BB29A25D8D4C}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -58,5 +57,23 @@ Global {06C30E8F-87FB-42C1-AFDC-3A39AA82AD66}.Release|x64.Build.0 = Release|Any CPU {06C30E8F-87FB-42C1-AFDC-3A39AA82AD66}.Release|x86.ActiveCfg = Release|Any CPU {06C30E8F-87FB-42C1-AFDC-3A39AA82AD66}.Release|x86.Build.0 = Release|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Debug|x64.ActiveCfg = Debug|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Debug|x64.Build.0 = Debug|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Debug|x86.ActiveCfg = Debug|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Debug|x86.Build.0 = Debug|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Release|Any CPU.Build.0 = Release|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Release|x64.ActiveCfg = Release|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Release|x64.Build.0 = Release|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Release|x86.ActiveCfg = Release|Any CPU + {096D6545-66D0-4ABB-B4FF-0D284B65CE23}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C122CA47-3D01-445C-B8D0-4E48E795E3B4} EndGlobalSection EndGlobal