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..e391f73 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() { 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..541ebc1 100644 --- a/src/Hless.Api/Models/Dto/SchemaDto.cs +++ b/src/Hless.Api/Models/Dto/SchemaDto.cs @@ -1,3 +1,5 @@ +using Hless.Data.Models; + namespace Hless.Api.Models.Dto { public record SchemaDto @@ -7,6 +9,6 @@ public record SchemaDto public string Definition { get; init; } public string DraftDefinition { get; init; } public string CreatedBy { 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..cf57e54 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,12 +13,49 @@ 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 = 0, + Name = "HomePage", + Definition = "{\n\"fields\":[\n{\n\"name\":\"Title\",\n\"type\":\"text\"\n}\n]\n}" + } }; - 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, + 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) @@ -31,12 +69,12 @@ public async Task> GetSchemasAsync() return await Task.FromResult(schemas); } - public Task PublishSchemaAsync(long schemaId) + public Task PublishSchemaAsync(long schemaId) { throw new System.NotImplementedException(); } - public Task UpdateSchemaAsync(Schema schema) + public Task UpdateSchemaAsync(Schema schema) { throw new System.NotImplementedException(); } 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..2493fa8 100644 --- a/src/Hless.Data/Models/Schema.cs +++ b/src/Hless.Data/Models/Schema.cs @@ -1,3 +1,5 @@ +using System; + namespace Hless.Data.Models { public record Schema @@ -7,6 +9,11 @@ public record Schema public string Definition { get; init; } public string DraftDefinition { get; init; } public string CreatedBy { get; init; } + public DateTime CreatedAt { get; init; } + public DateTime LastModified { get; init; } + public DateTime? FirstPublished { get; init; } + public DateTime? LastPublished { get; init; } + public long ApplicationId { get; init; } } 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