From b7e39b59fd0fc7b5610ebff29035bf622079e0d8 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Wed, 5 Oct 2022 20:45:21 +0800 Subject: refactor: Change file structure --- code/api/src/Data/Database/ApiAccessToken.cs | 31 +++++++++++++++ code/api/src/Data/Database/Base.cs | 15 ++++++++ code/api/src/Data/Database/BaseWithOwner.cs | 19 +++++++++ code/api/src/Data/Database/Customer.cs | 6 +++ code/api/src/Data/Database/CustomerContact.cs | 12 ++++++ code/api/src/Data/Database/CustomerEvent.cs | 7 ++++ .../api/src/Data/Database/ForgotPasswordRequest.cs | 23 +++++++++++ code/api/src/Data/Database/Project.cs | 7 ++++ code/api/src/Data/Database/Tenant.cs | 11 ++++++ code/api/src/Data/Database/TimeCategory.cs | 31 +++++++++++++++ code/api/src/Data/Database/TimeEntry.cs | 45 ++++++++++++++++++++++ code/api/src/Data/Database/TimeLabel.cs | 31 +++++++++++++++ code/api/src/Data/Database/Todo.cs | 13 +++++++ code/api/src/Data/Database/TodoComment.cs | 7 ++++ code/api/src/Data/Database/TodoLabel.cs | 8 ++++ code/api/src/Data/Database/TodoProject.cs | 16 ++++++++ .../src/Data/Database/TodoProjectAccessControl.cs | 11 ++++++ code/api/src/Data/Database/TodoStatus.cs | 45 ++++++++++++++++++++++ code/api/src/Data/Database/User.cs | 37 ++++++++++++++++++ 19 files changed, 375 insertions(+) create mode 100644 code/api/src/Data/Database/ApiAccessToken.cs create mode 100644 code/api/src/Data/Database/Base.cs create mode 100644 code/api/src/Data/Database/BaseWithOwner.cs create mode 100644 code/api/src/Data/Database/Customer.cs create mode 100644 code/api/src/Data/Database/CustomerContact.cs create mode 100644 code/api/src/Data/Database/CustomerEvent.cs create mode 100644 code/api/src/Data/Database/ForgotPasswordRequest.cs create mode 100644 code/api/src/Data/Database/Project.cs create mode 100644 code/api/src/Data/Database/Tenant.cs create mode 100644 code/api/src/Data/Database/TimeCategory.cs create mode 100644 code/api/src/Data/Database/TimeEntry.cs create mode 100644 code/api/src/Data/Database/TimeLabel.cs create mode 100644 code/api/src/Data/Database/Todo.cs create mode 100644 code/api/src/Data/Database/TodoComment.cs create mode 100644 code/api/src/Data/Database/TodoLabel.cs create mode 100644 code/api/src/Data/Database/TodoProject.cs create mode 100644 code/api/src/Data/Database/TodoProjectAccessControl.cs create mode 100644 code/api/src/Data/Database/TodoStatus.cs create mode 100644 code/api/src/Data/Database/User.cs (limited to 'code/api/src/Data/Database') diff --git a/code/api/src/Data/Database/ApiAccessToken.cs b/code/api/src/Data/Database/ApiAccessToken.cs new file mode 100644 index 0000000..9582869 --- /dev/null +++ b/code/api/src/Data/Database/ApiAccessToken.cs @@ -0,0 +1,31 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class ApiAccessToken : Base +{ + public User User { get; set; } + public DateTime ExpiryDate { get; set; } + public bool AllowRead { get; set; } + public bool AllowCreate { get; set; } + public bool AllowUpdate { get; set; } + public bool AllowDelete { get; set; } + public bool HasExpired => ExpiryDate < AppDateTime.UtcNow; + public ApiAccessTokenDto AsDto => new(this); + + public class ApiAccessTokenDto + { + public ApiAccessTokenDto(ApiAccessToken source) { + ExpiryDate = source.ExpiryDate; + AllowRead = source.AllowRead; + AllowCreate = source.AllowCreate; + AllowUpdate = source.AllowUpdate; + AllowDelete = source.AllowDelete; + } + + public DateTime ExpiryDate { get; set; } + public bool AllowRead { get; set; } + public bool AllowCreate { get; set; } + public bool AllowUpdate { get; set; } + public bool AllowDelete { get; set; } + public bool HasExpired => ExpiryDate < AppDateTime.UtcNow; + } +} \ No newline at end of file diff --git a/code/api/src/Data/Database/Base.cs b/code/api/src/Data/Database/Base.cs new file mode 100644 index 0000000..ae9efa2 --- /dev/null +++ b/code/api/src/Data/Database/Base.cs @@ -0,0 +1,15 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class Base +{ + protected Base() { + Id = Guid.NewGuid(); + CreatedAt = AppDateTime.UtcNow; + } + + public Guid Id { get; init; } + public DateTime CreatedAt { get; init; } + public DateTime? ModifiedAt { get; private set; } + public bool Deleted { get; set; } + public void Modified() => ModifiedAt = AppDateTime.UtcNow; +} \ No newline at end of file diff --git a/code/api/src/Data/Database/BaseWithOwner.cs b/code/api/src/Data/Database/BaseWithOwner.cs new file mode 100644 index 0000000..1eb99f4 --- /dev/null +++ b/code/api/src/Data/Database/BaseWithOwner.cs @@ -0,0 +1,19 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +/// +/// Base class for all entities. +/// +public class BaseWithOwner : Base +{ + protected BaseWithOwner() { } + + protected BaseWithOwner(Guid userId) { + UserId = userId; + } + + public Guid? UserId { get; set; } + public Guid? TenantId { get; init; } + public Guid? ModifiedById { get; init; } + public Guid? CreatedById { get; init; } + public Guid? DeletedById { get; init; } +} \ No newline at end of file diff --git a/code/api/src/Data/Database/Customer.cs b/code/api/src/Data/Database/Customer.cs new file mode 100644 index 0000000..c6b06a4 --- /dev/null +++ b/code/api/src/Data/Database/Customer.cs @@ -0,0 +1,6 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class Customer : BaseWithOwner +{ + public string Name { get; set; } +} \ No newline at end of file diff --git a/code/api/src/Data/Database/CustomerContact.cs b/code/api/src/Data/Database/CustomerContact.cs new file mode 100644 index 0000000..f5a951d --- /dev/null +++ b/code/api/src/Data/Database/CustomerContact.cs @@ -0,0 +1,12 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class CustomerContact : BaseWithOwner +{ + public Customer Customer { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + public string WorkTitle { get; set; } + public string Note { get; set; } +} diff --git a/code/api/src/Data/Database/CustomerEvent.cs b/code/api/src/Data/Database/CustomerEvent.cs new file mode 100644 index 0000000..da3e3ed --- /dev/null +++ b/code/api/src/Data/Database/CustomerEvent.cs @@ -0,0 +1,7 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class CustomerEvent : BaseWithOwner +{ + public Customer Customer { get; set; } + public string Name { get; set; } +} diff --git a/code/api/src/Data/Database/ForgotPasswordRequest.cs b/code/api/src/Data/Database/ForgotPasswordRequest.cs new file mode 100644 index 0000000..1510a35 --- /dev/null +++ b/code/api/src/Data/Database/ForgotPasswordRequest.cs @@ -0,0 +1,23 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class ForgotPasswordRequest +{ + public ForgotPasswordRequest() { } + + public ForgotPasswordRequest(User user) { + CreatedAt = AppDateTime.UtcNow; + Id = Guid.NewGuid(); + User = user; + } + + public Guid Id { get; set; } + public Guid UserId { get; set; } + public User User { get; set; } + public DateTime CreatedAt { get; set; } + + [NotMapped] + public DateTime ExpirationDate => CreatedAt.AddMinutes(15); + + [NotMapped] + public bool IsExpired => DateTime.Compare(ExpirationDate, AppDateTime.UtcNow) < 0; +} diff --git a/code/api/src/Data/Database/Project.cs b/code/api/src/Data/Database/Project.cs new file mode 100644 index 0000000..7e694ee --- /dev/null +++ b/code/api/src/Data/Database/Project.cs @@ -0,0 +1,7 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class Project : BaseWithOwner +{ + public string Name { get; set; } + public Guid? CustomerId { get; set; } +} diff --git a/code/api/src/Data/Database/Tenant.cs b/code/api/src/Data/Database/Tenant.cs new file mode 100644 index 0000000..b185c7a --- /dev/null +++ b/code/api/src/Data/Database/Tenant.cs @@ -0,0 +1,11 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class Tenant : BaseWithOwner +{ + public string Name { get; set; } + public string Description { get; set; } + public string ContactEmail { get; set; } + public Guid MasterUserId { get; set; } + public string MasterUserPassword { get; set; } + public ICollection Users { get; set; } +} diff --git a/code/api/src/Data/Database/TimeCategory.cs b/code/api/src/Data/Database/TimeCategory.cs new file mode 100644 index 0000000..69c6957 --- /dev/null +++ b/code/api/src/Data/Database/TimeCategory.cs @@ -0,0 +1,31 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TimeCategory : BaseWithOwner +{ + public TimeCategory() { } + public TimeCategory(Guid userId) : base(userId) { } + public string Name { get; set; } + public string Color { get; set; } + public TimeCategoryDto AsDto => new(this); + + public class TimeCategoryDto + { + public TimeCategoryDto() { } + + public TimeCategoryDto(TimeCategory sourceEntry = default) { + if (sourceEntry == default) { + return; + } + + Id = sourceEntry.Id; + ModifiedAt = sourceEntry.ModifiedAt; + Name = sourceEntry.Name; + Color = sourceEntry.Color; + } + + public Guid Id { get; set; } + public DateTime? ModifiedAt { get; set; } + public string Name { get; set; } + public string Color { get; set; } + } +} diff --git a/code/api/src/Data/Database/TimeEntry.cs b/code/api/src/Data/Database/TimeEntry.cs new file mode 100644 index 0000000..46c62e1 --- /dev/null +++ b/code/api/src/Data/Database/TimeEntry.cs @@ -0,0 +1,45 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TimeEntry : BaseWithOwner +{ + public TimeEntry() { } + public TimeEntry(Guid userId) : base(userId) { } + public DateTime Start { get; set; } + public DateTime Stop { get; set; } + public string Description { get; set; } + public ICollection Labels { get; set; } + public TimeCategory Category { get; set; } + public TimeEntryDto AsDto => new(this); + + public class TimeEntryDto + { + public TimeEntryDto() { } + + public TimeEntryDto(TimeEntry sourceEntry = default) { + if (sourceEntry == default) { + return; + } + + Id = sourceEntry.Id; + ModifiedAt = sourceEntry.ModifiedAt; + Stop = sourceEntry.Stop; + Start = sourceEntry.Start; + Description = sourceEntry.Description; + if (sourceEntry.Labels != default) { + Labels = sourceEntry.Labels + .Select(t => t.AsDto) + .ToList(); + } + + Category = sourceEntry.Category.AsDto; + } + + public Guid? Id { get; set; } + public DateTime? ModifiedAt { get; set; } + public DateTime Start { get; set; } + public DateTime Stop { get; set; } + public string Description { get; set; } + public List Labels { get; set; } + public TimeCategory.TimeCategoryDto Category { get; set; } + } +} diff --git a/code/api/src/Data/Database/TimeLabel.cs b/code/api/src/Data/Database/TimeLabel.cs new file mode 100644 index 0000000..55e20b0 --- /dev/null +++ b/code/api/src/Data/Database/TimeLabel.cs @@ -0,0 +1,31 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TimeLabel : BaseWithOwner +{ + public TimeLabel() { } + public TimeLabel(Guid userId) : base(userId) { } + public string Name { get; set; } + public string Color { get; set; } + + [NotMapped] + public TimeLabelDto AsDto => new(this); + + public class TimeLabelDto + { + public TimeLabelDto() { } + + public TimeLabelDto(TimeLabel sourceEntry) { + Id = sourceEntry.Id; + CreatedAt = sourceEntry.CreatedAt; + ModifiedAt = sourceEntry.ModifiedAt; + Name = sourceEntry.Name; + Color = sourceEntry.Color; + } + + public Guid Id { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime? ModifiedAt { get; set; } + public string Name { get; set; } + public string Color { get; set; } + } +} diff --git a/code/api/src/Data/Database/Todo.cs b/code/api/src/Data/Database/Todo.cs new file mode 100644 index 0000000..5fe3c9a --- /dev/null +++ b/code/api/src/Data/Database/Todo.cs @@ -0,0 +1,13 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class Todo : BaseWithOwner +{ + public int PublicId { get; set; } + public TodoStatus Status { get; set; } + public TodoProject Project { get; set; } + public Guid? AssignedUserId { get; set; } + public string Title { get; set; } + public string Description { get; set; } + public ICollection Labels { get; set; } + public ICollection Comments { get; set; } +} diff --git a/code/api/src/Data/Database/TodoComment.cs b/code/api/src/Data/Database/TodoComment.cs new file mode 100644 index 0000000..44dcbed --- /dev/null +++ b/code/api/src/Data/Database/TodoComment.cs @@ -0,0 +1,7 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TodoComment : BaseWithOwner +{ + public string Value { get; set; } + public Todo Todo { get; set; } +} diff --git a/code/api/src/Data/Database/TodoLabel.cs b/code/api/src/Data/Database/TodoLabel.cs new file mode 100644 index 0000000..7753ade --- /dev/null +++ b/code/api/src/Data/Database/TodoLabel.cs @@ -0,0 +1,8 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TodoLabel : BaseWithOwner +{ + public string Name { get; set; } + public string Color { get; set; } + public Todo Todo { get; set; } +} diff --git a/code/api/src/Data/Database/TodoProject.cs b/code/api/src/Data/Database/TodoProject.cs new file mode 100644 index 0000000..0a4a7be --- /dev/null +++ b/code/api/src/Data/Database/TodoProject.cs @@ -0,0 +1,16 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TodoProject : BaseWithOwner +{ + public string Name { get; set; } + public TodoVisibility Visibility { get; set; } + public Guid? ProjectId { get; set; } +} + +public enum TodoVisibility +{ + PRIVATE = 0, + UNLISTED = 1, + TENANT_WIDE = 2, + PUBLIC = 3, +} diff --git a/code/api/src/Data/Database/TodoProjectAccessControl.cs b/code/api/src/Data/Database/TodoProjectAccessControl.cs new file mode 100644 index 0000000..964f831 --- /dev/null +++ b/code/api/src/Data/Database/TodoProjectAccessControl.cs @@ -0,0 +1,11 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TodoProjectAccessControl +{ + public TodoProject Project { get; set; } + public Guid? UserId { get; set; } + public bool Browse { get; set; } + public bool Submit { get; set; } + public bool Comment { get; set; } + public bool Edit { get; set; } +} diff --git a/code/api/src/Data/Database/TodoStatus.cs b/code/api/src/Data/Database/TodoStatus.cs new file mode 100644 index 0000000..416212d --- /dev/null +++ b/code/api/src/Data/Database/TodoStatus.cs @@ -0,0 +1,45 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class TodoStatus : BaseWithOwner +{ + public string Name { get; set; } + public string Color { get; set; } + public Todo Todo { get; set; } + + public static List GetDefaultStatusSetForTenant(Guid tenantId) { + return new List() { + new() { + Name = "Reported", + TenantId = tenantId + }, + new() { + Name = "Resolved", + TenantId = tenantId + }, + new() { + Name = "Fixed", + TenantId = tenantId + }, + new() { + Name = "Implemented", + TenantId = tenantId + }, + new() { + Name = "Won't fix", + TenantId = tenantId + }, + new() { + Name = "By design", + TenantId = tenantId + }, + new() { + Name = "Invalid", + TenantId = tenantId + }, + new() { + Name = "Duplicate", + TenantId = tenantId + } + }; + } +} diff --git a/code/api/src/Data/Database/User.cs b/code/api/src/Data/Database/User.cs new file mode 100644 index 0000000..9db5d35 --- /dev/null +++ b/code/api/src/Data/Database/User.cs @@ -0,0 +1,37 @@ +namespace IOL.GreatOffice.Api.Data.Database; + +public class User : Base +{ + public User() { } + + public User(string username) { + Username = username; + } + + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Username { get; set; } + public string Password { get; set; } + public ICollection Tenants { get; set; } + + public string DisplayName() { + if (FirstName.HasValue() && LastName.HasValue()) return FirstName + " " + LastName; + return FirstName.HasValue() ? FirstName : Email; + } + + public void HashAndSetPassword(string password) { + Password = PasswordHelper.HashPassword(password); + } + + public bool VerifyPassword(string password) { + return PasswordHelper.Verify(password, Password); + } + + public IEnumerable DefaultClaims() { + return new Claim[] { + new(AppClaims.USER_ID, Id.ToString()), + new(AppClaims.NAME, Username), + }; + } +} \ No newline at end of file -- cgit v1.3