├── .gitattributes ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── DevOps ├── ContinuousIntegration.yml ├── ManualFullBuild.yml ├── NuGet.config └── PullRequest.yml ├── LICENSE ├── README.md ├── docfx_project ├── .gitignore ├── .vscode │ └── settings.json ├── api │ ├── .gitignore │ └── index.md ├── articles │ ├── Accounts-Module.md │ ├── Architecture.md │ ├── Asset-Register-Module.md │ ├── Budget-Module.md │ ├── Calendar-Module.md │ ├── Contacts-Module.md │ ├── Core-Module.md │ ├── Dashboard-Module.md │ ├── Design-Notes.md │ ├── Documents-Module.md │ ├── Mail-Module.md │ ├── Misc-CLI-Tools.md │ ├── Reports-Module.md │ ├── Tasks-Module.md │ ├── intro.md │ ├── toc.yml │ └── wip.md ├── assets │ ├── test.drawio │ └── ux │ │ └── AdminAssistantUIDesign.epgz ├── docfx.json ├── images │ ├── Accounts-Module │ │ └── AccountsModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Architecture │ │ ├── Component-Diagram_V1o0o0.png │ │ └── System-Architecture-Diagram_V1o0o0.png │ ├── Asset-Register-Module │ │ └── AssetsRegisterModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Budget-Module │ │ └── BudgetModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Calendar-Module │ │ └── CalendarModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Contacts-Module │ │ └── ContactsModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Core-Module │ │ └── CoreModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Documents-Module │ │ └── DocumentsModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Food-Module │ │ └── Food_Module.png │ └── Tasks-Module │ │ └── TasksModule_EntityRelationshipDiagram_V1o0o0.png ├── index.md └── toc.yml ├── docs ├── api │ ├── AdminAssistant.Blazor.Client.Shared.AdminAssistantComponentBase-1.html │ ├── AdminAssistant.Blazor.Client.Shared.AdminAssistantLayoutComponentBase-1.html │ ├── AdminAssistant.Blazor.Client.Shared.html │ ├── AdminAssistant.Blazor.Server.Startup.html │ ├── AdminAssistant.Blazor.Server.html │ ├── AdminAssistant.Constants.html │ ├── AdminAssistant.DomainModel.Factory.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Bank.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.BankAccount.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.BankAccountInfo.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.BankAccountTransaction.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.BankAccountType.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Builders.IBankAccountBuilder.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Builders.IBankAccountInfoBuilder.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Builders.IBankAccountTransactionBuilder.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Builders.IBankAccountTypeBuilder.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Builders.IBankBuilder.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankAccountByIDQuery.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankAccountCreateCommand.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankAccountInfoQuery.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankAccountTransactionsByBankAccountIDQuery.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankAccountTypesQuery.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankAccountUpdateCommand.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankByIDQuery.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankCreateCommand.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankQuery.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.BankUpdateCommand.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Validation.IBankAccountTransactionValidator.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Validation.IBankAccountTypeValidator.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Validation.IBankAccountValidator.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Validation.IBankValidator.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.Validation.html │ ├── AdminAssistant.DomainModel.Modules.AccountsModule.html │ ├── AdminAssistant.DomainModel.Modules.AssetRegisterModule.Asset.html │ ├── AdminAssistant.DomainModel.Modules.AssetRegisterModule.Builders.IAssetBuilder.html │ ├── AdminAssistant.DomainModel.Modules.AssetRegisterModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.AssetRegisterModule.CQRS.AssetQuery.html │ ├── AdminAssistant.DomainModel.Modules.AssetRegisterModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.AssetRegisterModule.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.Budget.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.Builders.IBudgetBuilder.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.CQRS.BudgetQuery.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.Validation.IBudgetValidator.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.Validation.html │ ├── AdminAssistant.DomainModel.Modules.BudgetModule.html │ ├── AdminAssistant.DomainModel.Modules.CalendarModule.Builders.IReminderBuilder.html │ ├── AdminAssistant.DomainModel.Modules.CalendarModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.CalendarModule.CQRS.ReminderQuery.html │ ├── AdminAssistant.DomainModel.Modules.CalendarModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.CalendarModule.Reminder.html │ ├── AdminAssistant.DomainModel.Modules.CalendarModule.html │ ├── AdminAssistant.DomainModel.Modules.ContactsModule.Builders.IContactBuilder.html │ ├── AdminAssistant.DomainModel.Modules.ContactsModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.ContactsModule.CQRS.ContactQuery.html │ ├── AdminAssistant.DomainModel.Modules.ContactsModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.ContactsModule.Contact.html │ ├── AdminAssistant.DomainModel.Modules.ContactsModule.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.Builders.ICurrencyBuilder.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.CQRS.CurrenciesQuery.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.CQRS.CurrencyByIDQuery.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.CQRS.CurrencyCreateCommand.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.CQRS.CurrencyUpdateCommand.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.Company.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.Currency.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.Validation.ICurrencyValidator.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.Validation.html │ ├── AdminAssistant.DomainModel.Modules.CoreModule.html │ ├── AdminAssistant.DomainModel.Modules.DocumentsModule.Builders.IDocumentBuilder.html │ ├── AdminAssistant.DomainModel.Modules.DocumentsModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.DocumentsModule.CQRS.DocumentQuery.html │ ├── AdminAssistant.DomainModel.Modules.DocumentsModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.DocumentsModule.Document.html │ ├── AdminAssistant.DomainModel.Modules.DocumentsModule.html │ ├── AdminAssistant.DomainModel.Modules.MailModule.Builders.IMailMessageBuilder.html │ ├── AdminAssistant.DomainModel.Modules.MailModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.MailModule.CQRS.MailMessageQuery.html │ ├── AdminAssistant.DomainModel.Modules.MailModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.MailModule.MailMessage.html │ ├── AdminAssistant.DomainModel.Modules.MailModule.html │ ├── AdminAssistant.DomainModel.Modules.TasksModule.Builders.ITaskListBuilder.html │ ├── AdminAssistant.DomainModel.Modules.TasksModule.Builders.html │ ├── AdminAssistant.DomainModel.Modules.TasksModule.CQRS.TaskListQuery.html │ ├── AdminAssistant.DomainModel.Modules.TasksModule.CQRS.html │ ├── AdminAssistant.DomainModel.Modules.TasksModule.TaskList.html │ ├── AdminAssistant.DomainModel.Modules.TasksModule.html │ ├── AdminAssistant.DomainModel.RequestHandlerBase-2.html │ ├── AdminAssistant.DomainModel.Shared.ConfigurationSettings.html │ ├── AdminAssistant.DomainModel.Shared.DatabaseProvider.html │ ├── AdminAssistant.DomainModel.Shared.IUserContextProvider.html │ ├── AdminAssistant.DomainModel.Shared.User.html │ ├── AdminAssistant.DomainModel.Shared.html │ ├── AdminAssistant.DomainModel.html │ ├── AdminAssistant.Framework.TypeMapping.IMapFrom-1.html │ ├── AdminAssistant.Framework.TypeMapping.IMapTo-1.html │ ├── AdminAssistant.Framework.TypeMapping.MappingProfileBase.html │ ├── AdminAssistant.Framework.TypeMapping.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.ApplicationDbContext.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.IApplicationDbContext.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Migrations.Initial.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Migrations.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankAccountEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankAccountStatementEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankAccountTransactionDocumentEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankAccountTransactionEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankAccountTransactionTypeEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankAccountTypeEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.BankEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.PayeeEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Accounts.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.AccountsSchema.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.AssetRegister.AssetEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.AssetRegister.ManufacturerEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.AssetRegister.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Billing.ClientEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Billing.InvoiceEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Billing.SupplierEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Billing.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Budget.BudgetEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Budget.BudgetEntryEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Budget.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Calendar.AppointmentEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Calendar.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Contacts.AddressEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Contacts.ContactAddressEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Contacts.ContactEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Contacts.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.AuditEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.CompanyEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.CoreSchema.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.CurrencyEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.OwnerEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.PermissionEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.PersonalDetailsEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.SettingEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.UserProfileEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.UserProfilePermissionEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.UserProfileSettingEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Core.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Documents.DocumentEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Documents.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Grocery.GroceryItemEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Grocery.MealPlanEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Grocery.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Tasks.TaskEntity.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.Tasks.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.Model.html │ ├── AdminAssistant.Infra.DAL.EntityFramework.html │ ├── AdminAssistant.Infra.DAL.IDatabasePersistable.html │ ├── AdminAssistant.Infra.DAL.IReadOnlyChildRepository-1.html │ ├── AdminAssistant.Infra.DAL.IReadOnlyRepository-1.html │ ├── AdminAssistant.Infra.DAL.IRepository-1.html │ ├── AdminAssistant.Infra.DAL.MappingProfile.html │ ├── AdminAssistant.Infra.DAL.Modules.AccountsModule.IBankAccountInfoRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.AccountsModule.IBankAccountRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.AccountsModule.IBankAccountTransactionRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.AccountsModule.IBankAccountTypeRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.AccountsModule.IBankRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.AccountsModule.html │ ├── AdminAssistant.Infra.DAL.Modules.CoreModule.ICurrencyRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.CoreModule.html │ ├── AdminAssistant.Infra.DAL.Modules.DocumentsModule.IDocumentRepository.html │ ├── AdminAssistant.Infra.DAL.Modules.DocumentsModule.html │ ├── AdminAssistant.Infra.DAL.html │ ├── AdminAssistant.Infra.Providers.IDateTimeProvider.html │ ├── AdminAssistant.Infra.Providers.ILoggingProvider.html │ ├── AdminAssistant.Infra.Providers.html │ ├── AdminAssistant.UI.IViewModelBase.html │ ├── AdminAssistant.UI.Modules.AccountsModule.EditBankAccountMessage.html │ ├── AdminAssistant.UI.Modules.AccountsModule.IAccountsService.html │ ├── AdminAssistant.UI.Modules.AccountsModule.IAccountsViewModel.html │ ├── AdminAssistant.UI.Modules.AccountsModule.IBankAccountBalanceListViewModel.html │ ├── AdminAssistant.UI.Modules.AccountsModule.IBankAccountEditDialogViewModel.html │ ├── AdminAssistant.UI.Modules.AccountsModule.IBankAccountRightSidebarViewModel.html │ ├── AdminAssistant.UI.Modules.AccountsModule.IBankAccountTransactionListViewModel.html │ ├── AdminAssistant.UI.Modules.AccountsModule.html │ ├── AdminAssistant.UI.Modules.AdminModule.IAdminViewModel.html │ ├── AdminAssistant.UI.Modules.AdminModule.html │ ├── AdminAssistant.UI.Modules.AssetRegisterModule.IAssetRegisterViewModel.html │ ├── AdminAssistant.UI.Modules.AssetRegisterModule.html │ ├── AdminAssistant.UI.Modules.BillingModule.IBillingViewModel.html │ ├── AdminAssistant.UI.Modules.BillingModule.html │ ├── AdminAssistant.UI.Modules.BudgetModule.IBudgetViewModel.html │ ├── AdminAssistant.UI.Modules.BudgetModule.html │ ├── AdminAssistant.UI.Modules.CalendarModule.ICalendarViewModel.html │ ├── AdminAssistant.UI.Modules.CalendarModule.html │ ├── AdminAssistant.UI.Modules.ContactsModule.IContactsViewModel.html │ ├── AdminAssistant.UI.Modules.ContactsModule.html │ ├── AdminAssistant.UI.Modules.CoreModule.ICoreService.html │ ├── AdminAssistant.UI.Modules.CoreModule.html │ ├── AdminAssistant.UI.Modules.DashboardModule.IDashboardViewModel.html │ ├── AdminAssistant.UI.Modules.DashboardModule.html │ ├── AdminAssistant.UI.Modules.DocumentsModule.IDocumentsService.html │ ├── AdminAssistant.UI.Modules.DocumentsModule.IDocumentsViewModel.html │ ├── AdminAssistant.UI.Modules.DocumentsModule.html │ ├── AdminAssistant.UI.Modules.MailModule.IMailViewModel.html │ ├── AdminAssistant.UI.Modules.MailModule.html │ ├── AdminAssistant.UI.Modules.ReportsModule.IReportsViewModel.html │ ├── AdminAssistant.UI.Modules.ReportsModule.html │ ├── AdminAssistant.UI.Modules.TasksModule.ITasksViewModel.html │ ├── AdminAssistant.UI.Modules.TasksModule.html │ ├── AdminAssistant.UI.Shared.ExpandedContractedStateToggle.html │ ├── AdminAssistant.UI.Shared.IAppService.html │ ├── AdminAssistant.UI.Shared.IMainWindowViewModel.html │ ├── AdminAssistant.UI.Shared.ModeEnum.html │ ├── AdminAssistant.UI.Shared.ModeSelectionChangedMessage.html │ ├── AdminAssistant.UI.Shared.ModeSelectionItem.html │ ├── AdminAssistant.UI.Shared.ModuleEnum.html │ ├── AdminAssistant.UI.Shared.ModuleSelectionChangedMessage.html │ ├── AdminAssistant.UI.Shared.ModuleSelectionItem.html │ ├── AdminAssistant.UI.Shared.SidebarStateSettings.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.AdminAssistantWebAPIClient.ObjectResponseResult-1.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.AdminAssistantWebAPIClient.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.ApiException-1.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.ApiException.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.AssetResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankAccountCreateRequestDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankAccountInfoResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankAccountResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankAccountTransactionResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankAccountTypeResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankAccountUpdateRequestDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankCreateRequestDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BankUpdateRequestDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.BudgetResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.ContactResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.CurrencyCreateRequestDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.CurrencyResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.CurrencyUpdateRequestDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.DocumentResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.IAdminAssistantWebAPIClient.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.MailMessageResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.MappingProfile.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.ProblemDetails.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.ReminderResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.TaskListResponseDto.html │ ├── AdminAssistant.UI.Shared.WebAPIClient.v1.html │ ├── AdminAssistant.UI.Shared.html │ ├── AdminAssistant.UI.ViewModelLocator.html │ ├── AdminAssistant.UI.html │ ├── AdminAssistant.WPF.App.html │ ├── AdminAssistant.WPF.MainWindow.html │ ├── AdminAssistant.WPF.Modules.AccountsModule.AccountsComponent.html │ ├── AdminAssistant.WPF.Modules.AccountsModule.BankAccountBalanceListComponent.html │ ├── AdminAssistant.WPF.Modules.AccountsModule.BankAccountEditDialog.html │ ├── AdminAssistant.WPF.Modules.AccountsModule.BankAccountRightSidebarComponent.html │ ├── AdminAssistant.WPF.Modules.AccountsModule.BankAccountTransactionListComponent.html │ ├── AdminAssistant.WPF.Modules.AccountsModule.html │ ├── AdminAssistant.WPF.Modules.Admin.AdminComponent.html │ ├── AdminAssistant.WPF.Modules.Admin.html │ ├── AdminAssistant.WPF.Modules.AssetRegisterModule.AssetRegisterComponent.html │ ├── AdminAssistant.WPF.Modules.AssetRegisterModule.html │ ├── AdminAssistant.WPF.Modules.BillingModule.BillingComponent.html │ ├── AdminAssistant.WPF.Modules.BillingModule.html │ ├── AdminAssistant.WPF.Modules.BudgetModule.BudgetComponent.html │ ├── AdminAssistant.WPF.Modules.BudgetModule.html │ ├── AdminAssistant.WPF.Modules.CalendarModule.CalendarComponent.html │ ├── AdminAssistant.WPF.Modules.CalendarModule.html │ ├── AdminAssistant.WPF.Modules.ContactsModule.ContactsComponent.html │ ├── AdminAssistant.WPF.Modules.ContactsModule.html │ ├── AdminAssistant.WPF.Modules.DashboardModule.DashboardComponent.html │ ├── AdminAssistant.WPF.Modules.DashboardModule.html │ ├── AdminAssistant.WPF.Modules.DocumentsModule.DocumentsComponent.html │ ├── AdminAssistant.WPF.Modules.DocumentsModule.html │ ├── AdminAssistant.WPF.Modules.MailModule.MailComponent.html │ ├── AdminAssistant.WPF.Modules.MailModule.html │ ├── AdminAssistant.WPF.Modules.ReportsModule.ReportsComponent.html │ ├── AdminAssistant.WPF.Modules.ReportsModule.html │ ├── AdminAssistant.WPF.Modules.TasksModule.TasksComponent.html │ ├── AdminAssistant.WPF.Modules.TasksModule.html │ ├── AdminAssistant.WPF.Shared.ModeEnumExtensions.html │ ├── AdminAssistant.WPF.Shared.ModeEnumToIconImageConverter.html │ ├── AdminAssistant.WPF.Shared.ModeImageExtension.html │ ├── AdminAssistant.WPF.Shared.ModeSelectionItemToIconImageConverter.html │ ├── AdminAssistant.WPF.Shared.ModuleEnumExtensions.html │ ├── AdminAssistant.WPF.Shared.ModuleEnumToIconImageConverter.html │ ├── AdminAssistant.WPF.Shared.ModuleImageExtension.html │ ├── AdminAssistant.WPF.Shared.html │ ├── AdminAssistant.WPF.ViewModelLocator.html │ ├── AdminAssistant.WPF.html │ ├── AdminAssistant.WebAPI.WebAPIControllerBase.html │ ├── AdminAssistant.WebAPI.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountController.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountCreateRequestDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountInfoController.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountInfoResponseDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountResponseDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountTransactionResponseDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountTypeController.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountTypeResponseDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankAccountUpdateRequestDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankController.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankCreateRequestDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankResponseDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.BankUpdateRequestDto.html │ ├── AdminAssistant.WebAPI.v1.AccountsModule.html │ ├── AdminAssistant.WebAPI.v1.AssetRegisterModule.AssetController.html │ ├── AdminAssistant.WebAPI.v1.AssetRegisterModule.AssetResponseDto.html │ ├── AdminAssistant.WebAPI.v1.AssetRegisterModule.html │ ├── AdminAssistant.WebAPI.v1.BudgetModule.BudgetController.html │ ├── AdminAssistant.WebAPI.v1.BudgetModule.BudgetResponseDto.html │ ├── AdminAssistant.WebAPI.v1.BudgetModule.html │ ├── AdminAssistant.WebAPI.v1.CalendarModule.ReminderController.html │ ├── AdminAssistant.WebAPI.v1.CalendarModule.ReminderResponseDto.html │ ├── AdminAssistant.WebAPI.v1.CalendarModule.html │ ├── AdminAssistant.WebAPI.v1.ContactsModule.ContactController.html │ ├── AdminAssistant.WebAPI.v1.ContactsModule.ContactResponseDto.html │ ├── AdminAssistant.WebAPI.v1.ContactsModule.html │ ├── AdminAssistant.WebAPI.v1.CoreModule.CurrencyController.html │ ├── AdminAssistant.WebAPI.v1.CoreModule.CurrencyCreateRequestDto.html │ ├── AdminAssistant.WebAPI.v1.CoreModule.CurrencyResponseDto.html │ ├── AdminAssistant.WebAPI.v1.CoreModule.CurrencyUpdateRequestDto.html │ ├── AdminAssistant.WebAPI.v1.CoreModule.html │ ├── AdminAssistant.WebAPI.v1.DocumentsModule.DocumentController.html │ ├── AdminAssistant.WebAPI.v1.DocumentsModule.DocumentResponseDto.html │ ├── AdminAssistant.WebAPI.v1.DocumentsModule.html │ ├── AdminAssistant.WebAPI.v1.MailModule.MailMessageController.html │ ├── AdminAssistant.WebAPI.v1.MailModule.MailMessageResponseDto.html │ ├── AdminAssistant.WebAPI.v1.MailModule.html │ ├── AdminAssistant.WebAPI.v1.MappingProfile.html │ ├── AdminAssistant.WebAPI.v1.TasksModule.TaskListController.html │ ├── AdminAssistant.WebAPI.v1.TasksModule.TaskListResponseDto.html │ ├── AdminAssistant.WebAPI.v1.TasksModule.html │ ├── AdminAssistant.WebAPI.v1.html │ ├── AdminAssistant.WinForms.MainForm.html │ ├── AdminAssistant.WinForms.Modules.AccountsModule.AccountsComponent.html │ ├── AdminAssistant.WinForms.Modules.AccountsModule.html │ ├── AdminAssistant.WinForms.html │ ├── AdminAssistant.html │ ├── Microsoft.Extensions.DependencyInjection.DependencyInjectionExtensions.html │ ├── Microsoft.Extensions.DependencyInjection.html │ ├── index.html │ └── toc.html ├── articles │ ├── Accounts-Module.html │ ├── Architecture.html │ ├── Asset-Register-Module.html │ ├── Budget-Module.html │ ├── Calendar-Module.html │ ├── Contacts-Module.html │ ├── Core-Module.html │ ├── Dashboard-Module.html │ ├── Design-Notes.html │ ├── Documents-Module.html │ ├── Home.html │ ├── Mail-Module.html │ ├── Misc-CLI-Tools.html │ ├── Reports-Module.html │ ├── Tasks-Module.html │ ├── _Sidebar.html │ ├── intro.html │ ├── toc.html │ └── wip.html ├── favicon.ico ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── images │ ├── Accounts-Module │ │ └── AccountsModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Architecture │ │ ├── Component-Diagram_V1o0o0.png │ │ └── System-Architecture-Diagram_V1o0o0.png │ ├── Asset-Register-Module │ │ └── AssetsRegisterModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Budget-Module │ │ └── BudgetModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Calendar-Module │ │ └── CalendarModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Contacts-Module │ │ └── ContactsModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Core-Module │ │ └── CoreModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Documents-Module │ │ └── DocumentsModule_EntityRelationshipDiagram_V1o0o0.png │ ├── Food-Module │ │ └── Food_Module.png │ └── Tasks-Module │ │ └── TasksModule_EntityRelationshipDiagram_V1o0o0.png ├── index.html ├── logo.svg ├── manifest.json ├── search-stopwords.json ├── styles │ ├── docfx.css │ ├── docfx.js │ ├── docfx.vendor.css │ ├── docfx.vendor.js │ ├── lunr.js │ ├── lunr.min.js │ ├── main.css │ ├── main.js │ └── search-worker.js ├── toc.html └── xrefmap.yml ├── models └── c4 │ └── AdminAssistant.dsl └── src ├── .config └── dotnet-tools.json ├── .editorconfig ├── AdminAssistant.Application ├── AdminAssistant.Application.csproj ├── DependencyInjectionExtensions.cs ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Modules │ ├── AccountsModule │ │ ├── Commands │ │ │ ├── BankAccountCreateCommandHandler.cs │ │ │ ├── BankAccountUpdateCommandHandler.cs │ │ │ ├── BankCreateCommandHandler.cs │ │ │ └── BankUpdateCommandHandler.cs │ │ └── Queries │ │ │ ├── BankAccountByIDQueryHandler.cs │ │ │ ├── BankAccountInfoQueryHandler.cs │ │ │ ├── BankAccountTransactionsByBankAccountIDQueryHandler.cs │ │ │ ├── BankAccountTypesQueryHandler.cs │ │ │ ├── BankByIDQueryHandler.cs │ │ │ ├── BankQueryHandler.cs │ │ │ └── Queries.cs │ ├── AssetRegisterModule │ │ └── Queries │ │ │ └── Queries.cs │ ├── BudgetModule │ │ └── Queries │ │ │ └── Queries.cs │ ├── CalendarModule │ │ └── Queries │ │ │ └── Queries.cs │ ├── ContactsModule │ │ ├── Commands │ │ │ ├── ContactCreateCommandHandler.cs │ │ │ └── ContactUpdateCommandHandler.cs │ │ └── Queries │ │ │ └── ContactByIDQueryHandler.cs │ ├── CoreModule │ │ ├── Commands │ │ │ ├── CurrencyCreateCommandHandler.cs │ │ │ └── CurrencyUpdateCommandHandler.cs │ │ └── Queries │ │ │ ├── CurrenciesQueryHandler.cs │ │ │ └── CurrencyByIDQueryHandler.cs │ ├── DocumentsModule │ │ └── Queries │ │ │ └── DocumentQueryHandler.cs │ ├── MailModule │ │ └── Queries │ │ │ └── Queries.cs │ └── TasksModule │ │ └── Queries │ │ └── Queries.cs └── RequestHandlerBase.cs ├── AdminAssistant.Blazor.Server ├── AdminAssistant.Blazor.Server.csproj ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Program.cs ├── Properties │ ├── launchSettings.json │ ├── serviceDependencies.json │ └── serviceDependencies.local.json ├── Startup.cs ├── WebAPI │ ├── WebApiControllerBase.cs │ └── v1 │ │ ├── AccountsModule │ │ ├── BankAccountController.BankAccountCreateRequestDto.cs │ │ ├── BankAccountController.BankAccountResponseDto.cs │ │ ├── BankAccountController.BankAccountTransactionResponseDto.cs │ │ ├── BankAccountController.BankAccountUpdateRequestDto.cs │ │ ├── BankAccountController.cs │ │ ├── BankAccountInfoController.BankAccountInfoResponseDto.cs │ │ ├── BankAccountInfoController.cs │ │ ├── BankAccountTypeController.BankAccountTypeResponseDto.cs │ │ ├── BankAccountTypeController.cs │ │ ├── BankController.BankCreateRequestDto.cs │ │ ├── BankController.BankResponseDto.cs │ │ ├── BankController.BankUpdateRequestDto.cs │ │ └── BankController.cs │ │ ├── AssetRegisterModule │ │ ├── AssetController.AssetResponseDto.cs │ │ └── AssetController.cs │ │ ├── BudgetModule │ │ ├── BudgetController.BudgetResponseDto.cs │ │ └── BudgetController.cs │ │ ├── CalendarModule │ │ ├── ReminderController.ReminderResponseDto.cs │ │ └── ReminderController.cs │ │ ├── ContactsModule │ │ ├── ContactController.ContactCreateRequestDto.cs │ │ ├── ContactController.ContactResponseDto.cs │ │ ├── ContactController.ContactUpdateRequestDto.cs │ │ └── ContactController.cs │ │ ├── CoreModule │ │ ├── CurrencyController.CurrencyCreateRequestDto.cs │ │ ├── CurrencyController.CurrencyResponseDto.cs │ │ ├── CurrencyController.CurrencyUpdateRequestDto.cs │ │ └── CurrencyController.cs │ │ ├── DocumentsModule │ │ ├── DocumentController.DocumentResponseDto.cs │ │ └── DocumentController.cs │ │ ├── MailModule │ │ ├── MailMessageController.MailMessageResponseDto.cs │ │ └── MailMessageController.cs │ │ ├── MappingProfile.cs │ │ └── TasksModule │ │ ├── TaskListController.TaskListResponseDto.cs │ │ └── TaskListController.cs ├── appsettings.Development.json └── appsettings.json ├── AdminAssistant.Blazor.Webasm ├── AdminAssistant.Blazor.Webasm.csproj ├── App.razor ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Modules │ ├── AccountsModule │ │ ├── Accounts.razor │ │ ├── Admin │ │ │ └── BankListComponent.razor │ │ ├── BankAccountBalanceListComponent.razor │ │ ├── BankAccountEditDialogComponent.razor │ │ ├── BankAccountEditDialogComponent.razor.css │ │ ├── BankAccountRightSidebarComponent.razor │ │ ├── BankAccountTransactionBulkUploadComponent.razor │ │ └── BankAccountTransactionListComponent.razor │ ├── AdminAssistantModuleComponentBase.cs │ ├── AdminModule │ │ └── Admin.razor │ ├── AssetRegisterModule │ │ └── AssetRegister.razor │ ├── BillingModule │ │ └── Billing.razor │ ├── BudgetModule │ │ └── Budget.razor │ ├── CalendarModule │ │ └── Calendar.razor │ ├── ContactsModule │ │ └── Contacts.razor │ ├── CoreModule │ │ └── Admin │ │ │ └── CurrencyListComponent.razor │ ├── DashboardModule │ │ └── Dashboard.razor │ ├── DocumentsModule │ │ └── Documents.razor │ ├── MailModule │ │ └── Mail.razor │ ├── NotesModule │ │ └── Notes.razor │ ├── ReportsModule │ │ └── Reports.razor │ └── TasksModule │ │ └── Tasks.razor ├── Program.cs ├── Properties │ └── launchSettings.json ├── Shared │ ├── AdminAssistantComponentBase.cs │ ├── AdminAssistantLayoutComponentBase.cs │ └── MainLayout.razor ├── _Imports.razor └── wwwroot │ ├── appsettings.example.json │ ├── appsettings.json │ ├── assets │ ├── css │ │ ├── font-awesome.css │ │ ├── font-awesome.min.css │ │ └── loading.css │ └── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── favicon.ico │ ├── icon-192.png │ ├── icon-512.png │ ├── index.html │ ├── manifest.json │ ├── service-worker.js │ └── service-worker.published.js ├── AdminAssistant.DomainModel ├── AdminAssistant.DomainModel.csproj ├── Constants.cs ├── DependencyInjectionExtensions.cs ├── Factory.cs ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── MappingProfile.cs ├── Modules │ ├── AccountsModule │ │ ├── Bank.cs │ │ ├── BankAccount.cs │ │ ├── BankAccountInfo.cs │ │ ├── BankAccountStatement.cs │ │ ├── BankAccountTransaction.cs │ │ ├── BankAccountTransactionType.cs │ │ ├── BankAccountType.cs │ │ ├── Builders │ │ │ ├── BankAccountBuilder.cs │ │ │ ├── BankAccountInfoBuilder.cs │ │ │ ├── BankAccountTransactionBuilder.cs │ │ │ ├── BankAccountTypeBuilder.cs │ │ │ ├── BankBuilder.cs │ │ │ └── PayeeBuilder.cs │ │ ├── Payee.cs │ │ ├── PayeeContact.cs │ │ └── Validation │ │ │ ├── BankAccountTransactionValidator.cs │ │ │ ├── BankAccountTypeValidator.cs │ │ │ ├── BankAccountValidator.cs │ │ │ ├── BankValidator.cs │ │ │ └── PayeeValidator.cs │ ├── AssetRegisterModule │ │ ├── Asset.cs │ │ └── Builders │ │ │ └── AssetBuilder.cs │ ├── BudgetModule │ │ ├── Budget.cs │ │ ├── Builders │ │ │ └── BudgetBuilder.cs │ │ └── Validation │ │ │ └── BudgetValidator.cs │ ├── CalendarModule │ │ ├── Builders │ │ │ └── ReminderBuilder.cs │ │ └── Reminder.cs │ ├── ContactsModule │ │ ├── Builders │ │ │ └── ContactBuilder.cs │ │ ├── Contact.cs │ │ └── Validation │ │ │ └── ContactValidator.cs │ ├── CoreModule │ │ ├── Builders │ │ │ └── CurrencyBuilder.cs │ │ ├── Company.cs │ │ ├── Currency.cs │ │ └── Validation │ │ │ └── CurrencyValidator.cs │ ├── DocumentsModule │ │ ├── Builders │ │ │ └── DocumentBuilder.cs │ │ └── Document.cs │ ├── MailModule │ │ ├── Builders │ │ │ └── MailMessageBuilder.cs │ │ └── MailMessage.cs │ └── TasksModule │ │ ├── Builders │ │ └── TaskListBuilder.cs │ │ └── TaskList.cs └── Shared │ ├── ConfigurationSettings.cs │ ├── DatabaseProvider.cs │ ├── EntityDescription.cs │ ├── EntityName.cs │ ├── User.cs │ ├── UserContextProvider.cs │ └── Validation │ └── FluentValidationRuleBuilderExtensions.cs ├── AdminAssistant.Infra.ClientSide ├── AdminAssistant.Infra.ClientSide.csproj ├── DependencyInjectionExtensions.cs ├── GlobalSuppressions.cs └── Infrastructure │ └── Providers │ ├── ClientSideLoggingProvider.cs │ ├── DateTimeProvider.cs │ ├── LoggingProvider.cs │ └── PdfFileProvider.cs ├── AdminAssistant.Infra.WebAPIClient ├── AdminAssistant.Infra.WebAPIClient.csproj ├── DependencyInjectionExtensions.cs ├── nswag.json └── swagger.json ├── AdminAssistant.Infra ├── AdminAssistant.Infra.csproj ├── DependencyInjectionExtensions.cs ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Infrastructure │ ├── DAL │ │ ├── IReadOnlyChildRepository.cs │ │ ├── IReadOnlyRepository.cs │ │ ├── IRepository.cs │ │ └── RepositoryBase.cs │ ├── EntityFramework │ │ ├── ApplicationDbContext .cs │ │ ├── ApplicationDbContext .md │ │ ├── Migrations │ │ │ ├── Postgres │ │ │ │ ├── 20230709185539_Initial.Designer.cs │ │ │ │ ├── 20230709185539_Initial.cs │ │ │ │ └── PostgresApplicationDbContextModelSnapshot.cs │ │ │ └── SqlServer │ │ │ │ ├── 20201019144909_Initial.Designer.cs │ │ │ │ ├── 20201019144909_Initial.cs │ │ │ │ ├── ApplicationDbContextModelSnapshot.cs │ │ │ │ └── Initial.sql │ │ ├── Model │ │ │ ├── Accounts │ │ │ │ ├── BankAccountEntity.cs │ │ │ │ ├── BankAccountStatementEntity.cs │ │ │ │ ├── BankAccountTransactionDocumentEntity.cs │ │ │ │ ├── BankAccountTransactionEntity.cs │ │ │ │ ├── BankAccountTransactionTypeEntity.cs │ │ │ │ ├── BankAccountTypeEntity.cs │ │ │ │ ├── BankEntity.cs │ │ │ │ ├── PayeeContactEntity.cs │ │ │ │ └── PayeeEntity.cs │ │ │ ├── AccountsSchema.cs │ │ │ ├── AssetRegister │ │ │ │ ├── AssetEntity.cs │ │ │ │ └── ManufacturerEntity.cs │ │ │ ├── AssetRegisterSchema.cs │ │ │ ├── Billing │ │ │ │ ├── ClientEntity.cs │ │ │ │ ├── InvoiceEntity.cs │ │ │ │ └── SupplierEntity.cs │ │ │ ├── BillingSchema.cs │ │ │ ├── Budget │ │ │ │ ├── BudgetEntity.cs │ │ │ │ └── BudgetEntryEntity.cs │ │ │ ├── BudgetSchema.cs │ │ │ ├── Calendar │ │ │ │ └── AppointmentEntity.cs │ │ │ ├── CalendarSchema.cs │ │ │ ├── Contacts │ │ │ │ ├── AddressEntity.cs │ │ │ │ ├── ContactAddressEntity.cs │ │ │ │ └── ContactEntity.cs │ │ │ ├── ContactsSchema.cs │ │ │ ├── Core │ │ │ │ ├── AuditEntity.cs │ │ │ │ ├── CompanyEntity.cs │ │ │ │ ├── CurrencyEntity.cs │ │ │ │ ├── OwnerEntity.cs │ │ │ │ ├── PermissionEntity.cs │ │ │ │ ├── PersonalDetailsEntity.cs │ │ │ │ ├── SettingEntity.cs │ │ │ │ ├── UserProfileEntity.cs │ │ │ │ ├── UserProfilePermissionEntity.cs │ │ │ │ └── UserProfileSettingEntity.cs │ │ │ ├── CoreSchema.cs │ │ │ ├── Documents │ │ │ │ └── DocumentEntity.cs │ │ │ ├── DocumentsSchema.cs │ │ │ ├── Grocery │ │ │ │ ├── GroceryItemEntity.cs │ │ │ │ └── MealPlanEntity.cs │ │ │ ├── GrocerySchema.cs │ │ │ ├── Tasks │ │ │ │ └── TaskEntity.cs │ │ │ └── TasksSchema.cs │ │ ├── PostgresApplicationDbContext.cs │ │ ├── SqlServerApplicationDbContext.cs │ │ └── SqliteApplicationDbContext.cs │ ├── MappingProfile.cs │ ├── MediatR │ │ └── LoggingBehaviour.cs │ └── Providers │ │ └── ServerSideLoggingProvider.cs └── Modules │ ├── AccountsModule │ └── Infrastructure │ │ └── DAL │ │ ├── BankAccountInfoRepository.cs │ │ ├── BankAccountRepository.cs │ │ ├── BankAccountTransactionRepository.cs │ │ ├── BankAccountTypeRepository.cs │ │ └── BankRepository.cs │ ├── ContactsModule │ └── Infrastructure │ │ └── DAL │ │ └── ContactRepository.cs │ ├── CoreModule │ └── Infrastructure │ │ └── DAL │ │ └── CurrencyRepository.cs │ └── DocumentsModule │ └── Infrastructure │ └── DAL │ └── DocumentRepository.cs ├── AdminAssistant.Retro ├── AdminAssistant.Retro.csproj ├── DependencyInjectionExtensions.cs ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Modules │ ├── Accounts │ │ └── BankAccountEditDialog.cs │ └── Core │ │ └── CurrencyListComponent.cs ├── Program.cs └── Shared │ └── DialogWindowBase.cs ├── AdminAssistant.Test ├── .config │ └── dotnet-tools.json ├── .runsettings ├── AcceptanceTestBase.cs ├── AdminAssistant.Test.csproj ├── Architecture │ ├── ArchitecturePolicyEvaluationReportingExtensions.cs │ └── Architecture_Test.cs ├── AutoMapper_DalMappingProfile_UnitTest.cs ├── AutoMapper_WebApiClientMappingProfile_UnitTest.cs ├── AutoMapper_WebApiMappingProfile_UnitTest.cs ├── DependencyInjectionExtensions.cs ├── DependencyInjectionExtensions_UnitTest.cs ├── DomainModel │ └── Modules │ │ ├── AccountsModule │ │ ├── CQRS │ │ │ ├── BankAccountByIDQuery_UnitTest.cs │ │ │ ├── BankAccountCreateCommand_UnitTest.cs │ │ │ ├── BankAccountInfoQuery_UnitTest.cs │ │ │ ├── BankAccountTransactionsByBankAccountIDQuery_UnitTest.cs │ │ │ ├── BankAccountTypesQuery_UnitTest.cs │ │ │ ├── BankAccountUpdateCommand_UnitTest.cs │ │ │ ├── BankByIDQuery_UnitTest.cs │ │ │ ├── BankCreateCommand_UnitTest.cs │ │ │ ├── BankQuery_UnitTest.cs │ │ │ └── BankUpdateCommand_UnitTest.cs │ │ └── Validation │ │ │ ├── BankAccountTransactionValidator_UnitTest.cs │ │ │ ├── BankAccountTypeValidator_UnitTest.cs │ │ │ ├── BankAccountValidator_UnitTest.cs │ │ │ ├── BankValidator_UnitTest.cs │ │ │ └── PayeeValidator_UnitTest.cs │ │ ├── BudgetModule │ │ └── Validation │ │ │ └── BudgetValidator_UnitTest.cs │ │ ├── ContactsModule │ │ ├── CQRS │ │ │ ├── ContactByIDQuery_UnitTest.cs │ │ │ ├── ContactCreateCommand_UnitTest.cs │ │ │ └── ContactUpdateCommand_UnitTest.cs │ │ └── Validation │ │ │ └── ContactValidator_UnitTest.cs │ │ ├── CoreModule │ │ ├── CQRS │ │ │ ├── CurrenciesQuery_UnitTest.cs │ │ │ ├── CurrencyByIDQuery_UnitTest.cs │ │ │ ├── CurrencyCreateCommand_UnitTest.cs │ │ │ └── CurrencyUpdateCommand_UnitTest.cs │ │ └── Validation │ │ │ └── CurrencyValidator_UnitTest.cs │ │ └── DocumentsModule │ │ └── CQRS │ │ └── DocumentQuery_UnitTest.cs ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Infra │ ├── DAL │ │ └── Modules │ │ │ ├── AccountsModule │ │ │ ├── BankAccountRepository_UnitTest.cs │ │ │ └── BankAccountTypeRepository_UnitTest.cs │ │ │ ├── ContactsModule │ │ │ └── ContactRepository_unitTest.cs │ │ │ └── CoreModule │ │ │ └── CurrencyRepository_UnitTest.cs │ └── Providers │ │ └── PdfFileProvider_Tests.cs ├── IntegrationTestBase.cs ├── Properties │ ├── serviceDependencies.json │ └── serviceDependencies.local.json ├── README.md ├── TestConstants.cs ├── UI │ └── Modules │ │ ├── AccountsModule │ │ ├── AccountsService_UnitTest.cs │ │ ├── BankAccountEditDialogViewModel_UnitTest.cs │ │ ├── BankAccountEditDialog_AcceptanceTest.cs │ │ └── BankEditDialogViewModel_UnitTest.cs │ │ ├── CoreModule │ │ └── CoreService_UnitTest.cs │ │ └── DocumentsModule │ │ └── DocumentsService_UnitTest.cs ├── WebAPI │ └── v1 │ │ ├── AccountsModule │ │ ├── BankAccountController_IntegrationTest.cs │ │ ├── BankAccountController_UnitTest.cs │ │ ├── BankAccountInfoController_IntegrationTest.cs │ │ ├── BankAccountInfoController_UnitTest.cs │ │ ├── BankAccountTypeController_IntegrationTest.cs │ │ ├── BankAccountTypeController_UnitTest.cs │ │ ├── BankController_IntegrationTest.cs │ │ └── BankController_UnitTest.cs │ │ ├── AssetRegisterModule │ │ └── AssetController_UnitTest.cs │ │ ├── BudgetModule │ │ └── BudgetController_UnitTest.cs │ │ ├── CalendarModule │ │ └── ReminderController_UnitTest.cs │ │ ├── ContactsModule │ │ └── ContactController_UnitTest.cs │ │ ├── CoreModule │ │ ├── CurrencyController_IntegrationTest.cs │ │ └── CurrencyController_UnitTest.cs │ │ ├── DocumentsModule │ │ ├── DocumentController_IntegrationTest.cs │ │ └── DocumentController_UnitTest.cs │ │ ├── MailModule │ │ └── MailMessageController_UnitTest.cs │ │ └── TasksModule │ │ └── TaskListController_UnitTest.cs └── stryker-config.json ├── AdminAssistant.UI ├── AdminAssistant.UI.csproj ├── DependencyInjectionExtensions.cs ├── GlobalSuppressions.cs ├── GlobalUsings.cs ├── Modules │ ├── AccountsModule │ │ ├── AdminUI │ │ │ └── BankListViewModel.cs │ │ └── UI │ │ │ ├── AccountsService.cs │ │ │ ├── AccountsViewModel.cs │ │ │ ├── BankAccountBalanceListViewModel.cs │ │ │ ├── BankAccountEditDialogViewModel.cs │ │ │ ├── BankAccountRightSidebarViewModel.cs │ │ │ ├── BankAccountStatementImportViewModel.cs │ │ │ ├── BankAccountTransactionListViewModel.cs │ │ │ └── EditBankAccountMessage.cs │ ├── AdminModule │ │ └── AdminUI │ │ │ └── AdminViewModel.cs │ ├── AssetRegisterModule │ │ └── UI │ │ │ └── AssetRegisterViewModel.cs │ ├── BillingModule │ │ └── UI │ │ │ └── BillingViewModel.cs │ ├── BudgetModule │ │ └── UI │ │ │ └── BudgetViewModel.cs │ ├── CalendarModule │ │ └── UI │ │ │ └── CalendarViewModel.cs │ ├── ContactsModule │ │ └── UI │ │ │ └── ContactsViewModel.cs │ ├── CoreModule │ │ ├── AdminUI │ │ │ └── CurrencyListViewModel.cs │ │ └── UI │ │ │ └── CoreService.cs │ ├── DashboardModule │ │ └── UI │ │ │ └── DashboardViewModel.cs │ ├── DocumentsModule │ │ └── UI │ │ │ ├── DocumentsService.cs │ │ │ └── DocumentsViewModel.cs │ ├── MailModule │ │ └── UI │ │ │ └── MailViewModel.cs │ ├── NotesModule │ │ └── UI │ │ │ └── NotesViewModel.cs │ ├── ReportsModule │ │ └── UI │ │ │ └── ReportingViewModel.cs │ └── TasksModule │ │ └── UI │ │ └── TasksViewModel.cs ├── Primitives │ └── UI │ │ ├── IModuleViewModelBase.cs │ │ ├── ServiceBase.cs │ │ ├── ViewModelBase.cs │ │ └── ViewModelLocator.cs └── Shared │ ├── UI │ ├── AppService.cs │ ├── ExpandedContractedStateToggle.cs │ ├── FontAwesomeVersion.cs │ ├── MainWindowViewModel.cs │ ├── Mode.cs │ ├── ModeSelectionChangedMessage.cs │ ├── ModeSelectionItem.cs │ ├── Module.cs │ ├── ModuleSelectionChangedMessage.cs │ ├── ModuleSelectionItem.cs │ └── SidebarStateSettings.cs │ └── WebAPIClient │ └── v1 │ ├── AdminAssistant.WebAPI.nswag │ ├── AdminAssistantWebAPIClientCodeGen.cs │ ├── IAdminAssistantWebAPIClientCodeGen.cs │ └── MappingProfile.cs ├── AdminAssistant.WPF ├── AdminAssistant.WPF.csproj ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Modules │ ├── AccountsModule │ │ ├── AccountsComponent.xaml │ │ ├── AccountsComponent.xaml.cs │ │ ├── BankAccountBalanceListComponent.xaml │ │ ├── BankAccountBalanceListComponent.xaml.cs │ │ ├── BankAccountEditDialog.xaml │ │ ├── BankAccountEditDialog.xaml.cs │ │ ├── BankAccountRightSidebarComponent.xaml │ │ ├── BankAccountRightSidebarComponent.xaml.cs │ │ ├── BankAccountTransactionListComponent.xaml │ │ └── BankAccountTransactionListComponent.xaml.cs │ ├── Admin │ │ ├── AdminComponent.xaml │ │ └── AdminComponent.xaml.cs │ ├── AssetRegisterModule │ │ ├── AssetRegisterComponent.xaml │ │ └── AssetRegisterComponent.xaml.cs │ ├── BillingModule │ │ ├── BillingComponent.xaml │ │ └── BillingComponent.xaml.cs │ ├── BudgetModule │ │ ├── BudgetComponent.xaml │ │ └── BudgetComponent.xaml.cs │ ├── CalendarModule │ │ ├── CalendarComponent.xaml │ │ └── CalendarComponent.xaml.cs │ ├── ContactsModule │ │ ├── ContactsComponent.xaml │ │ └── ContactsComponent.xaml.cs │ ├── DashboardModule │ │ ├── DashboardComponent.xaml │ │ └── DashboardComponent.xaml.cs │ ├── DocumentsModule │ │ ├── DocumentsComponent.xaml │ │ └── DocumentsComponent.xaml.cs │ ├── MailModule │ │ ├── MailComponent.xaml │ │ └── MailComponent.xaml.cs │ ├── ReportsModule │ │ ├── ReportsComponent.xaml │ │ └── ReportsComponent.xaml.cs │ └── TasksModule │ │ ├── TasksComponent.xaml │ │ └── TasksComponent.xaml.cs └── Shared │ ├── ModeExtensions.cs │ ├── ModeImageExtension.cs │ ├── ModeSelectionItemToIconImageConverter.cs │ ├── ModeToIconImageConverter.cs │ ├── ModuleExtensions.cs │ ├── ModuleImageExtension.cs │ └── ModuleToIconImageConverter.cs ├── AdminAssistant.code-workspace ├── AdminAssistant.sln ├── AdminAssistant.sln.DotSettings ├── AdminAssistant_Windows.sln ├── Directory.Build.props ├── Directory.Packages.props ├── SimonGeering.Framework ├── ApplicationBaseExceptionBase.cs ├── Configuration │ └── ConfigurationException.cs ├── Constants.cs ├── GlobalSuppressions.cs ├── Primitives │ ├── DomainEntity.cs │ ├── IDatabasePersistable.cs │ ├── Id.cs │ └── ValueObject.cs ├── SimonGeering.Framework.csproj └── TypeMapping │ ├── IMapFrom.cs │ ├── IMapTo.cs │ ├── MappingProfileBase.cs │ └── TypeMappingException.cs ├── database.dbml ├── dev.template.env ├── global.json └── uml ├── AdminAssistant.EAP ├── ComponentDependencies.mmd └── Database Schema Design.mmd /DevOps/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Simon Geering 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docfx_project/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # folder # 3 | ############### 4 | /**/DROP/ 5 | /**/TEMP/ 6 | /**/packages/ 7 | /**/bin/ 8 | /**/obj/ 9 | _site 10 | -------------------------------------------------------------------------------- /docfx_project/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownlint.config": { 3 | "MD028": false, 4 | "MD025": { 5 | "front_matter_title": "" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /docfx_project/api/.gitignore: -------------------------------------------------------------------------------- 1 | ############### 2 | # temp file # 3 | ############### 4 | *.yml 5 | .manifest 6 | -------------------------------------------------------------------------------- /docfx_project/api/index.md: -------------------------------------------------------------------------------- 1 | # PLACEHOLDER 2 | TODO: Add .NET projects to the *src* folder and run `docfx` to generate **REAL** *API Documentation*! 3 | -------------------------------------------------------------------------------- /docfx_project/articles/Architecture.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | ## Overview 4 | 5 | _TODO: Add a brief overview of describing the application architecture here._ 6 | 7 | ## System Architecture Diagram 8 | 9 | The following diagram gives an overview of the Admin Assistant system architecture as it would be when deployed in production on the Microsoft Azure Cloud Platform. 10 | 11 | [![Admin Assistant System Architecture Diagram](../images/Architecture/System-Architecture-Diagram_V1o0o0.png)](https://simongeering.github.io/AdminAssistant/images/Architecture/System-Architecture-Diagram_V1o0o0.png) 12 | _Fig 1. System Architecture Diagram for the Admin Assistant Application - (Click for larger size)_ 13 | 14 | ## Component Dependency Diagram 15 | 16 | The following diagram shows the relationships between the various components of the Admin Assistant system. 17 | 18 | [![Admin Assistant UML Component Diagram](../images/Architecture/Component-Diagram_V1o0o0.png)](https://simongeering.github.io/AdminAssistant/images/Architecture/Component-Diagram_V1o0o0.png) 19 | _Fig 2. UML Component Diagram for the Admin Assistant Application - (Click for larger size)_ 20 | -------------------------------------------------------------------------------- /docfx_project/articles/Dashboard-Module.md: -------------------------------------------------------------------------------- 1 | | [Issues](https://github.com/SimonGeering/AdminAssistant/milestone/19) | [Project Plan](https://github.com/SimonGeering/AdminAssistant/projects/9) | 2 | 3 | *** 4 | 5 | # Overview 6 | 7 | TODO 8 | 9 | ## Use Case Diagram 10 | 11 | TODO 12 | 13 | # User Stories 14 | 15 | - [ ] [My Example User Story](## My Example User Story) - See [Issue #xxx](https://github.com/SimonGeering/AdminAssistant/issues/xxx) 16 | 17 | ## My Example User Story 18 | 19 | ``` Gherkin 20 | Feature: Feature name 21 | # As a 22 | # I want to 23 | # So I can 24 | ``` 25 | 26 | # UI Design 27 | 28 | a - [Example Screen Name](###Example Screen Name) 29 | 30 | ## Screen Mockups 31 | 32 | ### Example Screen Name 33 | 34 | TODO 35 | 36 | # Database Schema 37 | 38 | TODO 39 | -------------------------------------------------------------------------------- /docfx_project/articles/Mail-Module.md: -------------------------------------------------------------------------------- 1 | | [Issues](https://github.com/SimonGeering/AdminAssistant/milestone/7) | [Project Plan](https://github.com/SimonGeering/AdminAssistant/projects/11) | 2 | 3 | *** 4 | 5 | # Overview 6 | 7 | TODO 8 | 9 | ## Use Case Diagram 10 | 11 | TODO 12 | 13 | # User Stories 14 | 15 | - [ ] [My Example User Story](## My Example User Story) - See [Issue #xxx](https://github.com/SimonGeering/AdminAssistant/issues/xxx) 16 | - [ ] Create Draft Mail Message - See [Issue #96](https://github.com/SimonGeering/AdminAssistant/issues/96) 17 | - [ ] Get MailMessage List - See [Issue #130](https://github.com/SimonGeering/AdminAssistant/issues/130) 18 | 19 | ## My Example User Story 20 | 21 | ``` Gherkin 22 | Feature: Feature name 23 | # As a 24 | # I want to 25 | # So I can 26 | ``` 27 | 28 | # UI Design 29 | 30 | a - [Example Screen Name](###Example Screen Name) 31 | 32 | ## Screen Mockups 33 | 34 | ### Example Screen Name 35 | 36 | TODO 37 | 38 | # Database Schema 39 | 40 | TODO 41 | -------------------------------------------------------------------------------- /docfx_project/articles/Reports-Module.md: -------------------------------------------------------------------------------- 1 | | [Issues](https://github.com/SimonGeering/AdminAssistant/milestone/10) | [Project Plan](https://github.com/SimonGeering/AdminAssistant/projects/16) | 2 | 3 | *** 4 | 5 | # Overview 6 | 7 | TODO 8 | 9 | ## Use Case Diagram 10 | 11 | TODO 12 | 13 | # User Stories 14 | 15 | - [ ] [My Example User Story](## My Example User Story) - See [Issue #xxx](https://github.com/SimonGeering/AdminAssistant/issues/xxx) 16 | 17 | ## My Example User Story 18 | 19 | ``` Gherkin 20 | Feature: Feature name 21 | # As a 22 | # I want to 23 | # So I can 24 | ``` 25 | 26 | # UI Design 27 | 28 | a - [Example Screen Name](###Example Screen Name) 29 | 30 | ## Screen Mockups 31 | 32 | ### Example Screen Name 33 | 34 | TODO 35 | 36 | # Database Schema 37 | 38 | TODO 39 | -------------------------------------------------------------------------------- /docfx_project/articles/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Architecture 2 | href: Architecture.md 3 | - name: Design Decisions 4 | href: Design-Notes.md 5 | - name: CLI Tools 6 | href: Misc-CLI-Tools.md 7 | - name: Individual Modules 8 | items: 9 | - name: Dashboard 10 | href: Dashboard-Module.md 11 | - name: Accounts 12 | href: Accounts-Module.md 13 | - name: Asset Register 14 | href: Asset-Register-Module.md 15 | - name: Budget 16 | href: Budget-Module.md 17 | - name: Mail 18 | href: Mail-Module.md 19 | - name: Calendar 20 | href: Calendar-Module.md 21 | - name: Contacts 22 | href: Contacts-Module.md 23 | - name: Tasks 24 | href: Tasks-Module.md 25 | - name: Documents 26 | href: Documents-Module.md 27 | - name: Reports 28 | href: Reports-Module.md 29 | - name: Core 30 | href: Core-Module.md 31 | -------------------------------------------------------------------------------- /docfx_project/assets/test.drawio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/assets/test.drawio -------------------------------------------------------------------------------- /docfx_project/assets/ux/AdminAssistantUIDesign.epgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/assets/ux/AdminAssistantUIDesign.epgz -------------------------------------------------------------------------------- /docfx_project/images/Accounts-Module/AccountsModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Accounts-Module/AccountsModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Architecture/Component-Diagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Architecture/Component-Diagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Architecture/System-Architecture-Diagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Architecture/System-Architecture-Diagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Asset-Register-Module/AssetsRegisterModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Asset-Register-Module/AssetsRegisterModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Budget-Module/BudgetModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Budget-Module/BudgetModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Calendar-Module/CalendarModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Calendar-Module/CalendarModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Contacts-Module/ContactsModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Contacts-Module/ContactsModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Core-Module/CoreModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Core-Module/CoreModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Documents-Module/DocumentsModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Documents-Module/DocumentsModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/images/Food-Module/Food_Module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Food-Module/Food_Module.png -------------------------------------------------------------------------------- /docfx_project/images/Tasks-Module/TasksModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docfx_project/images/Tasks-Module/TasksModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docfx_project/index.md: -------------------------------------------------------------------------------- 1 | # This is the **HOMEPAGE**. 2 | Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. 3 | ## Quick Start Notes: 4 | 1. Add images to the *images* folder if the file is referencing an image. 5 | -------------------------------------------------------------------------------- /docfx_project/toc.yml: -------------------------------------------------------------------------------- 1 | - name: Articles 2 | href: articles/ 3 | - name: Api Documentation 4 | href: api/ 5 | homepage: index.md 6 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/favicon.ico -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /docs/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /docs/images/Accounts-Module/AccountsModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Accounts-Module/AccountsModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Architecture/Component-Diagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Architecture/Component-Diagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Architecture/System-Architecture-Diagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Architecture/System-Architecture-Diagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Asset-Register-Module/AssetsRegisterModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Asset-Register-Module/AssetsRegisterModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Budget-Module/BudgetModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Budget-Module/BudgetModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Calendar-Module/CalendarModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Calendar-Module/CalendarModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Contacts-Module/ContactsModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Contacts-Module/ContactsModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Core-Module/CoreModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Core-Module/CoreModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Documents-Module/DocumentsModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Documents-Module/DocumentsModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/images/Food-Module/Food_Module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Food-Module/Food_Module.png -------------------------------------------------------------------------------- /docs/images/Tasks-Module/TasksModule_EntityRelationshipDiagram_V1o0o0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/images/Tasks-Module/TasksModule_EntityRelationshipDiagram_V1o0o0.png -------------------------------------------------------------------------------- /docs/styles/main.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/docs/styles/main.css -------------------------------------------------------------------------------- /docs/styles/main.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. 2 | -------------------------------------------------------------------------------- /docs/toc.html: -------------------------------------------------------------------------------- 1 |  2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 | 22 |
23 |
24 |
25 |
-------------------------------------------------------------------------------- /src/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-ef": { 6 | "version": "8.0.0", 7 | "commands": [ 8 | "dotnet-ef" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/AdminAssistant.Application/AdminAssistant.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AdminAssistant.Application.docs.xml 5 | $(NoWarn); 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/DependencyInjectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant; 2 | 3 | namespace Microsoft.Extensions.DependencyInjection; 4 | 5 | public static partial class DependencyInjectionExtensions 6 | { 7 | public static IServiceCollection AddAdminAssistantApplication(this IServiceCollection services) 8 | { 9 | // Set-up / Add MediatR based on an assembly marker type ... 10 | services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(RequestHandlerBase<,>).Assembly)); 11 | return services; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using AdminAssistant.Infrastructure.Providers; 2 | global using Ardalis.Result; 3 | global using Ardalis.Result.FluentValidation; 4 | global using MediatR; 5 | global using Trace = System.Diagnostics.Trace; 6 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Commands/BankCreateCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | using AdminAssistant.Modules.AccountsModule.Validation; 3 | 4 | namespace AdminAssistant.Modules.AccountsModule.Commands; 5 | 6 | public sealed record BankCreateCommand(Bank Bank) : IRequest>; 7 | 8 | internal sealed class BankCreateCommandHandler( 9 | ILoggingProvider loggingProvider, 10 | IBankRepository bankRepository, 11 | IBankValidator bankValidator) 12 | : RequestHandlerBase>(loggingProvider) 13 | { 14 | public override async Task> Handle(BankCreateCommand command, CancellationToken cancellationToken) 15 | { 16 | var validationResult = await bankValidator.ValidateAsync(command.Bank, cancellationToken).ConfigureAwait(false); 17 | 18 | if (validationResult.IsValid == false) 19 | { 20 | return Result.Invalid(validationResult.AsErrors()); 21 | } 22 | 23 | var result = await bankRepository.SaveAsync(command.Bank, cancellationToken).ConfigureAwait(false); 24 | return Result.Success(result); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Commands/BankUpdateCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Infrastructure.Providers; 2 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 3 | using AdminAssistant.Modules.AccountsModule.Validation; 4 | 5 | namespace AdminAssistant.Modules.AccountsModule.Commands; 6 | 7 | public sealed record BankUpdateCommand(Bank Bank) : IRequest>; 8 | 9 | internal sealed class BankUpdateCommandHandler( 10 | ILoggingProvider loggingProvider, 11 | IBankRepository bankRepository, 12 | IBankValidator bankValidator) 13 | : RequestHandlerBase>(loggingProvider) 14 | { 15 | public override async Task> Handle(BankUpdateCommand command, CancellationToken cancellationToken) 16 | { 17 | var validationResult = await bankValidator.ValidateAsync(command.Bank, cancellationToken).ConfigureAwait(false); 18 | 19 | if (validationResult.IsValid == false) 20 | { 21 | return Result.Invalid(validationResult.AsErrors()); 22 | } 23 | 24 | var result = await bankRepository.SaveAsync(command.Bank, cancellationToken).ConfigureAwait(false); 25 | return Result.Success(result); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/BankAccountByIDQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Queries; 4 | 5 | internal sealed class BankAccountByIDQueryHandler(ILoggingProvider loggingProvider, IBankAccountRepository bankAccountRepository) 6 | : RequestHandlerBase>(loggingProvider) 7 | { 8 | public override async Task> Handle(BankAccountByIDQuery request, CancellationToken cancellationToken) 9 | { 10 | var bankAccount = await bankAccountRepository.GetAsync(new(request.BankAccountID), cancellationToken).ConfigureAwait(false); 11 | 12 | if (bankAccount == null || bankAccount.BankAccountID.IsUnknownRecordID) 13 | return Result.NotFound(); 14 | 15 | return Result.Success(bankAccount); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/BankAccountInfoQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Queries; 4 | 5 | internal sealed class BankAccountInfoQueryHandler( 6 | IBankAccountInfoRepository bankAccountInfoRepository, 7 | ILoggingProvider loggingProvider) 8 | : RequestHandlerBase>>(loggingProvider) 9 | { 10 | public override async Task>> Handle(BankAccountInfoQuery request, CancellationToken cancellationToken) 11 | { 12 | // TODO: implement owned entities - pass in request.OwnerID 13 | var bankAccountInfoList = await bankAccountInfoRepository.GetListAsync(cancellationToken).ConfigureAwait(false); 14 | return Result>.Success(bankAccountInfoList); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/BankAccountTransactionsByBankAccountIDQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Queries; 4 | 5 | internal sealed class BankAccountTransactionsByBankAccountIDQueryHandler( 6 | IBankAccountTransactionRepository bankAccountTransactionRepository, 7 | ILoggingProvider loggingProvider) 8 | : RequestHandlerBase>>(loggingProvider) 9 | { 10 | public override async Task>> Handle(BankAccountTransactionsByBankAccountIDQuery request, CancellationToken cancellationToken) 11 | { 12 | var bankAccountTransactionList = await bankAccountTransactionRepository.GetListAsync(request.BankAccountID, cancellationToken).ConfigureAwait(false); 13 | 14 | if (bankAccountTransactionList == null || bankAccountTransactionList.Count == 0) 15 | return Result>.NotFound(); 16 | 17 | return Result>.Success(bankAccountTransactionList); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/BankAccountTypesQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Queries; 4 | 5 | internal sealed class BankAccountTypesQueryHandler( 6 | IBankAccountTypeRepository bankAccountTypeRepository, 7 | ILoggingProvider loggingProvider) 8 | : RequestHandlerBase>>(loggingProvider) 9 | { 10 | public override async Task>> Handle(BankAccountTypesQuery request, CancellationToken cancellationToken) 11 | { 12 | var result = await bankAccountTypeRepository.GetListAsync(cancellationToken).ConfigureAwait(false); 13 | 14 | Trace.Assert(result.Count > 0, "BankAccountType list was not populated."); 15 | 16 | return Result>.Success(result); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/BankByIDQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Queries; 4 | 5 | internal sealed class BankByIDQueryHandler(IBankRepository bankRepository, ILoggingProvider loggingProvider) 6 | : RequestHandlerBase>(loggingProvider) 7 | { 8 | public override async Task> Handle(BankByIDQuery request, CancellationToken cancellationToken) 9 | { 10 | var result = await bankRepository.GetAsync(new BankId(request.BankID), cancellationToken).ConfigureAwait(false); 11 | 12 | if (result == null || result.BankID.IsUnknownRecordID) 13 | return Result.NotFound(); 14 | 15 | return Result.Success(result); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/BankQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Queries; 4 | 5 | internal sealed class BankQueryHandler(IBankRepository bankRepository, ILoggingProvider loggingProvider) 6 | : RequestHandlerBase>>(loggingProvider) 7 | { 8 | public override async Task>> Handle(BankQuery request, CancellationToken cancellationToken) 9 | { 10 | var result = await bankRepository.GetListAsync(cancellationToken).ConfigureAwait(false); 11 | 12 | Trace.Assert(result.Count > 0, "Bank list was not populated."); 13 | 14 | return Result>.Success(result); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AccountsModule/Queries/Queries.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Queries 2 | { 3 | public sealed record BankAccountByIDQuery(int BankAccountID) : IRequest>; 4 | public sealed record BankAccountInfoQuery(int OwnerID) : IRequest>>; 5 | public sealed record BankAccountTypesQuery : IRequest>>; 6 | public sealed record BankAccountTransactionsByBankAccountIDQuery(int BankAccountID) : IRequest>>; 7 | public sealed record BankByIDQuery(int BankID) : IRequest>; 8 | public sealed record BankQuery : IRequest>>; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/AssetRegisterModule/Queries/Queries.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AssetRegisterModule.Queries; 2 | 3 | public sealed record AssetQuery : IRequest>>; 4 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/BudgetModule/Queries/Queries.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.BudgetModule.Queries; 2 | 3 | public sealed record BudgetQuery : IRequest>>; 4 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/CalendarModule/Queries/Queries.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CalendarModule.Queries; 2 | 3 | public sealed record ReminderQuery : IRequest>>; 4 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/ContactsModule/Commands/ContactCreateCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.ContactsModule.Infrastructure.DAL; 2 | using AdminAssistant.Modules.ContactsModule.Validation; 3 | 4 | namespace AdminAssistant.Modules.ContactsModule.Commands; 5 | 6 | public record ContactCreateCommand(Contact Contact) : IRequest>; 7 | 8 | internal sealed class ContactCreateCommandHandler( 9 | ILoggingProvider loggingProvider, 10 | IContactRepository contactRepository, 11 | IContactValidator contactValidator) 12 | : RequestHandlerBase>(loggingProvider) 13 | { 14 | public override async Task> Handle(ContactCreateCommand command, CancellationToken cancellationToken) 15 | { 16 | var validationResult = await contactValidator.ValidateAsync(command.Contact, cancellationToken).ConfigureAwait(false); 17 | 18 | if (validationResult.IsValid == false) 19 | { 20 | return Result.Invalid(validationResult.AsErrors()); 21 | } 22 | 23 | var result = await contactRepository.SaveAsync(command.Contact, cancellationToken).ConfigureAwait(false); 24 | return Result.Success(result); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/ContactsModule/Queries/ContactByIDQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.ContactsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.ContactsModule.Queries; 4 | 5 | public sealed record ContactQuery : IRequest>>; 6 | 7 | public sealed record ContactByIDQuery(int ContactID) : IRequest>; 8 | 9 | internal sealed class ContactByIDQueryHandler(ILoggingProvider loggingProvider, IContactRepository contactRepository) 10 | : RequestHandlerBase>(loggingProvider) 11 | { 12 | public override async Task> Handle(ContactByIDQuery request, CancellationToken cancellationToken) 13 | { 14 | var result = await contactRepository.GetAsync(new ContactId(request.ContactID), cancellationToken).ConfigureAwait(false); 15 | if (result == null || result.ContactID.IsUnknownRecordID) 16 | return Result.NotFound(); 17 | 18 | return Result.Success(result); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/CoreModule/Queries/CurrenciesQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.CoreModule.Queries; 4 | 5 | public sealed record CurrenciesQuery : IRequest>>; 6 | 7 | internal sealed class CurrenciesQueryHandler(ICurrencyRepository currencyRepository, ILoggingProvider loggingProvider) 8 | : RequestHandlerBase>>(loggingProvider) 9 | { 10 | public override async Task>> Handle(CurrenciesQuery request, CancellationToken cancellationToken) 11 | { 12 | var result = await currencyRepository.GetListAsync(cancellationToken).ConfigureAwait(false); 13 | 14 | Trace.Assert(result.Count > 0, "Currency list was not populated."); 15 | 16 | return Result>.Success(result); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/CoreModule/Queries/CurrencyByIDQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.CoreModule.Queries; 4 | 5 | public sealed record CurrencyByIDQuery(int CurrencyID) : IRequest>; 6 | 7 | internal sealed class CurrencyByIDQueryHandler(ICurrencyRepository currencyRepository, ILoggingProvider loggingProvider) 8 | : RequestHandlerBase>(loggingProvider) 9 | { 10 | public override async Task> Handle(CurrencyByIDQuery request, CancellationToken cancellationToken) 11 | { 12 | var result = await currencyRepository.GetAsync(new CurrencyId(request.CurrencyID), cancellationToken).ConfigureAwait(false); 13 | 14 | if (result == null || result.CurrencyID.IsUnknownRecordID) 15 | return Result.NotFound(); 16 | 17 | return Result.Success(result); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/DocumentsModule/Queries/DocumentQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.DocumentsModule.Infrastructure.DAL; 2 | 3 | namespace AdminAssistant.Modules.DocumentsModule.Queries; 4 | public sealed record DocumentQuery : IRequest>>; 5 | 6 | internal sealed class DocumentQueryHandler(IDocumentRepository repository, ILoggingProvider loggingProvider) 7 | : RequestHandlerBase>>(loggingProvider) 8 | { 9 | public override async Task>> Handle(DocumentQuery request, CancellationToken cancellationToken) 10 | { 11 | var result = await repository.GetListAsync(cancellationToken).ConfigureAwait(false); 12 | return Result>.Success(result); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/MailModule/Queries/Queries.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.MailModule.Queries 2 | { 3 | public sealed record MailMessageQuery : IRequest>>; 4 | } 5 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/Modules/TasksModule/Queries/Queries.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.TasksModule.Queries 2 | { 3 | public sealed record TaskListQuery : IRequest>>; 4 | } 5 | -------------------------------------------------------------------------------- /src/AdminAssistant.Application/RequestHandlerBase.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant; 2 | 3 | internal abstract class RequestHandlerBase : IRequestHandler 4 | where TRequest : IRequest 5 | { 6 | protected ILoggingProvider Log { get; } 7 | 8 | protected RequestHandlerBase(ILoggingProvider loggingProvider) => Log = loggingProvider; 9 | 10 | public abstract Task Handle(TRequest request, CancellationToken cancellationToken); 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using AdminAssistant.Infrastructure.Providers; 2 | global using Ardalis.Result; 3 | global using AutoMapper; 4 | global using MediatR; 5 | global using Microsoft.AspNetCore.Mvc; 6 | global using SimonGeering.Framework.TypeMapping; 7 | global using Swashbuckle.AspNetCore.Annotations; 8 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Blazor.Server; 2 | 3 | Host.CreateDefaultBuilder() 4 | .ConfigureLogging(logging => 5 | { 6 | logging.ClearProviders(); 7 | #if DEBUG 8 | logging.AddConsole(); 9 | logging.AddDebug(); 10 | 11 | logging.AddFilter("Default", LogLevel.Information) 12 | .AddFilter(ILoggingProvider.ServerSideLogCategory, LogLevel.Debug) 13 | .AddFilter("Microsoft", LogLevel.Warning) 14 | .AddFilter("Microsoft.Hosting.Lifetime", LogLevel.Information); 15 | #else 16 | logging.AddFilter("Default", LogLevel.Warning) 17 | .AddFilter(ILoggingProvider.ServerSideLogCategory, LogLevel.Warning) 18 | .AddFilter("Microsoft", LogLevel.Warning) 19 | .AddFilter("Microsoft.Hosting.Lifetime", LogLevel.Warning); 20 | 21 | // TODO: Configure production logging. 22 | #endif 23 | }) 24 | .ConfigureAppConfiguration((hostingContext, config) => config.AddCommandLine(args)) 25 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup()) 26 | .Build() 27 | .Run(); 28 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/Properties/serviceDependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "secrets1": { 4 | "type": "secrets" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/Properties/serviceDependencies.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "secrets1": { 4 | "type": "secrets.user" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/WebApiControllerBase.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.WebAPI; 2 | 3 | public abstract class WebApiControllerBase : ControllerBase 4 | { 5 | protected WebApiControllerBase(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 6 | { 7 | Mapper = mapper; 8 | Mediator = mediator; 9 | Log = loggingProvider; 10 | } 11 | 12 | protected IMapper Mapper { get; } 13 | protected IMediator Mediator { get; } 14 | protected ILoggingProvider Log { get; } 15 | } 16 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankAccountController.BankAccountCreateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 5 | 6 | [SwaggerSchema(Required = new[] { "BankAccountTypeID", "CurrencyID", "AccountName", "IsBudgeted", "OpeningBalance", "OpenedOn" })] 7 | public sealed record BankAccountCreateRequestDto : IMapTo 8 | { 9 | [SwaggerSchema("The BankAccountType for this BankAccount.")] 10 | public int BankAccountTypeID { get; init; } 11 | public int CurrencyID { get; init; } 12 | public string AccountName { get; init; } = string.Empty; 13 | public int Balance { get; init; } 14 | public bool IsBudgeted { get; init; } 15 | public int OpeningBalance { get; init; } 16 | public int CurrentBalance { get; init; } 17 | public DateTime OpenedOn { get; init; } 18 | 19 | public void MapTo(AutoMapper.Profile profile) 20 | => profile.CreateMap() 21 | .ForMember(x => x.BankAccountID, opt => opt.Ignore()) 22 | .ForMember(x => x.OwnerID, opt => opt.Ignore()); 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankAccountController.BankAccountResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 5 | 6 | public sealed record BankAccountResponseDto : IMapFrom 7 | { 8 | [SwaggerSchema("The BankAccount identifier.", ReadOnly = true)] 9 | public int BankAccountID { get; init; } 10 | [SwaggerSchema("The BankAccountType for this BankAccount.")] 11 | public int BankAccountTypeID { get; init; } 12 | public int CurrencyID { get; init; } 13 | public string AccountName { get; init; } = string.Empty; 14 | public bool IsBudgeted { get; init; } 15 | public int OpeningBalance { get; init; } 16 | public int CurrentBalance { get; init; } 17 | public DateTime OpenedOn { get; init; } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankAccountController.BankAccountUpdateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 5 | 6 | [SwaggerSchema(Required = new[] { "BankAccountID", "BankAccountTypeID", "CurrencyID", "AccountName", "IsBudgeted", "OpeningBalance", "OpenedOn" })] 7 | public sealed record BankAccountUpdateRequestDto : IMapTo 8 | { 9 | [SwaggerSchema("The BankAccount identifier.")] 10 | public int BankAccountID { get; init; } 11 | [SwaggerSchema("The BankAccountType for this BankAccount.")] 12 | public int BankAccountTypeID { get; init; } 13 | public int CurrencyID { get; init; } 14 | public string AccountName { get; init; } = string.Empty; 15 | public bool IsBudgeted { get; init; } 16 | public int OpeningBalance { get; init; } 17 | public int CurrentBalance { get; init; } 18 | public DateTime OpenedOn { get; init; } 19 | 20 | public void MapTo(AutoMapper.Profile profile) 21 | => profile.CreateMap() 22 | .ForMember(x => x.OwnerID, opt => opt.Ignore()); 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankAccountInfoController.BankAccountInfoResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 4 | 5 | public sealed record BankAccountInfoResponseDto : IMapFrom 6 | { 7 | public int BankAccountID { get; init; } 8 | public string AccountName { get; init; } = string.Empty; 9 | public int CurrentBalance { get; init; } 10 | public string Symbol { get; init; } = string.Empty; 11 | public string DecimalFormat { get; init; } = string.Empty; 12 | public bool IsBudgeted { get; init; } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankAccountTypeController.BankAccountTypeResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 4 | 5 | public sealed record BankAccountTypeResponseDto : IMapFrom 6 | { 7 | public int BankAccountTypeID { get; init; } 8 | public string Description { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankController.BankCreateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 5 | 6 | [SwaggerSchema(Required = new[] { "BankName" })] 7 | public sealed record BankCreateRequestDto : IMapTo 8 | { 9 | public string BankName { get; init; } = string.Empty; 10 | 11 | public void MapTo(AutoMapper.Profile profile) 12 | => profile.CreateMap() 13 | .ForMember(x => x.BankID, opt => opt.Ignore()); 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankController.BankResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 4 | 5 | public sealed record BankResponseDto : IMapFrom 6 | { 7 | public int BankID { get; init; } = Constants.UnknownRecordID; 8 | public string BankName { get; init; } = string.Empty; 9 | 10 | public void MapFrom(AutoMapper.Profile profile) => profile 11 | .CreateMap() 12 | .ForMember(x => x.BankName, opt => opt.MapFrom(s => s.BankName.Value)); 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AccountsModule/BankController.BankUpdateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.AccountsModule; 5 | 6 | [SwaggerSchema(Required = new[] { "BankID", "BankName" })] 7 | public sealed record BankUpdateRequestDto : IMapTo 8 | { 9 | [SwaggerSchema("The Bank identifier.", ReadOnly = true)] 10 | public int BankID { get; init; } 11 | public string BankName { get; init; } = string.Empty; 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AssetRegisterModule/AssetController.AssetResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AssetRegisterModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.AssetRegisterModule; 4 | 5 | public sealed record AssetResponseDto : IMapFrom 6 | { 7 | public int AssetID { get; init; } 8 | public string AssetName { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/AssetRegisterModule/AssetController.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AssetRegisterModule.Queries; 2 | 3 | namespace AdminAssistant.WebAPI.v1.AssetRegisterModule; 4 | 5 | [ApiController] 6 | [Route("api/v1/assetregister-module/[controller]")] 7 | [ApiExplorerSettings(GroupName = "Asset Register Module")] 8 | public sealed class AssetController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 9 | : WebApiControllerBase(mapper, mediator, loggingProvider) 10 | { 11 | [HttpGet] 12 | [SwaggerOperation("Lists all assets", OperationId = "GetAsset")] 13 | [SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of AssetResponseDto", type: typeof(IEnumerable))] 14 | public async Task>> GetAssets(CancellationToken cancellationToken) 15 | { 16 | Log.Start(); 17 | 18 | var result = await Mediator.Send(new AssetQuery(), cancellationToken).ConfigureAwait(false); 19 | var response = Mapper.Map>(result.Value); 20 | 21 | return Log.Finish(Ok(response)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/BudgetModule/BudgetController.BudgetResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.BudgetModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.BudgetModule; 4 | 5 | public sealed record BudgetResponseDto : IMapFrom 6 | { 7 | public int BudgetID { get; init; } 8 | public string BudgetName { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/BudgetModule/BudgetController.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.BudgetModule.Queries; 2 | 3 | namespace AdminAssistant.WebAPI.v1.BudgetModule; 4 | 5 | [ApiController] 6 | [Route("api/v1/budget-module/[controller]")] 7 | [ApiExplorerSettings(GroupName = "Budget Module")] 8 | public sealed class BudgetController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 9 | : WebApiControllerBase(mapper, mediator, loggingProvider) 10 | { 11 | [HttpGet] 12 | [SwaggerOperation("Lists all budgets.", OperationId = "GetBudget")] 13 | [SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of BudgetResponseDto", type: typeof(IEnumerable))] 14 | public async Task>> GetBudgets(CancellationToken cancellationToken) 15 | { 16 | Log.Start(); 17 | 18 | var result = await Mediator.Send(new BudgetQuery(), cancellationToken).ConfigureAwait(false); 19 | var response = Mapper.Map>(result.Value); 20 | 21 | return Log.Finish(Ok(response)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/CalendarModule/ReminderController.ReminderResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CalendarModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.CalendarModule; 4 | 5 | public sealed record ReminderResponseDto : IMapFrom 6 | { 7 | public int ReminderID { get; init; } 8 | public string ReminderName { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/CalendarModule/ReminderController.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CalendarModule.Queries; 2 | 3 | namespace AdminAssistant.WebAPI.v1.CalendarModule; 4 | 5 | [ApiController] 6 | [Route("api/v1/calendar-module/[controller]")] 7 | [ApiExplorerSettings(GroupName = "Calendar Module")] 8 | public sealed class ReminderController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 9 | : WebApiControllerBase(mapper, mediator, loggingProvider) 10 | { 11 | [HttpGet] 12 | [SwaggerOperation("Lists all reminders.", OperationId = "GetReminder")] 13 | [SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of ReminderResponseDto", type: typeof(IEnumerable))] 14 | public async Task>> GetReminders(CancellationToken cancellationToken) 15 | { 16 | Log.Start(); 17 | 18 | var result = await Mediator.Send(new ReminderQuery(), cancellationToken).ConfigureAwait(false); 19 | var response = Mapper.Map>(result.Value); 20 | 21 | return Log.Finish(Ok(response)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/ContactsModule/ContactController.ContactCreateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.ContactsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.ContactsModule; 5 | 6 | [SwaggerSchema(Required = new[] { "FirstName", "LastName" })] 7 | public sealed record ContactCreateRequestDto : IMapTo 8 | { 9 | public string FirstName { get; init; } = string.Empty; 10 | public string LastName { get; init; } = string.Empty; 11 | 12 | public void MapTo(AutoMapper.Profile profile)=> profile 13 | .CreateMap() 14 | .ForMember(x => x.ContactID, opt => opt.Ignore()) 15 | .ForMember(x => x.OwnerID, opt => opt.Ignore()) 16 | .ForMember(x => x.TitleID, opt => opt.Ignore()) 17 | .ForMember(x => x.DateOfBirth, opt => opt.Ignore()); 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/ContactsModule/ContactController.ContactResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.ContactsModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.ContactsModule; 4 | 5 | public sealed record ContactResponseDto : IMapFrom 6 | { 7 | public int ContactID { get; init; } 8 | public string FirstName { get; init; } = string.Empty; 9 | public string LastName { get; init; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/ContactsModule/ContactController.ContactUpdateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.ContactsModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.ContactsModule; 5 | 6 | [SwaggerSchema(Required = new[] { "ContactID", "FirstName", "LastName" })] 7 | public sealed record ContactUpdateRequestDto : IMapTo 8 | { 9 | [SwaggerSchema("The Contact identifier.")] 10 | public int ContactID { get; init; } 11 | public string FirstName { get; init; } = string.Empty; 12 | public string LastName { get; init; } = string.Empty; 13 | 14 | public void MapTo(AutoMapper.Profile profile) => profile 15 | .CreateMap() 16 | .ForMember(x => x.OwnerID, opt => opt.Ignore()) 17 | .ForMember(x => x.TitleID, opt => opt.Ignore()) 18 | .ForMember(x => x.DateOfBirth, opt => opt.Ignore()); 19 | } 20 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/CoreModule/CurrencyController.CurrencyCreateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.CoreModule; 5 | 6 | [SwaggerSchema(Required = new[] { "Symbol", "DecimalFormat" })] 7 | public sealed record CurrencyCreateRequestDto : IMapTo 8 | { 9 | public string Symbol { get; init; } = string.Empty; 10 | public string DecimalFormat { get; init; } = string.Empty; 11 | 12 | public void MapTo(AutoMapper.Profile profile) 13 | => profile.CreateMap() 14 | .ForMember(x => x.CurrencyID, opt => opt.Ignore()); 15 | } 16 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/CoreModule/CurrencyController.CurrencyResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.CoreModule; 4 | 5 | public sealed record CurrencyResponseDto : IMapFrom 6 | { 7 | public int CurrencyID { get; init; } 8 | public string Symbol { get; init; } = string.Empty; 9 | public string DecimalFormat { get; init; } = string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/CoreModule/CurrencyController.CurrencyUpdateRequestDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule; 2 | using Swashbuckle.AspNetCore.Annotations; 3 | 4 | namespace AdminAssistant.WebAPI.v1.CoreModule; 5 | 6 | [SwaggerSchema(Required = new[] { "CurrencyID", "Symbol", "DecimalFormat" })] 7 | public sealed record CurrencyUpdateRequestDto : IMapTo 8 | { 9 | [SwaggerSchema("The Currency identifier.", ReadOnly = true)] 10 | public int CurrencyID { get; init; } 11 | public string Symbol { get; init; } = string.Empty; 12 | public string DecimalFormat { get; init; } = string.Empty; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/DocumentsModule/DocumentController.DocumentResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.DocumentsModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.DocumentsModule; 4 | 5 | public sealed record DocumentResponseDto : IMapFrom 6 | { 7 | public int DocumentID { get; init; } 8 | public string FileName { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/DocumentsModule/DocumentController.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.DocumentsModule.Queries; 2 | 3 | namespace AdminAssistant.WebAPI.v1.DocumentsModule; 4 | 5 | [ApiController] 6 | [Route("api/v1/document-module/[controller]")] 7 | [ApiExplorerSettings(GroupName = "Documents Module")] 8 | public sealed class DocumentController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 9 | : WebApiControllerBase(mapper, mediator, loggingProvider) 10 | { 11 | [HttpGet] 12 | [SwaggerOperation("Lists all documents.", OperationId = "GetDocument")] 13 | [SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of DocumentResponseDto", type: typeof(IEnumerable))] 14 | public async Task>> GetDocuments(CancellationToken cancellationToken) 15 | { 16 | Log.Start(); 17 | 18 | var result = await Mediator.Send(new DocumentQuery(), cancellationToken).ConfigureAwait(false); 19 | var response = Mapper.Map>(result.Value); 20 | 21 | return Log.Finish(Ok(response)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/MailModule/MailMessageController.MailMessageResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.MailModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.MailModule; 4 | 5 | public sealed record MailMessageResponseDto : IMapFrom 6 | { 7 | public int MailMessageID { get; init; } 8 | public string Subject { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/MailModule/MailMessageController.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.MailModule.Queries; 2 | 3 | namespace AdminAssistant.WebAPI.v1.MailModule; 4 | 5 | [ApiController] 6 | [Route("api/v1/mail-module/[controller]")] 7 | [ApiExplorerSettings(GroupName = "Mail Module")] 8 | public sealed class MailMessageController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 9 | : WebApiControllerBase(mapper, mediator, loggingProvider) 10 | { 11 | [HttpGet] 12 | [SwaggerOperation("Lists all mail messages", OperationId = "GetMailMessage")] 13 | [SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of MailMessageResponseDto", type: typeof(IEnumerable))] 14 | public async Task>> GetMailMessages(CancellationToken cancellationToken) 15 | { 16 | Log.Start(); 17 | 18 | var result = await Mediator.Send(new MailMessageQuery(), cancellationToken).ConfigureAwait(false); 19 | var response = Mapper.Map>(result.Value); 20 | 21 | return Log.Finish(Ok(response)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.WebAPI.v1; 2 | 3 | public sealed class MappingProfile : MappingProfileBase 4 | { 5 | public MappingProfile() 6 | : base(typeof(MappingProfile).Assembly) 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/TasksModule/TaskListController.TaskListResponseDto.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.TasksModule; 2 | 3 | namespace AdminAssistant.WebAPI.v1.TasksModule; 4 | 5 | public sealed record TaskListResponseDto : IMapFrom 6 | { 7 | public int TaskListID { get; init; } 8 | public string TaskListName { get; init; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/WebAPI/v1/TasksModule/TaskListController.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.TasksModule.Queries; 2 | 3 | namespace AdminAssistant.WebAPI.v1.TasksModule; 4 | 5 | [ApiController] 6 | [Route("api/v1/tasks-module/[controller]")] 7 | [ApiExplorerSettings(GroupName = "Tasks Module")] 8 | public sealed class TaskListController(IMapper mapper, IMediator mediator, ILoggingProvider loggingProvider) 9 | : WebApiControllerBase(mapper, mediator, loggingProvider) 10 | { 11 | [HttpGet] 12 | [SwaggerOperation("Lists all task lists.", OperationId = "GetTaskList")] 13 | [SwaggerResponse(StatusCodes.Status200OK, "Ok - returns a list of TaskListResponseDto", type: typeof(IEnumerable))] 14 | public async Task>> GetTaskLists(CancellationToken cancellationToken) 15 | { 16 | Log.Start(); 17 | 18 | var result = await Mediator.Send(new TaskListQuery(), cancellationToken).ConfigureAwait(false); 19 | var response = Mapper.Map>(result.Value); 20 | 21 | return Log.Finish(Ok(response)); 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "AdminAssistant": "Debug", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Server/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "AdminAssistant": "Information", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Not found 8 | 9 |

Sorry, there's nothing at this address.

10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Keep vm lowercase as used by blazor html markup", Scope = "member", Target = "~P:AdminAssistant.Blazor.Client.Shared.AdminAssistantLayoutComponentBase`1.vm")] 9 | [assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Keep vm lowercase as used by blazor html markup", Scope = "member", Target = "~P:AdminAssistant.Blazor.Client.Shared.AdminAssistantComponentBase`1.vm")] 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using AdminAssistant.Primitives.UI; 2 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/AccountsModule/BankAccountBalanceListComponent.razor: -------------------------------------------------------------------------------- 1 | 

BankAccountBalanceList

2 | 3 | @code { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/AdminAssistantModuleComponentBase.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Blazor.Client.Shared; 2 | 3 | namespace AdminAssistant.Blazor.Client.Modules; 4 | 5 | public abstract class AdminAssistantModuleComponentBase : AdminAssistantComponentBase 6 | where TViewModel : IModuleViewModelBase 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/AssetRegisterModule/AssetRegister.razor: -------------------------------------------------------------------------------- 1 | @page "/assetregister" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | 8 | @code { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/BillingModule/Billing.razor: -------------------------------------------------------------------------------- 1 | @page "/Billing" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | 8 | @code { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/BudgetModule/Budget.razor: -------------------------------------------------------------------------------- 1 | @page "/budget" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | 8 | @code { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/CalendarModule/Calendar.razor: -------------------------------------------------------------------------------- 1 | @page "/calendar" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | 8 | @code { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/ContactsModule/Contacts.razor: -------------------------------------------------------------------------------- 1 | @page "/contacts" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | 8 | @code { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/DashboardModule/Dashboard.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @page "/dashboard" 3 | @inherits AdminAssistantModuleComponentBase 4 | 5 | @vm.HeaderText 6 | @vm.HeaderText 7 | @vm.SubHeaderText 8 | 9 | @code { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/DocumentsModule/Documents.razor: -------------------------------------------------------------------------------- 1 | @page "/documents" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/MailModule/Mail.razor: -------------------------------------------------------------------------------- 1 | @page "/mail" 2 | @inherits AdminAssistantModuleComponentBase 3 | @vm.HeaderText 4 | @vm.HeaderText 5 | @vm.SubHeaderText 6 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/NotesModule/Notes.razor: -------------------------------------------------------------------------------- 1 | @page "/notes" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/ReportsModule/Reports.razor: -------------------------------------------------------------------------------- 1 | @page "/reports" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Modules/TasksModule/Tasks.razor: -------------------------------------------------------------------------------- 1 | @page "/tasks" 2 | @inherits AdminAssistantModuleComponentBase 3 | 4 | @vm.HeaderText 5 | @vm.HeaderText 6 | @vm.SubHeaderText 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "AdminAssistant.Blazor.Client": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | }, 10 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Shared/AdminAssistantComponentBase.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Primitives.UI; 2 | using Microsoft.AspNetCore.Components; 3 | 4 | namespace AdminAssistant.Blazor.Client.Shared; 5 | 6 | public abstract class AdminAssistantComponentBase : ComponentBase 7 | where TViewModel : IViewModelBase 8 | { 9 | #pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. 10 | [Inject] 11 | protected TViewModel vm { get; set; } 12 | #pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. 13 | 14 | protected override void OnInitialized() 15 | { 16 | vm.PropertyChanged += (o, e) => StateHasChanged(); 17 | base.OnInitialized(); 18 | } 19 | 20 | protected override Task OnInitializedAsync() => vm.OnInitializedAsync(); 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/Shared/AdminAssistantLayoutComponentBase.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Primitives.UI; 2 | using Microsoft.AspNetCore.Components; 3 | 4 | namespace AdminAssistant.Blazor.Client.Shared; 5 | 6 | public abstract class AdminAssistantLayoutComponentBase : LayoutComponentBase 7 | where TViewModel : IViewModelBase 8 | { 9 | #pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. 10 | [Inject] 11 | protected TViewModel vm { get; set; } 12 | #pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. 13 | 14 | protected override void OnInitialized() 15 | { 16 | vm.PropertyChanged += (o, e) => StateHasChanged(); 17 | base.OnInitialized(); 18 | } 19 | 20 | protected override Task OnInitializedAsync() => vm.OnInitializedAsync(); 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Components.Forms 3 | @using Microsoft.AspNetCore.Components.Routing 4 | @using Microsoft.AspNetCore.Components.Web 5 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 6 | @using Microsoft.JSInterop 7 | @using AdminAssistant.Blazor.Client 8 | @using AdminAssistant.Blazor.Client.Shared 9 | @using MudBlazor 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/appsettings.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "Auth0": { 3 | "Authority": "https://", 4 | "ClientId": "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Auth0": { 3 | "Authority": "https://admin-assistant.eu.auth0.com", 4 | "ClientId": "5flOMLNyDGG4YSuLqgvbGNy0eFBnVXWd" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/assets/css/loading.css: -------------------------------------------------------------------------------- 1 | .loading { 2 | position: absolute; 3 | top: 50%; 4 | left: 50%; 5 | -ms-transform: translate(-50%, -50%); 6 | /* IE 9 */ 7 | -webkit-transform: translate(-50%, -50%); 8 | /* Safari */ 9 | transform: translate(-50%, -50%); 10 | /* Standard syntax */ 11 | } 12 | 13 | .loading .loading-bar { 14 | display: inline-block; 15 | width: 6px; 16 | height: 30px; 17 | border-radius: 4px; 18 | animation: loading 1s ease-in-out infinite; 19 | } 20 | 21 | .loading .loading-bar:nth-child(1) { 22 | background-color: #222; 23 | animation-delay: 0; 24 | } 25 | 26 | .loading .loading-bar:nth-child(2) { 27 | background-color: #222; 28 | animation-delay: 0.09s; 29 | } 30 | 31 | .loading .loading-bar:nth-child(3) { 32 | background-color: #222; 33 | animation-delay: .18s; 34 | } 35 | 36 | .loading .loading-bar:nth-child(4) { 37 | background-color: #222; 38 | animation-delay: .27s; 39 | } 40 | 41 | @keyframes loading { 42 | 0% { 43 | transform: scale(1); 44 | } 45 | 46 | 20% { 47 | transform: scale(1, 2.2); 48 | } 49 | 50 | 40% { 51 | transform: scale(1); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/icon-192.png -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Blazor.Webasm/wwwroot/icon-512.png -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Admin Assistant", 3 | "short_name": "Admin Assistant", 4 | "start_url": "./", 5 | "display": "standalone", 6 | "background_color": "#201f1f", 7 | "theme_color": "#282727", 8 | "prefer_related_applications": false, 9 | "icons": [ 10 | { 11 | "src": "icon-512.png", 12 | "type": "image/png", 13 | "sizes": "512x512" 14 | }, 15 | { 16 | "src": "icon-192.png", 17 | "type": "image/png", 18 | "sizes": "192x192" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Blazor.Webasm/wwwroot/service-worker.js: -------------------------------------------------------------------------------- 1 | // In development, always fetch from the network and do not enable offline support. 2 | // This is because caching would make development more difficult (changes would not 3 | // be reflected on the first load after each change). 4 | self.addEventListener('fetch', () => { }); 5 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/AdminAssistant.DomainModel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AdminAssistant.DomainModel.docs.xml 5 | $(NoWarn); 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using SimonGeering.Framework.Primitives; 2 | global using FluentValidation; 3 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | using SimonGeering.Framework.TypeMapping; 3 | 4 | namespace AdminAssistant.Domain; 5 | 6 | public class MappingProfile : MappingProfileBase 7 | { 8 | public MappingProfile() 9 | : base(typeof(MappingProfile).Assembly) 10 | { 11 | CreateMap().ConvertUsing(x => x.Value); 12 | CreateMap().ConvertUsing(x => x.Value); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Bank.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule; 4 | 5 | public sealed record Bank : IPersistable 6 | { 7 | public const int BankNameMaxLength = EntityName.MaxLength; 8 | 9 | public BankId BankID { get; init; } = BankId.Default; 10 | public BankName BankName { get; init; } = BankName.Default; 11 | 12 | /// 13 | public Id PrimaryKey => BankID; 14 | } 15 | public sealed record BankId(int Value) : Id(Value) 16 | { 17 | public static BankId Default => new(Constants.UnknownRecordID); 18 | } 19 | public sealed record BankName(string Value) : EntityName(Value) 20 | { 21 | public static BankName Default => new(string.Empty); 22 | } 23 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/BankAccountInfo.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule; 2 | 3 | public sealed record BankAccountInfo : IPersistable 4 | { 5 | public BankAccountId BankAccountID { get; init; } = BankAccountId.Default; 6 | public string AccountName { get; init; } = string.Empty; 7 | public int CurrentBalance { get; init; } 8 | public string Symbol { get; init; } = string.Empty; 9 | public string DecimalFormat { get; init; } = string.Empty; 10 | public bool IsBudgeted { get; init; } 11 | 12 | public Id PrimaryKey => BankAccountID; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/BankAccountStatement.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.DocumentsModule; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule; 4 | 5 | /// 6 | /// 7 | public sealed record BankAccountStatement : IPersistable 8 | { 9 | public BankAccountStatementId BankAccountStatementID { get; init; } = BankAccountStatementId.Default; 10 | public BankAccountId BankAccountID { get; init; } = BankAccountId.Default; 11 | public DocumentId DocumentID { get; init; } = DocumentId.Default; 12 | public DateTime StatementDate { get; init; } 13 | public bool IsReconciled { get; init; } 14 | public DateTime StartDate { get; init; } 15 | public DateTime EndDate { get; init; } 16 | public int OpeningBalance { get; init; } 17 | public int ClosingBalance { get; init; } 18 | public int TotalPaymentsIn { get; init; } 19 | public int TotalPaymentsOut { get; init; } 20 | 21 | /// 22 | public Id PrimaryKey => BankAccountStatementID; 23 | } 24 | public sealed record BankAccountStatementId(int Value) : Id(Value) 25 | { 26 | public static BankAccountStatementId Default => new(Constants.UnknownRecordID); 27 | } 28 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/BankAccountTransactionType.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule; 4 | 5 | public sealed record BankAccountTransactionType : IPersistable 6 | { 7 | public const int DescriptionMaxLength = EntityDescription.MaxLength; 8 | 9 | public BankAccountTransactionTypeId BankAccountTransactionTypeID { get; init; } = BankAccountTransactionTypeId.Default; 10 | public string Description { get; init; } = string.Empty; 11 | public Id PrimaryKey => BankAccountTransactionTypeID; 12 | } 13 | public sealed record BankAccountTransactionTypeId(int Value) : Id(Value) 14 | { 15 | public static BankAccountTransactionTypeId Default => new(Constants.UnknownRecordID); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/BankAccountType.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule; 4 | 5 | public sealed record BankAccountType : IPersistable 6 | { 7 | public const int DescriptionMaxLength = EntityDescription.MaxLength; 8 | 9 | public BankAccountTypeId BankAccountTypeID { get; init; } = BankAccountTypeId.Default; 10 | public string Description { get; init; } = string.Empty; 11 | public Id PrimaryKey => BankAccountTypeID; 12 | } 13 | public sealed record BankAccountTypeId(int Value) : Id(Value) 14 | { 15 | public static BankAccountTypeId Default => new(Constants.UnknownRecordID); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Builders/BankAccountInfoBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Builders; 2 | 3 | public interface IBankAccountInfoBuilder 4 | { 5 | BankAccountInfo Build(); 6 | IBankAccountInfoBuilder WithTestData(int bankAccountInfoID = Constants.UnknownRecordID); 7 | } 8 | internal sealed class BankAccountInfoBuilder : IBankAccountInfoBuilder 9 | { 10 | private BankAccountInfo _bankAccountInfo = new(); 11 | 12 | public static BankAccountInfo Default(IBankAccountInfoBuilder builder) => builder.Build(); 13 | 14 | public BankAccountInfo Build() => _bankAccountInfo; 15 | 16 | public IBankAccountInfoBuilder WithTestData(int bankAccountInfoID = 0) 17 | { 18 | _bankAccountInfo = _bankAccountInfo with 19 | { 20 | BankAccountID = new(bankAccountInfoID), 21 | AccountName = "A valid account name", 22 | CurrentBalance = 0, 23 | Symbol = "GBP", 24 | DecimalFormat = "2.2-2", 25 | IsBudgeted = false 26 | }; 27 | return this; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Builders/BankBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Builders; 2 | 3 | public interface IBankBuilder 4 | { 5 | Bank Build(); 6 | IBankBuilder WithTestData(int bankID = Constants.UnknownRecordID); 7 | IBankBuilder WithBankName(string bankName); 8 | } 9 | internal sealed class BankBuilder : IBankBuilder 10 | { 11 | private Bank _bank = new(); 12 | 13 | public static Bank Default(IBankBuilder builder) => builder.Build(); 14 | public Bank Build() => _bank; 15 | 16 | public IBankBuilder WithTestData(int bankID = Constants.UnknownRecordID) 17 | { 18 | _bank = _bank with 19 | { 20 | BankID = new(bankID), 21 | BankName = new("ACME Bank PLC") 22 | }; 23 | return this; 24 | } 25 | 26 | public IBankBuilder WithBankName(string bankName) 27 | { 28 | _bank = _bank with { BankName = new(bankName) }; 29 | return this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Builders/PayeeBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Builders; 2 | 3 | public interface IPayeeBuilder 4 | { 5 | Payee Build(); 6 | IPayeeBuilder WithTestData(int payeeID = Constants.UnknownRecordID); 7 | IPayeeBuilder WithName(string name); 8 | } 9 | internal sealed class PayeeBuilder : IPayeeBuilder 10 | { 11 | private Payee _payee = new(); 12 | 13 | public Payee Build() => _payee; 14 | 15 | public IPayeeBuilder WithTestData(int payeeID = Constants.UnknownRecordID) 16 | { 17 | _payee = _payee with 18 | { 19 | PayeeID = new(payeeID), 20 | Name = $"Payee {payeeID}", 21 | }; 22 | 23 | return this; 24 | } 25 | 26 | public IPayeeBuilder WithName(string name) 27 | { 28 | _payee = _payee with { Name = name }; 29 | return this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Payee.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule; 4 | 5 | public sealed record Payee : IPersistable 6 | { 7 | public const int NameMaxLength = EntityName.MaxLength; 8 | 9 | public PayeeId PayeeID { get; init; } = PayeeId.Default; 10 | public string Name { get; init; } = string.Empty; 11 | 12 | public Id PrimaryKey => PayeeID; 13 | } 14 | public sealed record PayeeId(int Value) : Id(Value) 15 | { 16 | public static PayeeId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/PayeeContact.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.ContactsModule; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule; 4 | 5 | public sealed record PayeeContact : IPersistable 6 | { 7 | public PayeeContactId PayeeContactID { get; init; } = PayeeContactId.Default; 8 | public PayeeId PayeeID { get; init; } = PayeeId.Default; 9 | public ContactId ContactID { get; init; } = ContactId.Default; 10 | public bool IsPrimaryContact { get; init; } 11 | 12 | public Id PrimaryKey => PayeeContactID; 13 | } 14 | public sealed record PayeeContactId(int Value) : Id(Value) 15 | { 16 | public static PayeeContactId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Validation/BankAccountTransactionValidator.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Validation; 2 | 3 | public interface IBankAccountTransactionValidator : IValidator 4 | { 5 | } 6 | internal sealed class BankAccountTransactionValidator : AbstractValidator, IBankAccountTransactionValidator 7 | { 8 | public BankAccountTransactionValidator() 9 | { 10 | RuleFor(x => x.Description) 11 | .NotEmpty() 12 | .MaximumLength(BankAccountTransaction.DescriptionMaxLength); 13 | 14 | RuleFor(x => x.BankAccountID) 15 | .NotEqual(BankAccountId.Default); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Validation/BankAccountTypeValidator.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Validation; 2 | 3 | public interface IBankAccountTypeValidator : IValidator 4 | { 5 | } 6 | internal sealed class BankAccountTypeValidator : AbstractValidator, IBankAccountTypeValidator 7 | { 8 | public BankAccountTypeValidator() 9 | => RuleFor(x => x.Description) 10 | .NotEmpty() 11 | .MaximumLength(BankAccountType.DescriptionMaxLength); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Validation/BankAccountValidator.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Validation; 4 | 5 | public interface IBankAccountValidator : IValidator 6 | { 7 | } 8 | internal sealed class BankAccountValidator : AbstractValidator, IBankAccountValidator 9 | { 10 | public BankAccountValidator() 11 | { 12 | RuleFor(x => x.AccountName) 13 | .NotEmpty() 14 | .MaximumLength(BankAccount.AccountNameMaxLength); 15 | 16 | RuleFor(x => x.BankAccountTypeID) 17 | .NotEqual(BankAccountTypeId.Default); 18 | 19 | RuleFor(x => x.CurrencyID) 20 | .NotEqual(CurrencyId.Default); 21 | 22 | // TODO: Validate BankAccountTypeID selection against DB. 23 | 24 | RuleFor(x => x.OpenedOn) 25 | .NotNull(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Validation/BankValidator.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared.Validation; 2 | 3 | namespace AdminAssistant.Modules.AccountsModule.Validation; 4 | 5 | public interface IBankValidator : IValidator 6 | { 7 | } 8 | internal sealed class BankValidator : AbstractValidator, IBankValidator 9 | { 10 | public BankValidator() 11 | => RuleFor(x => x.BankName).ValidEntityName(nameof(Bank.BankName)); 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AccountsModule/Validation/PayeeValidator.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.Validation; 2 | 3 | public interface IPayeeValidator : IValidator 4 | { 5 | } 6 | internal sealed class PayeeValidator : AbstractValidator, IPayeeValidator 7 | { 8 | public PayeeValidator() 9 | => RuleFor(x => x.Name) 10 | .NotEmpty() 11 | .MaximumLength(Payee.NameMaxLength); 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AssetRegisterModule/Asset.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.AssetRegisterModule; 4 | 5 | public sealed record Asset : IPersistable 6 | { 7 | public const int AssetNameMaxLength = EntityName.MaxLength; 8 | 9 | public AssetId AssetID { get; set; } = AssetId.Default; 10 | public string AssetName { get; set; } = string.Empty; 11 | 12 | public Id PrimaryKey => AssetID; 13 | } 14 | public sealed record AssetId(int Value) : Id(Value) 15 | { 16 | public static AssetId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/AssetRegisterModule/Builders/AssetBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AssetRegisterModule.Builders; 2 | 3 | public interface IAssetBuilder 4 | { 5 | Asset Build(); 6 | IAssetBuilder WithTestData(int assetID = Constants.UnknownRecordID); 7 | IAssetBuilder WithAssetName(string assetName); 8 | } 9 | internal sealed class AssetBuilder : IAssetBuilder 10 | { 11 | private Asset _asset = new(); 12 | 13 | public static Asset Default(IAssetBuilder builder) => builder.Build(); 14 | public static Asset Default(AssetBuilder builder) => builder.Build(); 15 | 16 | public Asset Build() => _asset; 17 | 18 | public IAssetBuilder WithTestData(int assetID = Constants.UnknownRecordID) 19 | { 20 | _asset = _asset with 21 | { 22 | AssetID = new(assetID), 23 | AssetName = "2 bed detached house" 24 | }; 25 | return this; 26 | } 27 | public IAssetBuilder WithAssetName(string assetName) 28 | { 29 | _asset = _asset with { AssetName = assetName }; 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/BudgetModule/Budget.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.BudgetModule; 4 | 5 | public sealed record Budget : IPersistable 6 | { 7 | public const int BudgetNameMaxLength = EntityName.MaxLength; 8 | 9 | public BudgetId BudgetID { get; set; } = BudgetId.Default; 10 | public string BudgetName { get; set; } = string.Empty; 11 | 12 | public Id PrimaryKey => BudgetID; 13 | } 14 | public sealed record BudgetId(int Value) : Id(Value) 15 | { 16 | public static BudgetId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/BudgetModule/Builders/BudgetBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.BudgetModule.Builders; 2 | 3 | public interface IBudgetBuilder 4 | { 5 | Budget Build(); 6 | IBudgetBuilder WithTestData(int budgetID = Constants.UnknownRecordID); 7 | IBudgetBuilder WithBudgetName(string budgetName); 8 | } 9 | internal sealed class BudgetBuilder : IBudgetBuilder 10 | { 11 | private Budget _budget = new(); 12 | 13 | public static Budget Default(IBudgetBuilder builder) => builder.Build(); 14 | 15 | public Budget Build() => _budget; 16 | 17 | public IBudgetBuilder WithTestData(int budgetID = Constants.UnknownRecordID) 18 | { 19 | _budget = _budget with 20 | { 21 | BudgetID = new(budgetID), 22 | BudgetName = "Test Budget" 23 | }; 24 | return this; 25 | } 26 | 27 | public IBudgetBuilder WithBudgetName(string budgetName) 28 | { 29 | _budget = _budget with { BudgetName = budgetName }; 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/BudgetModule/Validation/BudgetValidator.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.BudgetModule.Validation; 2 | 3 | public interface IBudgetValidator : IValidator 4 | { 5 | } 6 | internal sealed class BudgetValidator : AbstractValidator, IBudgetValidator 7 | { 8 | public BudgetValidator() 9 | => RuleFor(x => x.BudgetName) 10 | .NotEmpty() 11 | .MaximumLength(Budget.BudgetNameMaxLength); 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/CalendarModule/Builders/ReminderBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CalendarModule.Builders; 2 | 3 | public interface IReminderBuilder 4 | { 5 | Reminder Build(); 6 | IReminderBuilder WithTestData(int reminderID = Constants.UnknownRecordID); 7 | IReminderBuilder WithReminderName(string reminderName); 8 | } 9 | internal sealed class ReminderBuilder : IReminderBuilder 10 | { 11 | private Reminder _reminder = new(); 12 | 13 | public static Reminder Default(IReminderBuilder builder) => builder.Build(); 14 | public static Reminder Default(ReminderBuilder builder) => builder.Build(); 15 | 16 | public Reminder Build() => _reminder; 17 | 18 | public IReminderBuilder WithTestData(int reminderID = Constants.UnknownRecordID) 19 | { 20 | _reminder = _reminder with 21 | { 22 | ReminderID = new(reminderID), 23 | ReminderName = "Do something important" 24 | }; 25 | return this; 26 | } 27 | public IReminderBuilder WithReminderName(string reminderName) 28 | { 29 | _reminder = _reminder with { ReminderName = reminderName }; 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/CalendarModule/Reminder.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.CalendarModule; 4 | 5 | public sealed record Reminder : IPersistable 6 | { 7 | public const int ReminderNameMaxLength = EntityName.MaxLength; 8 | 9 | public ReminderId ReminderID { get; set; } = ReminderId.Default; 10 | public string ReminderName { get; set; } = string.Empty; 11 | 12 | public Id PrimaryKey => ReminderID; 13 | } 14 | public sealed record ReminderId(int Value) : Id(Value) 15 | { 16 | public static ReminderId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/ContactsModule/Contact.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.ContactsModule; 4 | 5 | public sealed record Contact : IPersistable 6 | { 7 | public const int FirstNameMaxLength = EntityName.MaxLength; 8 | public const int LastNameMaxLength = EntityName.MaxLength; 9 | 10 | public ContactId ContactID { get; init; } = ContactId.Default; 11 | public int OwnerID { get; init; } = Constants.UnknownRecordID; 12 | public int TitleID { get; init; } = Constants.UnknownRecordID; 13 | 14 | public string FirstName { get; set; } = string.Empty; 15 | public string LastName { get; set; } = string.Empty; 16 | public DateTime? DateOfBirth { get; set; } 17 | 18 | 19 | public Id PrimaryKey => ContactID; 20 | } 21 | public sealed record ContactId(int Value) : Id(Value) 22 | { 23 | public static ContactId Default => new(Constants.UnknownRecordID); 24 | } 25 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/ContactsModule/Validation/ContactValidator.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.ContactsModule.Validation; 2 | 3 | public interface IContactValidator : IValidator 4 | { 5 | } 6 | internal sealed class ContactValidator : AbstractValidator, IContactValidator 7 | { 8 | public ContactValidator() 9 | { 10 | RuleFor(x => x.FirstName) 11 | .NotEmpty() 12 | .MaximumLength(Contact.FirstNameMaxLength); 13 | 14 | RuleFor(x => x.LastName) 15 | .NotEmpty() 16 | .MaximumLength(Contact.LastNameMaxLength); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/CoreModule/Company.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CoreModule; 2 | 3 | public sealed record Company 4 | { 5 | public const int CompanyNumberMaxLength = 50; 6 | public const int VATNumberMaxLength = 50; 7 | } 8 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/CoreModule/Currency.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CoreModule; 2 | 3 | public sealed record Currency : IPersistable 4 | { 5 | public const int SymbolMaxLength = 3; 6 | public const int DecimalFormatMaxLength = 5; 7 | 8 | public CurrencyId CurrencyID { get; set; } = CurrencyId.Default; 9 | public string Symbol { get; set; } = string.Empty; 10 | public string DecimalFormat { get; set; } = string.Empty; 11 | 12 | public Id PrimaryKey => CurrencyID; 13 | } 14 | public sealed record CurrencyId(int Value) : Id(Value) 15 | { 16 | public static CurrencyId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/CoreModule/Validation/CurrencyValidator.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CoreModule.Validation; 2 | 3 | public interface ICurrencyValidator : IValidator 4 | { 5 | } 6 | internal sealed class CurrencyValidator : AbstractValidator, ICurrencyValidator 7 | { 8 | public CurrencyValidator() 9 | { 10 | RuleFor(x => x.DecimalFormat) 11 | .NotEmpty() 12 | .MaximumLength(Currency.DecimalFormatMaxLength); 13 | 14 | RuleFor(x => x.Symbol) 15 | .NotEmpty() 16 | .MaximumLength(Currency.SymbolMaxLength); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/DocumentsModule/Builders/DocumentBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.DocumentsModule.Builders; 2 | 3 | public interface IDocumentBuilder 4 | { 5 | Document Build(); 6 | IDocumentBuilder WithTestData(int documentID = Constants.UnknownRecordID); 7 | IDocumentBuilder WithFileName(string fileName); 8 | } 9 | internal sealed class DocumentBuilder : IDocumentBuilder 10 | { 11 | private Document _document = new(); 12 | 13 | public static Document Default(IDocumentBuilder builder) => builder.Build(); 14 | public static Document Default(DocumentBuilder builder) => builder.Build(); 15 | 16 | public Document Build() => _document; 17 | 18 | public IDocumentBuilder WithTestData(int documentID = Constants.UnknownRecordID) 19 | { 20 | _document = _document with 21 | { 22 | DocumentID = new DocumentId(documentID), 23 | FileName = "SomRandomFileName.txt" 24 | }; 25 | return this; 26 | } 27 | 28 | public IDocumentBuilder WithFileName(string fileName) 29 | { 30 | _document = _document with { FileName = fileName }; 31 | return this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/DocumentsModule/Document.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.DocumentsModule; 2 | 3 | public sealed record Document : IPersistable 4 | { 5 | public const int FileNameMaxLength = 255; 6 | 7 | public DocumentId DocumentID { get; set; } = DocumentId.Default; 8 | 9 | public string FileName { get; set; } = string.Empty; 10 | 11 | public Id PrimaryKey => DocumentID; 12 | } 13 | public sealed record DocumentId(int Value) : Id(Value) 14 | { 15 | public static DocumentId Default => new(Constants.UnknownRecordID); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/MailModule/Builders/MailMessageBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.MailModule.Builders; 2 | 3 | public interface IMailMessageBuilder 4 | { 5 | MailMessage Build(); 6 | IMailMessageBuilder WithTestData(int assetID = Constants.UnknownRecordID); 7 | IMailMessageBuilder WithSubject(string subject); 8 | } 9 | internal sealed class MailMessageBuilder : IMailMessageBuilder 10 | { 11 | private MailMessage _mailMessage = new(); 12 | 13 | public static MailMessage Default(IMailMessageBuilder builder) => builder.Build(); 14 | public static MailMessage Default(MailMessageBuilder builder) => builder.Build(); 15 | 16 | public MailMessage Build() => _mailMessage; 17 | 18 | public IMailMessageBuilder WithTestData(int assetID = Constants.UnknownRecordID) 19 | { 20 | _mailMessage = _mailMessage with 21 | { 22 | MailMessageID = new(assetID), 23 | Subject = "A mail from the boss" 24 | }; 25 | return this; 26 | } 27 | 28 | public IMailMessageBuilder WithSubject(string subject) 29 | { 30 | _mailMessage = _mailMessage with { Subject = subject }; 31 | return this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/MailModule/MailMessage.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.MailModule; 4 | 5 | public sealed record MailMessage : IPersistable 6 | { 7 | public const int SubjectNameMaxLength = EntityDescription.MaxLength; 8 | 9 | public MailMessageId MailMessageID { get; set; } = MailMessageId.Default; 10 | public string Subject { get; set; } = string.Empty; 11 | 12 | public Id PrimaryKey => MailMessageID; 13 | } 14 | public sealed record MailMessageId(int Value) : Id(Value) 15 | { 16 | public static MailMessageId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/TasksModule/Builders/TaskListBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.TasksModule.Builders; 2 | 3 | public interface ITaskListBuilder 4 | { 5 | TaskList Build(); 6 | ITaskListBuilder WithTestData(int taskListID = Constants.UnknownRecordID); 7 | ITaskListBuilder WithTaskListName(string taskListName); 8 | } 9 | internal sealed class TaskListBuilder : ITaskListBuilder 10 | { 11 | private TaskList _taskList = new(); 12 | 13 | public static TaskList Default(ITaskListBuilder builder) => builder.Build(); 14 | public static TaskList Default(TaskListBuilder builder) => builder.Build(); 15 | 16 | public TaskList Build() => _taskList; 17 | 18 | public ITaskListBuilder WithTestData(int taskListID = Constants.UnknownRecordID) 19 | { 20 | _taskList = _taskList with 21 | { 22 | TaskListID = new(taskListID), 23 | TaskListName = "My Task List" 24 | }; 25 | return this; 26 | } 27 | 28 | public ITaskListBuilder WithTaskListName(string taskListName) 29 | { 30 | _taskList = _taskList with { TaskListName = taskListName }; 31 | return this; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Modules/TasksModule/TaskList.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Shared; 2 | 3 | namespace AdminAssistant.Modules.TasksModule; 4 | 5 | public sealed record TaskList : IPersistable 6 | { 7 | public const int TaskListNameMaxLength = EntityName.MaxLength; 8 | 9 | public TaskListId TaskListID { get; set; } = TaskListId.Default; 10 | public string TaskListName { get; set; } = string.Empty; 11 | 12 | public Id PrimaryKey => TaskListID; 13 | } 14 | public sealed record TaskListId(int Value) : Id(Value) 15 | { 16 | public static TaskListId Default => new(Constants.UnknownRecordID); 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/ConfigurationSettings.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared; 2 | 3 | public sealed record ConfigurationSettings 4 | { 5 | public string WebApiClientBaseAddress { get; set; } = "https://localhost:5001"; 6 | public string DatabaseProvider { get; set; } = string.Empty; 7 | public string ConnectionString { get; set; } = string.Empty; 8 | public string Auth0Authority { get; set; } = string.Empty; 9 | public string Auth0ApiIdentifier { get; set; } = string.Empty; 10 | public string Auth0AuthorizeEndpoint { get; set; } = string.Empty; 11 | public string Auth0TokenEndpoint { get; set; } = string.Empty; 12 | public string Auth0ClientId { get; set; } = string.Empty; 13 | public string Auth0ClientSecret { get; set; } = string.Empty; 14 | public string Auth0AppName { get; set; } = string.Empty; 15 | } 16 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/DatabaseProvider.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared; 2 | 3 | public enum DatabaseProvider 4 | { 5 | SQLServer, 6 | SQLServerLocalDB, 7 | SQLite, 8 | PostgresSQL 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/EntityDescription.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared; 2 | 3 | public abstract record EntityDescription(string Value) 4 | { 5 | /// 6 | /// The maximum length of a description field. 7 | /// 8 | public const int MaxLength = 255; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/EntityName.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared; 2 | 3 | public abstract record EntityName(string Value) 4 | { 5 | /// 6 | /// The maximum length of a name filed 7 | /// 8 | /// 9 | /// For example the name of a person or company. 10 | /// 11 | public const int MaxLength = 50; 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/User.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared; 2 | 3 | public sealed record User 4 | { 5 | public const int SignOnMaxLength = 50; 6 | 7 | public int UserID { get; set; } = Constants.UnknownRecordID; 8 | public string SignOn { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/UserContextProvider.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared; 2 | 3 | public interface IUserContextProvider 4 | { 5 | User GetCurrentUser(); 6 | } 7 | internal sealed class UserContextProvider : IUserContextProvider 8 | { 9 | // TODO: Hard coded user ID. 10 | public User GetCurrentUser() => new() { UserID = 10, SignOn = "simongeering" }; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.DomainModel/Shared/Validation/FluentValidationRuleBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Ardalis.GuardClauses; 2 | 3 | namespace AdminAssistant.Shared.Validation; 4 | 5 | internal static class FluentValidationRuleBuilderExtensions 6 | { 7 | public static IRuleBuilderOptions ValidEntityName(this IRuleBuilder ruleBuilder, string overridePropertyName) 8 | { 9 | Guard.Against.NullOrEmpty(overridePropertyName); 10 | return ruleBuilder.ChildRules(childRule => childRule.RuleFor(x => x.Value).NotEmpty().MaximumLength(EntityName.MaxLength).WithName(overridePropertyName)); 11 | } 12 | public static IRuleBuilderOptions ValidEntityDescription(this IRuleBuilder ruleBuilder, string overridePropertyName) 13 | { 14 | Guard.Against.NullOrEmpty(overridePropertyName); 15 | return ruleBuilder.ChildRules(childRule => childRule.RuleFor(x => x.Value).NotEmpty().MaximumLength(EntityDescription.MaxLength).WithName(overridePropertyName)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra.ClientSide/AdminAssistant.Infra.ClientSide.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AdminAssistant.Infra.ClientSide.docs.xml 5 | $(NoWarn); 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | all 27 | runtime; build; native; contentfiles; analyzers 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra.ClientSide/DependencyInjectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Infrastructure.Providers; 2 | 3 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AdminAssistant.Test")] 4 | 5 | namespace Microsoft.Extensions.DependencyInjection; 6 | 7 | public static class DependencyInjectionExtensions 8 | { 9 | public static void AddAdminAssistantClientSideProviders(this IServiceCollection services) 10 | { 11 | // TODO: For now take a hard dependency between client side UI projects and Infra, inc un-needed anciliairy dependencies. 12 | // This can be resolved in future by splitting infra into multiple assemblies, but this is not worth doing 13 | // until it gets bigger sure to implementation of other integrations. 14 | services.AddTransient(); 15 | services.AddTransient(); 16 | services.AddSharedProviders(); 17 | } 18 | 19 | public static void AddSharedProviders(this IServiceCollection services) 20 | => services.AddTransient(); 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra.ClientSide/Infrastructure/Providers/ClientSideLoggingProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Logging; 2 | 3 | namespace AdminAssistant.Infrastructure.Providers; 4 | 5 | internal sealed class ClientSideLoggingProvider(ILoggerFactory loggerFactory) 6 | : LoggingProvider(loggerFactory, ILoggingProvider.ClientSideLogCategory) 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra.ClientSide/Infrastructure/Providers/DateTimeProvider.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.Providers; 2 | 3 | public interface IDateTimeProvider 4 | { 5 | /// 6 | ///Gets a System.DateTime object that is set to the current date and time on this 7 | ///computer, expressed as the Coordinated Universal Time (UTC). 8 | /// 9 | ///An object whose value is the current UTC date and time. 10 | DateTime UtcNow { get; } 11 | } 12 | 13 | internal sealed class DateTimeProvider : IDateTimeProvider 14 | { 15 | public DateTime UtcNow => DateTime.UtcNow; 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra.WebAPIClient/DependencyInjectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.DomainModel.Shared; 2 | namespace Microsoft.Extensions.DependencyInjection; 3 | 4 | public static class DependencyInjectionExtensions 5 | { 6 | public static void AddAdminAssistantWebAPIClient(this IServiceCollection services, ConfigurationSettings configurationSettings) 7 | => AddAdminAssistantWebAPIClient(services, new Uri(configurationSettings.WebApiClientBaseAddress)); 8 | 9 | public static void AddAdminAssistantWebAPIClient(this IServiceCollection services, Uri baseAddress) 10 | { 11 | //services.AddHttpClient(AdminAssistant.Constants.AdminAssistantWebAPIClient, (httpClient) => httpClient.BaseAddress = baseAddress); 12 | //services.AddAutoMapper(typeof(MappingProfile)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using AutoMapper; 2 | global using SimonGeering.Framework.Primitives; 3 | global using SimonGeering.Framework.TypeMapping; 4 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/DAL/IReadOnlyChildRepository.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.DAL; 2 | 3 | public interface IReadOnlyChildRepository 4 | where TDomainModel : IPersistable 5 | { 6 | Task GetAsync(int id, CancellationToken cancellationToken); 7 | Task> GetListAsync(int parentID, CancellationToken cancellationToken); 8 | Task> GetListAsync(IPersistable parent, CancellationToken cancellationToken) 9 | => GetListAsync(parent.PrimaryKey.Value, cancellationToken); 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/DAL/IReadOnlyRepository.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.DAL; 2 | 3 | public interface IReadOnlyRepository 4 | where TDomainModel : IPersistable 5 | where TId : Id 6 | { 7 | Task GetAsync(TId id, CancellationToken cancellationToken); 8 | Task> GetListAsync(CancellationToken cancellationToken); 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/DAL/IRepository.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.DAL; 2 | 3 | public interface IRepository : IReadOnlyRepository 4 | where TDomainModel : IPersistable 5 | where TId : Id 6 | { 7 | Task SaveAsync(TDomainModel domainObjectToSave, CancellationToken cancellationToken); 8 | Task DeleteAsync(TId id, CancellationToken cancellationToken); 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/DAL/RepositoryBase.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Infrastructure.EntityFramework; 2 | using AdminAssistant.Infrastructure.Providers; 3 | using AdminAssistant.Shared; 4 | 5 | namespace AdminAssistant.Infrastructure.DAL; 6 | 7 | internal abstract class RepositoryBase 8 | { 9 | protected IApplicationDbContext DbContext { get; } 10 | protected IMapper Mapper { get; } 11 | protected IDateTimeProvider DateTimeProvider { get; } 12 | protected IUserContextProvider UserContextProvider { get; } 13 | 14 | protected RepositoryBase(IApplicationDbContext dbContext, IMapper mapper, IDateTimeProvider dateTimeProvider, IUserContextProvider userContextProvider) 15 | { 16 | DbContext = dbContext; 17 | Mapper = mapper; 18 | DateTimeProvider = dateTimeProvider; 19 | UserContextProvider = userContextProvider; 20 | } 21 | 22 | protected static bool IsNew(IPersistable domainObject) => domainObject.IsNew; 23 | } 24 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Accounts/BankAccountTransactionDocumentEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 2 | 3 | public sealed class BankAccountTransactionDocumentEntity 4 | { 5 | // Table "Accounts.BankAccountTransactionDocument" 6 | public int BankAccountTransactionDocumentID { get; set; } // PK 7 | public int BankAccountTransactionID { get; set; } 8 | public int DocumentID { get; set; } 9 | public int AuditID { get; internal set; } 10 | public int PayeeID { get; internal set; } 11 | // Ref: "Accounts.BankAccountTransaction"."BankAccountTransactionID" < "Accounts.BankAccountTransactionDocument"."BankAccountTransactionDocumentID" 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Accounts/BankAccountTransactionTypeEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 4 | 5 | public sealed class BankAccountTransactionTypeEntity : IMapFrom, IMapTo 6 | { 7 | // Table "Accounts.BankAccountTransactionType" 8 | public int BankAccountTransactionTypeID { get; set; } // PK 9 | public string Description { get; set; } = string.Empty; 10 | public bool AllowPersonal { get; set; } 11 | public bool AllowCompany { get; set; } 12 | public bool IsDeprecated { get; set; } 13 | // Ref: "Accounts.BankAccountTransactionType"."BankAccountTransactionTypeID" < "Accounts.BankAccountTransaction"."BankAccountTransactionTypeID" 14 | 15 | public void MapFrom(AutoMapper.Profile profile) => profile 16 | .CreateMap() 17 | .ForMember(x => x.AllowPersonal, opt => opt.Ignore()) 18 | .ForMember(x => x.AllowCompany, opt => opt.Ignore()) 19 | .ForMember(x => x.IsDeprecated, opt => opt.Ignore()); 20 | } 21 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Accounts/BankAccountTypeEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 4 | 5 | public sealed class BankAccountTypeEntity : IMapFrom, IMapTo 6 | { 7 | public int BankAccountTypeID { get; set; } 8 | public string Description { get; set; } = string.Empty; 9 | public bool AllowPersonal { get; set; } 10 | public bool AllowCompany { get; set; } 11 | public bool IsDeprecated { get; set; } 12 | 13 | public void MapFrom(AutoMapper.Profile profile) => profile 14 | .CreateMap() 15 | .ForMember(x => x.AllowPersonal, opt => opt.Ignore()) 16 | .ForMember(x => x.AllowCompany, opt => opt.Ignore()) 17 | .ForMember(x => x.IsDeprecated, opt => opt.Ignore()); 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Accounts/BankEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 4 | 5 | public sealed class BankEntity : IMapFrom, IMapTo 6 | { 7 | public int BankID { get; set; } 8 | public string BankName { get; set; } = string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Accounts/PayeeContactEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 4 | 5 | public sealed class PayeeContactEntity : IMapFrom, IMapTo 6 | { 7 | // Table "Accounts.PayeeContact" 8 | public int PayeeContactID { get; set; } // PK 9 | public int PayeeID { get; set; } 10 | public int ContactID { get; set; } 11 | public int AuditID { get; set; } 12 | public bool IsPrimaryContact { get; set; } 13 | 14 | public Core.AuditEntity Audit { get; internal set; } = null!; 15 | 16 | public void MapFrom(AutoMapper.Profile profile) => profile 17 | .CreateMap() 18 | .ForMember(x => x.AuditID, opt => opt.Ignore()) 19 | .ForMember(x => x.Audit, opt => opt.Ignore()); 20 | } 21 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Accounts/PayeeEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.AccountsModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 4 | 5 | public sealed class PayeeEntity : IMapFrom, IMapTo 6 | { 7 | // Table "Accounts.Payee" 8 | public int PayeeID { get; set; } // PK 9 | public int AuditID { get; internal set; } 10 | public string Name { get; set; } = string.Empty; 11 | 12 | public Core.AuditEntity Audit { get; internal set; } = null!; 13 | 14 | public void MapFrom(AutoMapper.Profile profile) => profile 15 | .CreateMap() 16 | .ForMember(x => x.AuditID, opt => opt.Ignore()) 17 | .ForMember(x => x.Audit, opt => opt.Ignore()); 18 | 19 | // Ref: "Accounts.Payee"."PayeeID" < "Accounts.BankAccountTransaction"."PayeeID" 20 | // Ref: "Accounts.Payee"."PayeeID" < "Accounts.PayeeContact"."PayeeID" 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/AssetRegister/AssetEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.AssetRegister; 2 | 3 | public sealed class AssetEntity 4 | { 5 | // Table "Assets.Asset" 6 | public int AssetID { get; set; } // PK 7 | public int ManufacturerID { get; set; } 8 | public int AuditID { get; internal set; } 9 | public int OwnerID { get; internal set; } 10 | public int PurchasePrice { get; set; } 11 | public int DepreciatedValue { get; set; } 12 | public int ReplacementCost { get; set; } 13 | 14 | public Core.AuditEntity Audit { get; internal set; } = null!; 15 | public Core.OwnerEntity Owner { get; internal set; } = null!; 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/AssetRegister/ManufacturerEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.AssetRegister; 2 | 3 | public sealed class ManufacturerEntity 4 | { 5 | // Table "Assets.Manufacturer" 6 | public int ManufacturerID { get; set; } // PK 7 | public string ManufacturerName { get; set; } = string.Empty; 8 | public int AuditID { get; internal set; } 9 | 10 | public Core.AuditEntity Audit { get; internal set; } = null!; 11 | // Ref: "Assets.Manufacturer"."ManufacturerID" < "Assets.Asset"."ManufacturerID" 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/AssetRegisterSchema.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Infrastructure.EntityFramework.Model.AssetRegister; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace AdminAssistant.Infrastructure.EntityFramework.Model; 5 | 6 | internal static class AssetRegisterSchema 7 | { 8 | private const string Name = "Accounts"; 9 | 10 | internal static void OnModelCreating(ModelBuilder modelBuilder) => Asset_OnModelCreating(modelBuilder); 11 | 12 | private static void Asset_OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | modelBuilder.Entity().ToTable("Asset").Metadata.SetSchema(AssetRegisterSchema.Name); 15 | modelBuilder.Entity().Metadata.SetSchema("AssetRegister"); 16 | modelBuilder.Entity().HasKey(x => x.AssetID); 17 | modelBuilder.Entity().Property(x => x.PurchasePrice).IsRequired(); 18 | modelBuilder.Entity().Property(x => x.DepreciatedValue).IsRequired(); 19 | modelBuilder.Entity().Property(x => x.ReplacementCost).IsRequired(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Billing/ClientEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Billing; 2 | 3 | public sealed class ClientEntity 4 | { 5 | // Table "Billing.Client" 6 | public int ClientID { get; set; } // PK 7 | public string ClientName { get; set; } = string.Empty; 8 | public int AuditID { get; internal set; } 9 | 10 | public Core.AuditEntity Audit { get; internal set; } = null!; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Billing/InvoiceEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Billing; 2 | 3 | public sealed class InvoiceEntity 4 | { 5 | // Table "Billing.InvoiceEntity" 6 | public int InvoiceID { get; set; } // PK 7 | public int AuditID { get; internal set; } 8 | public int OwnerID { get; internal set; } 9 | 10 | public Core.AuditEntity Audit { get; internal set; } = null!; 11 | public Core.OwnerEntity Owner { get; internal set; } = null!; 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Billing/SupplierEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Billing; 2 | 3 | public sealed class SupplierEntity 4 | { 5 | // Table "Billing.SupplierEntity" 6 | public int SupplierID { get; set; } // PK 7 | public string SupplierName { get; set; } = string.Empty; 8 | public int AuditID { get; internal set; } 9 | 10 | public Core.AuditEntity Audit { get; internal set; } = null!; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/BillingSchema.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace AdminAssistant.Infrastructure.EntityFramework.Model; 5 | 6 | internal static class BillingSchema 7 | { 8 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "WIP")] 9 | private const string Name = "Billing"; 10 | 11 | [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "WIP")] 12 | internal static void OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | // TODO: BillingSchema.OnModelCreating 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Budget/BudgetEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Budget; 2 | 3 | public sealed class BudgetEntity 4 | { 5 | // Table "Budget.Budget" 6 | public int BudgetID { get; internal set; } // PK 7 | public int AuditID { get; internal set; } 8 | public int OwnerID { get; internal set; } 9 | public string BudgetName { get; set; } = string.Empty; 10 | 11 | public Core.AuditEntity Audit { get; internal set; } = null!; 12 | // Ref: "Budget.Budget"."BudgetID" < "Budget.BudgetEntry"."BudgetID" 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Budget/BudgetEntryEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Budget; 2 | 3 | public sealed class BudgetEntryEntity 4 | { 5 | // Table "Budget.BudgetEntry" 6 | public int BudgetEntryID { get; internal set; } // PK 7 | public int BudgetID { get; internal set; } 8 | public int AuditID { get; internal set; } 9 | 10 | public Core.AuditEntity Audit { get; internal set; } = null!; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Calendar/AppointmentEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Calendar; 2 | 3 | public sealed class AppointmentEntity 4 | { 5 | // Table "Calendar.Appointment" 6 | public int AppointmentD { get; set; } // PK 7 | public int AuditID { get; internal set; } 8 | 9 | public Core.AuditEntity Audit { get; internal set; } = null!; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/CalendarSchema.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace AdminAssistant.Infrastructure.EntityFramework.Model; 5 | 6 | internal static class CalendarSchema 7 | { 8 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "WIP")] 9 | private const string Name = "Calendar"; 10 | 11 | [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "WIP")] 12 | internal static void OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | // TODO: CalendarSchema.OnModelCreating 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Contacts/AddressEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Contacts; 2 | 3 | public sealed class AddressEntity 4 | { 5 | // Table "Contacts.Address" 6 | public int AddressID { get; set; } // PK 7 | public int AuditID { get; internal set; } 8 | 9 | public Core.AuditEntity Audit { get; internal set; } = null!; 10 | // Ref: "Contacts.Address"."AddressID" < "Contacts.ContactAddress"."AddressID" 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Contacts/ContactAddressEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Contacts; 2 | 3 | public sealed class ContactAddressEntity 4 | { 5 | // Table "Contacts.ContactAddress" 6 | public int ContactAddressID { get; set; } // PK 7 | public int AddressID { get; set; } 8 | public int ContactID { get; internal set; } 9 | public int AuditID { get; internal set; } 10 | 11 | public Core.AuditEntity Audit { get; internal set; } = null!; 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/CompanyEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class CompanyEntity 4 | { 5 | public int CompanyID { get; set; } 6 | public int AuditID { get; internal set; } 7 | public int UserProfileID { get; internal set; } 8 | public string Name { get; set; } = string.Empty; 9 | public string CompanyNumber { get; set; } = string.Empty; 10 | public string VATNumber { get; set; } = string.Empty; 11 | public DateTime DateOfIncorporation { get; set; } 12 | 13 | public AuditEntity Audit { get; set; } = null!; 14 | public UserProfileEntity UserProfile { get; set; } = null!; 15 | public IList Owns { get; internal set; } = new List(); 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/CurrencyEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.CoreModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 4 | 5 | public sealed class CurrencyEntity : IMapFrom, IMapTo 6 | { 7 | public int CurrencyID { get; set; } 8 | public string Symbol { get; set; } = string.Empty; 9 | public string DecimalFormat { get; set; } = string.Empty; 10 | public bool IsDeprecated { get; set; } 11 | 12 | public void MapFrom(AutoMapper.Profile profile) => profile 13 | .CreateMap() 14 | .ForMember(x => x.IsDeprecated, opt => opt.Ignore()); 15 | } 16 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/OwnerEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Infrastructure.EntityFramework.Model.Accounts; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 4 | 5 | public sealed class OwnerEntity 6 | { 7 | public int OwnerID { get; set; } 8 | public int? CompanyID { get; set; } 9 | public int? PersonalDetailsID { get; set; } 10 | 11 | public CompanyEntity Company { get; set; } = null!; 12 | public PersonalDetailsEntity PersonalDetails { get; set; } = null!; 13 | public IList BankAccounts { get; internal set; } = new List(); 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/PermissionEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class PermissionEntity 4 | { 5 | public int PermissionID { get; set; } 6 | 7 | public string PermissionKey { get; set; } = string.Empty; 8 | public IList UserProfilePermissions { get; internal set; } = new List(); 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/PersonalDetailsEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class PersonalDetailsEntity 4 | { 5 | public int PersonalDetailsID { get; set; } 6 | public int AuditID { get; internal set; } 7 | public int UserProfileID { get; internal set; } 8 | public AuditEntity Audit { get; set; } = null!; 9 | public UserProfileEntity UserProfile { get; set; } = null!; 10 | public IList Owns { get; internal set; } = new List(); 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/SettingEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class SettingEntity 4 | { 5 | public int SettingID { get; set; } 6 | public string SettingKey { get; set; } = string.Empty; 7 | public IList UserProfileSettings { get; internal set; } = new List(); 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/UserProfileEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class UserProfileEntity 4 | { 5 | public int UserProfileID { get; set; } 6 | public int AuditID { get; internal set; } 7 | public string SignOn { get; set; } = string.Empty; 8 | public string MSGraphID { get; set; } = string.Empty; 9 | 10 | public IList Permissions { get; } = new List(); 11 | public IList Settings { get; } = new List(); 12 | 13 | public IList Companies { get; } = new List(); 14 | public PersonalDetailsEntity PersonalDetails { get; set; } = null!; 15 | public AuditEntity Audit { get; set; } = null!; 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/UserProfilePermissionEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class UserProfilePermissionEntity 4 | { 5 | public int UserProfilePermissionID { get; set; } 6 | public int UserProfileID { get; set; } 7 | public int PermissionID { get; set; } 8 | 9 | public UserProfileEntity UserProfile { get; set; } = null!; 10 | public PermissionEntity Permission { get; internal set; } = null!; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Core/UserProfileSettingEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Core; 2 | 3 | public sealed class UserProfileSettingEntity 4 | { 5 | public int UserProfileSettingID { get; set; } 6 | public int UserProfileID { get; set; } 7 | public int SettingID { get; set; } 8 | 9 | public UserProfileEntity UserProfile { get; set; } = null!; 10 | public SettingEntity Setting { get; internal set; } = null!; 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Documents/DocumentEntity.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.DocumentsModule; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Documents; 4 | 5 | public sealed class DocumentEntity : IMapFrom, IMapTo 6 | { 7 | public int DocumentID { get; set; } 8 | public int AuditID { get; internal set; } 9 | public int OwnerID { get; internal set; } 10 | public string FileName { get; set; } = string.Empty; 11 | 12 | public Core.AuditEntity Audit { get; internal set; } = null!; 13 | 14 | public void MapFrom(AutoMapper.Profile profile) => profile 15 | .CreateMap() 16 | .ForMember(x => x.OwnerID, opt => opt.Ignore()) 17 | .ForMember(x => x.AuditID, opt => opt.Ignore()) 18 | .ForMember(x => x.Audit, opt => opt.Ignore()); 19 | } 20 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/DocumentsSchema.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Modules.DocumentsModule; 2 | using AdminAssistant.Infrastructure.EntityFramework.Model.Documents; 3 | using Microsoft.EntityFrameworkCore; 4 | 5 | namespace AdminAssistant.Infrastructure.EntityFramework.Model; 6 | 7 | internal static class DocumentsSchema 8 | { 9 | private const string Name = "Documents"; 10 | 11 | // TODO: DocumentsSchema.OnModelCreating 12 | internal static void OnModelCreating(ModelBuilder modelBuilder) => Document_OnModelCreating(modelBuilder); 13 | 14 | private static void Document_OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder.Entity().ToTable("Document").Metadata.SetSchema(Name); 17 | modelBuilder.Entity().HasKey(x => x.DocumentID); 18 | modelBuilder.Entity().Property(x => x.FileName).IsRequired().IsUnicode().HasMaxLength(Document.FileNameMaxLength); 19 | // TODO: Document_OnModelCreating 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Grocery/GroceryItemEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Grocery; 2 | 3 | public sealed class GroceryItemEntity 4 | { 5 | public int GroceryItemID { get; set; } 6 | public int AuditID { get; set; } 7 | public int OwnerID { get; internal set; } 8 | 9 | 10 | public string URI { get; set; } = string.Empty; 11 | 12 | public Core.AuditEntity Audit { get; internal set; } = null!; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Grocery/MealPlanEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Grocery; 2 | 3 | public sealed class MealPlanEntity 4 | { 5 | public int MealPlanID { get; set; } 6 | public int AuditID { get; set; } 7 | public int OwnerID { get; internal set; } 8 | 9 | public Core.AuditEntity Audit { get; internal set; } = null!; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/GrocerySchema.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Grocery; 4 | 5 | internal static class GrocerySchema 6 | { 7 | private const string Name = "Grocery"; 8 | 9 | // TODO: GrocerySchema.OnModelCreating 10 | internal static void OnModelCreating(ModelBuilder modelBuilder) => GroceryItem_OnModelCreating(modelBuilder); 11 | 12 | private static void GroceryItem_OnModelCreating(ModelBuilder modelBuilder) 13 | { 14 | modelBuilder.Entity().ToTable("GroceryItem").Metadata.SetSchema(GrocerySchema.Name); 15 | modelBuilder.Entity().HasKey(x => x.GroceryItemID); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/Tasks/TaskEntity.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure.EntityFramework.Model.Tasks; 2 | 3 | public sealed class TaskEntity 4 | { 5 | // Table "Tasks.Task" 6 | public int TaskID { get; set; } // PK 7 | public int AuditID { get; set; } 8 | public int OwnerID { get; internal set; } 9 | 10 | public Core.AuditEntity Audit { get; internal set; } = null!; 11 | public Core.OwnerEntity Owner { get; internal set; } = null!; 12 | } 13 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/Model/TasksSchema.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using Microsoft.EntityFrameworkCore; 3 | 4 | namespace AdminAssistant.Infrastructure.EntityFramework.Model; 5 | 6 | internal static class TasksSchema 7 | { 8 | [SuppressMessage("Performance", "CA1823:Avoid unused private fields", Justification = "WIP")] 9 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "WIP")] 10 | private const string Name = "Tasks"; 11 | 12 | [SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "WIP")] 13 | [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "WIP")] 14 | internal static void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | // TODO: DocumentsSchema.OnModelCreating 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/PostgresApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework; 4 | 5 | public sealed class PostgresApplicationDbContext(DbContextOptions options) 6 | : ApplicationDbContext(options, Shared.DatabaseProvider.PostgresSQL), IApplicationDbContext 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/SqlServerApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework; 4 | 5 | public sealed class SqlServerApplicationDbContext(DbContextOptions options) 6 | : ApplicationDbContext(options, Shared.DatabaseProvider.SQLServer), IApplicationDbContext 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/EntityFramework/SqliteApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace AdminAssistant.Infrastructure.EntityFramework; 4 | 5 | public sealed class SqliteApplicationDbContext(DbContextOptions options) 6 | : ApplicationDbContext(options, Shared.DatabaseProvider.SQLite), IApplicationDbContext 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/MappingProfile.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Infrastructure; 2 | 3 | public class MappingProfile() : MappingProfileBase(typeof(MappingProfile).Assembly); 4 | -------------------------------------------------------------------------------- /src/AdminAssistant.Infra/Infrastructure/Providers/ServerSideLoggingProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Logging; 2 | 3 | namespace AdminAssistant.Infrastructure.Providers; 4 | 5 | internal sealed class ServerSideLoggingProvider(ILoggerFactory loggerFactory) 6 | : LoggingProvider(loggerFactory, ILoggingProvider.ServerSideLogCategory) 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.Retro/DependencyInjectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using AdminAssistant.Retro.Modules.AccountsModule; 3 | 4 | namespace Microsoft.Extensions.DependencyInjection; 5 | 6 | public static class DependencyInjectionExtensions 7 | { 8 | public static IServiceCollection AddAdminAssistantRetroUIElements(this IServiceCollection services) 9 | { 10 | services.AddAccountsRetroUIElements(); 11 | return services; 12 | } 13 | 14 | [SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "WIP")] 15 | private static IServiceCollection AddAccountsRetroUIElements(this IServiceCollection services) 16 | { 17 | services.AddTransient(); 18 | //services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehaviour<,>)); // Use typeof because <,> 19 | return services; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.Retro/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Spellchecker", "CRRSP13:A misspelled word has been found", Justification = "US Spelling Used in base type", Scope = "member", Target = "~M:AdminAssistant.Retro.Modules.AccountsModule.BankAccountEditDialog.#ctor(AdminAssistant.UI.Modules.AccountsModule.IBankAccountEditDialogViewModel)")] 9 | [assembly: SuppressMessage("Spellchecker", "CRRSP09:A misspelled word has been found", Justification = "US Spelling Used in base type", Scope = "type", Target = "~T:AdminAssistant.Retro.Modules.AccountsModule.BankAccountEditDialog")] 10 | [assembly: SuppressMessage("Spellchecker", "CRRSP13:A misspelled word has been found", Justification = "US Spelling Used in base type")] 11 | [assembly: SuppressMessage("Minor Code Smell", "S3236:Caller information arguments should not be provided explicitly", Justification = "Specific situational message passed.")] 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.Retro/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using AdminAssistant.Retro.Shared; 2 | global using FluentValidation; 3 | global using Terminal.Gui; 4 | 5 | global using Trace = System.Diagnostics.Trace; 6 | -------------------------------------------------------------------------------- /src/AdminAssistant.Retro/Modules/Core/CurrencyListComponent.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/AdminAssistant.Retro/Modules/Core/CurrencyListComponent.cs -------------------------------------------------------------------------------- /src/AdminAssistant.Retro/Shared/DialogWindowBase.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Primitives.UI; 2 | 3 | namespace AdminAssistant.Retro.Shared; 4 | 5 | internal abstract class DialogWindowBase 6 | : Dialog 7 | where TViewModel : IViewModelBase 8 | { 9 | protected TViewModel VM {get; init;} 10 | 11 | protected DialogWindowBase(TViewModel vm, string title) 12 | { 13 | VM = vm; 14 | Title = title; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "dotnet-stryker": { 6 | "version": "3.12.0", 7 | "commands": [ 8 | "dotnet-stryker" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/AdminAssistant.Test/.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | AdminAssistant.* 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/AcceptanceTestBase.cs: -------------------------------------------------------------------------------- 1 | #if DEBUG // quick and dirty fix for #85 category filtering breaking CI Unit Test run. 2 | 3 | namespace AdminAssistant.Test; 4 | 5 | [Collection("SequentialDBBackedTests")] 6 | public abstract class AcceptanceTestBase : IntegrationTestBase 7 | { 8 | protected override Action ConfigureTestServices() => services => 9 | { 10 | base.ConfigureTestServices().Invoke(services); 11 | 12 | services.AddAdminAssistantClientSideProviders(); 13 | services.AddAdminAssistantClientSideDomainModel(); 14 | services.AddAdminAssistantUI(); 15 | }; 16 | } 17 | #endif // quick and dirty fix for #85 category filtering breaking CI Unit Test run. 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Ardalis.Result; 2 | global using FluentAssertions; 3 | global using Microsoft.Extensions.DependencyInjection; 4 | global using System.Diagnostics.CodeAnalysis; 5 | global using MediatR; 6 | global using MockQueryable.Moq; 7 | global using Moq; 8 | global using Xunit; 9 | 10 | global using IMapper = AutoMapper.IMapper; 11 | global using IConfigurationProvider = AutoMapper.IConfigurationProvider; 12 | global using MapperConfiguration = AutoMapper.MapperConfiguration; 13 | global using Severity = FluentValidation.Severity; 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/Properties/serviceDependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "secrets1": { 4 | "type": "secrets" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/AdminAssistant.Test/Properties/serviceDependencies.local.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "secrets1": { 4 | "type": "secrets.user" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/AdminAssistant.Test/README.md: -------------------------------------------------------------------------------- 1 | # AdminAssistant.Test - ReadMe 2 | 3 | ALL Commands assume a woking folder of the AdminAssistant.Test csproj file location. 4 | 5 | ## CLI Commands 6 | 7 | Restore tools from `.config/dotnet-tools.json` settings. 8 | 9 | > `dotnet tool restore` 10 | 11 | Run mutation tests 12 | 13 | > `dotnet stryker` 14 | 15 | ### Stryker mutation testing 16 | 17 | See (https://stryker-mutator.io/docs/stryker-net/introduction/) 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/TestConstants.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Test; 2 | 3 | public static class TestConstants 4 | { 5 | public const int Zero = 0; 6 | public const decimal ZeroSingle = 0.00M; 7 | } 8 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/UI/Modules/AccountsModule/BankEditDialogViewModel_UnitTest.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable CA1707 // Identifiers should not contain underscores 2 | using System.Diagnostics.CodeAnalysis; 3 | 4 | namespace AdminAssistant.Test.UI.Modules.AccountsModule; 5 | 6 | public sealed class BankEditDialogViewModel_Should 7 | { 8 | [Fact] 9 | [Trait("Category", "Unit")] 10 | [SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "WIP")] 11 | public async Task ShowAnNewBankAccount_WhenOpenedForCreate() 12 | { 13 | await Task.Delay(1000); 14 | } 15 | } 16 | #pragma warning restore CA1707 // Identifiers should not contain underscores 17 | -------------------------------------------------------------------------------- /src/AdminAssistant.Test/stryker-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "stryker-config": 3 | { 4 | "solution": "../AdminAssistant.sln", 5 | "project": "AdminAssistant.DomainModel.csproj", 6 | "test-case-filter": "Category=Unit", 7 | "reporters": [ 8 | "progress", 9 | "html" 10 | ], 11 | "ignore-methods": [ 12 | "*ConfigureAwait", 13 | "Log.Start", 14 | "Trace.Assert" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using AdminAssistant.Infrastructure.Providers; 2 | global using AdminAssistant.Primitives.UI; 3 | global using AdminAssistant.UI.Shared.WebAPIClient.v1; 4 | global using AutoMapper; 5 | global using CommunityToolkit.Mvvm.Input; 6 | global using CommunityToolkit.Mvvm.Messaging; 7 | global using CommunityToolkit.Mvvm.Messaging.Messages; 8 | global using FluentValidation.Results; 9 | global using SimonGeering.Framework.Primitives; 10 | global using System.ComponentModel; 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AccountsModule/AdminUI/BankListViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.AdminUI; 2 | 3 | public interface IBankListViewModel : IViewModelBase 4 | { 5 | IEnumerable Banks { get; } 6 | } 7 | 8 | internal sealed class BankListViewModel : ViewModelBase, IBankListViewModel 9 | { 10 | private readonly List _banks; 11 | 12 | public IEnumerable Banks => _banks.AsEnumerable(); 13 | 14 | public BankListViewModel(ILoggingProvider log) : base(log) 15 | => _banks = [ 16 | // TODO: Test data for mocking UI design bound to VM 17 | new Bank() { BankID = new(1), BankName = new("Barclays Bank plc") }, 18 | new Bank() { BankID = new(2), BankName = new("HSBC Bank (UK) Limited") }, 19 | new Bank() { BankID = new(3), BankName = new("Santander UK Plc") } 20 | ]; 21 | } 22 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AccountsModule/UI/AccountsViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.UI; 2 | 3 | public interface IAccountsViewModel : IModuleViewModelBase 4 | { 5 | BankAccount? SelectedBankAccount { get; } 6 | } 7 | internal sealed class AccountsViewModel(ILoggingProvider log) 8 | : ViewModelBase(log), IAccountsViewModel 9 | { 10 | public string HeaderText { get; } = "Accounts"; 11 | public string SubHeaderText { get; } = string.Empty; 12 | 13 | public BankAccount? SelectedBankAccount { get; } 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AccountsModule/UI/BankAccountBalanceListViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.UI; 2 | 3 | public interface IBankAccountBalanceListViewModel : IViewModelBase; 4 | 5 | internal sealed class BankAccountBalanceListViewModel(ILoggingProvider log) 6 | : ViewModelBase(log), IBankAccountBalanceListViewModel 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AccountsModule/UI/BankAccountRightSidebarViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.UI; 2 | 3 | public interface IBankAccountRightSidebarViewModel : IViewModelBase 4 | { 5 | IRelayCommand AddBankAccount { get; } 6 | } 7 | internal sealed class BankAccountRightSidebarViewModel : ViewModelBase, IBankAccountRightSidebarViewModel 8 | { 9 | private readonly IMessenger _messenger; 10 | 11 | public BankAccountRightSidebarViewModel( 12 | ILoggingProvider log, 13 | IMessenger messenger) 14 | : base(log) 15 | { 16 | _messenger = messenger; 17 | 18 | AddBankAccount = new RelayCommand(execute: OnAddBankAccountButtonClick); 19 | } 20 | 21 | public IRelayCommand AddBankAccount { get; } 22 | 23 | private void OnAddBankAccountButtonClick() 24 | { 25 | Log.Start(); 26 | 27 | _messenger.Send(new EditBankAccountMessage(new BankAccount())); 28 | 29 | Log.Finish(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AccountsModule/UI/BankAccountTransactionListViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.UI; 2 | 3 | public interface IBankAccountTransactionListViewModel : IViewModelBase 4 | { 5 | BindingList Transactions { get; } 6 | } 7 | internal sealed class BankAccountTransactionListViewModel(ILoggingProvider log) 8 | : ViewModelBase(log), IBankAccountTransactionListViewModel 9 | { 10 | public bool ShowAccountEditDialog { get; } 11 | public BankAccount? SelectedBankAccount { get; } 12 | public BindingList Transactions { get; } = []; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AccountsModule/UI/EditBankAccountMessage.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AccountsModule.UI; 2 | 3 | public sealed class EditBankAccountMessage(BankAccount bankAccount) 4 | { 5 | public BankAccount BankAccount { get; set; } = bankAccount; 6 | } 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AdminModule/AdminUI/AdminViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AdminModule.AdminUI; 2 | 3 | public interface IAdminViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class AdminViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IAdminViewModel 7 | { 8 | public string HeaderText => "Admin"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/AssetRegisterModule/UI/AssetRegisterViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.AssetRegisterModule.UI; 2 | 3 | public interface IAssetRegisterViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class AssetRegisterViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IAssetRegisterViewModel 7 | { 8 | public string HeaderText => "Asset Register"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/BillingModule/UI/BillingViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.BillingModule.UI; 2 | 3 | public interface IBillingViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class BillingViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IBillingViewModel 7 | { 8 | public string HeaderText => "Billing"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/BudgetModule/UI/BudgetViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.BudgetModule.UI; 2 | 3 | public interface IBudgetViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class BudgetViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IBudgetViewModel 7 | { 8 | public string HeaderText => "Budget"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/CalendarModule/UI/CalendarViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CalendarModule.UI; 2 | 3 | public interface ICalendarViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class CalendarViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), ICalendarViewModel 7 | { 8 | public string HeaderText => "Calendar"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/ContactsModule/UI/ContactsViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.ContactsModule.UI; 2 | 3 | public interface IContactsViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class ContactsViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IContactsViewModel 7 | { 8 | public string HeaderText => "Contacts"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/CoreModule/AdminUI/CurrencyListViewModel.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.Domain; 2 | 3 | namespace AdminAssistant.Modules.CoreModule.AdminUI; 4 | 5 | public interface ICurrencyListViewModel : IViewModelBase 6 | { 7 | IEnumerable Currencies { get; } 8 | } 9 | internal sealed class CurrencyListViewModel(ILoggingProvider log) 10 | : ViewModelBase(log), ICurrencyListViewModel 11 | { 12 | private readonly List _currencies = 13 | [ 14 | Factory.Currency.WithTestData(1).WithSymbol("GBP").Build(), 15 | Factory.Currency.WithTestData(2).WithSymbol("EUR").Build(), 16 | Factory.Currency.WithTestData(3).WithSymbol("USD").Build() 17 | ]; 18 | 19 | public IEnumerable Currencies => _currencies.AsEnumerable(); 20 | } 21 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/CoreModule/UI/CoreService.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.CoreModule.UI; 2 | 3 | public interface ICoreService 4 | { 5 | Task> GetCurrencyListAsync(); 6 | } 7 | 8 | internal sealed class CoreService(IAdminAssistantWebAPIClient adminAssistantWebAPIClient, IMapper mapper, ILoggingProvider log) 9 | : ServiceBase(adminAssistantWebAPIClient, mapper, log), ICoreService 10 | { 11 | public async Task> GetCurrencyListAsync() 12 | { 13 | Log.Start(); 14 | 15 | var response = await AdminAssistantWebAPIClient.GetCurrencyAsync().ConfigureAwait(false); 16 | 17 | var result = new List(Mapper.Map>(response)); 18 | result.Insert(0, new Currency() { CurrencyID = CurrencyId.Default, Symbol = string.Empty, DecimalFormat = string.Empty }); 19 | 20 | return Log.Finish(result); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/DashboardModule/UI/DashboardViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.DashboardModule.UI; 2 | 3 | public interface IDashboardViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class DashboardViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IDashboardViewModel 7 | { 8 | public string HeaderText => "Dashboard"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/DocumentsModule/UI/DocumentsService.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.DocumentsModule.UI; 2 | 3 | public interface IDocumentsService 4 | { 5 | Task> GetDocumentListAsync(); 6 | } 7 | internal sealed class DocumentsService( 8 | IAdminAssistantWebAPIClient adminAssistantWebAPIClient, 9 | IMapper mapper, 10 | ILoggingProvider log) 11 | : ServiceBase(adminAssistantWebAPIClient, mapper, log), IDocumentsService 12 | { 13 | public async Task> GetDocumentListAsync() 14 | { 15 | Log.Start(); 16 | 17 | var response = await AdminAssistantWebAPIClient.GetDocumentAsync().ConfigureAwait(false); 18 | var result = new List(Mapper.Map>(response)); 19 | 20 | return Log.Finish(result); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/DocumentsModule/UI/DocumentsViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.DocumentsModule.UI; 2 | 3 | public interface IDocumentsViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class DocumentsViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IDocumentsViewModel 7 | { 8 | public string HeaderText => "Documents"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/MailModule/UI/MailViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.MailModule.UI; 2 | 3 | public interface IMailViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class MailViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IMailViewModel 7 | { 8 | public string HeaderText => "Mail"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/NotesModule/UI/NotesViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.NotesModule.UI; 2 | 3 | public interface INotesViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class NotesViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), INotesViewModel 7 | { 8 | public string HeaderText => "Notes"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/ReportsModule/UI/ReportingViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.ReportsModule.UI; 2 | 3 | public interface IReportsViewModel : IModuleViewModelBase; 4 | 5 | internal sealed class ReportsViewModel(ILoggingProvider loggingProvider) 6 | : ViewModelBase(loggingProvider), IReportsViewModel 7 | { 8 | public string HeaderText => "Reports"; 9 | public string SubHeaderText => string.Empty; 10 | } 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Modules/TasksModule/UI/TasksViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Modules.TasksModule.UI; 2 | 3 | public interface ITasksViewModel : IModuleViewModelBase; 4 | internal sealed class TasksViewModel(ILoggingProvider loggingProvider) 5 | : ViewModelBase(loggingProvider), ITasksViewModel 6 | { 7 | public string HeaderText => "Tasks"; 8 | public string SubHeaderText => string.Empty; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Primitives/UI/IModuleViewModelBase.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Primitives.UI; 2 | 3 | public interface IModuleViewModelBase : IViewModelBase 4 | { 5 | string PageTitle => HeaderText; 6 | string HeaderText { get; } 7 | string SubHeaderText { get; } 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Primitives/UI/ServiceBase.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Primitives.UI; 2 | 3 | internal abstract class ServiceBase 4 | { 5 | protected IAdminAssistantWebAPIClient AdminAssistantWebAPIClient { get; } 6 | protected IMapper Mapper { get; } 7 | protected ILoggingProvider Log { get; } 8 | 9 | protected ServiceBase(IAdminAssistantWebAPIClient adminAssistantWebAPIClient, IMapper mapper, ILoggingProvider log) 10 | { 11 | AdminAssistantWebAPIClient = adminAssistantWebAPIClient; 12 | Log = log; 13 | Mapper = mapper; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/ExpandedContractedStateToggle.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public enum ExpandedContractedStateToggle 4 | { 5 | Expanded, 6 | Contracted, 7 | } 8 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/FontAwesomeVersion.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public enum FontAwesomeVersion 4 | { 5 | V4o7o0, 6 | V5o15o4, 7 | V6o2o1, 8 | } 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/Mode.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public enum Mode 4 | { 5 | Personal, 6 | Company, 7 | } 8 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/ModeSelectionChangedMessage.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public class ModeSelectionChangedMessage(ModeSelectionItem modeSelectionItem) 4 | : ValueChangedMessage(modeSelectionItem) 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/ModeSelectionItem.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public sealed class ModeSelectionItem(Mode mode, string tag, string label, string icon) 4 | { 5 | public Mode Mode { get; set; } = mode; 6 | public string Tag { get; set; } = tag; 7 | public string Label { get; set; } = label; 8 | public string Icon { get; set; } = icon; 9 | 10 | public override string ToString() => Mode.ToString(); 11 | } 12 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/Module.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public enum Module 4 | { 5 | Accounts, 6 | Admin, 7 | AssetRegister, 8 | Billing, 9 | Budget, 10 | Calendar, 11 | Contacts, 12 | Dashboard, 13 | Documents, 14 | Notes, 15 | Mail, 16 | Reports, 17 | Tasks 18 | } 19 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/ModuleSelectionChangedMessage.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public sealed class ModuleSelectionChangedMessage(ModuleSelectionItem moduleSelectionItem) 4 | : ValueChangedMessage(moduleSelectionItem) 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/ModuleSelectionItem.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public sealed class ModuleSelectionItem(Module module, string tag, string label, string icon) 4 | { 5 | public string ID => Module.ToString(); 6 | public Module Module { get; set; } = module; 7 | public string Tag { get; set; } = tag; 8 | 9 | public string Label { get; set; } = label; 10 | public string Icon { get; set; } = icon; 11 | public string Route { get; set; } = $"/{module.ToString().ToLowerInvariant()}"; 12 | public string StyleClass { get; set; } = string.Empty; 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.UI/Shared/UI/SidebarStateSettings.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.Shared.UI; 2 | 3 | public sealed class SidebarStateSettings(ExpandedContractedStateToggle state, string icon, string styleClass, bool showContent) 4 | { 5 | public ExpandedContractedStateToggle State { get; private set; } = state; 6 | public string Icon { get; private set; } = icon; 7 | public string StyleClass { get; private set; } = styleClass; 8 | public bool ShowContent { get; set; } = showContent; 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/App.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] 11 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace AdminAssistant.WPF 2 | { 3 | public partial class MainWindow : Syncfusion.Windows.Shared.ChromelessWindow 4 | { 5 | public MainWindow() => InitializeComponent(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/AccountsComponent.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/AccountsComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.AccountsModule 4 | { 5 | public partial class AccountsComponent : UserControl 6 | { 7 | public AccountsComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountBalanceListComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountBalanceListComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.AccountsModule 4 | { 5 | public partial class BankAccountBalanceListComponent : UserControl 6 | { 7 | public BankAccountBalanceListComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountEditDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using AdminAssistant.UI.Modules.AccountsModule; 3 | using Syncfusion.Windows.Shared; 4 | 5 | namespace AdminAssistant.WPF.Modules.AccountsModule 6 | { 7 | public partial class BankAccountEditDialog : ChromelessWindow 8 | { 9 | public BankAccountEditDialog() => InitializeComponent(); 10 | 11 | private void ChromelessWindow_Loaded(object sender, RoutedEventArgs e) => ((IBankAccountEditDialogViewModel)DataContext).Loaded.ExecuteAsync(null); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountRightSidebarComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountRightSidebarComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.AccountsModule 4 | { 5 | public partial class BankAccountRightSidebarComponent : UserControl 6 | { 7 | public BankAccountRightSidebarComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountTransactionListComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AccountsModule/BankAccountTransactionListComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.AccountsModule 4 | { 5 | public partial class BankAccountTransactionListComponent : UserControl 6 | { 7 | public BankAccountTransactionListComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/Admin/AdminComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/Admin/AdminComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.Admin 4 | { 5 | public partial class AdminComponent : UserControl 6 | { 7 | public AdminComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AssetRegisterModule/AssetRegisterComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/AssetRegisterModule/AssetRegisterComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.AssetRegisterModule 4 | { 5 | public partial class AssetRegisterComponent : UserControl 6 | { 7 | public AssetRegisterComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/BillingModule/BillingComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/BillingModule/BillingComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.BillingModule 4 | { 5 | public partial class BillingComponent : UserControl 6 | { 7 | public BillingComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/BudgetModule/BudgetComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/BudgetModule/BudgetComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.BudgetModule 4 | { 5 | public partial class BudgetComponent : UserControl 6 | { 7 | public BudgetComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/CalendarModule/CalendarComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/CalendarModule/CalendarComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.CalendarModule 4 | { 5 | public partial class CalendarComponent : UserControl 6 | { 7 | public CalendarComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/ContactsModule/ContactsComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/ContactsModule/ContactsComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.ContactsModule 4 | { 5 | public partial class ContactsComponent : UserControl 6 | { 7 | public ContactsComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/DashboardModule/DashboardComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/DashboardModule/DashboardComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.DashboardModule 4 | { 5 | public partial class DashboardComponent : UserControl 6 | { 7 | public DashboardComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/DocumentsModule/DocumentsComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/DocumentsModule/DocumentsComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.DocumentsModule 4 | { 5 | public partial class DocumentsComponent : UserControl 6 | { 7 | public DocumentsComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/MailModule/MailComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/MailModule/MailComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace AdminAssistant.WPF.Modules.MailModule 4 | { 5 | public partial class MailComponent : UserControl 6 | { 7 | public MailComponent() => InitializeComponent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/ReportsModule/ReportsComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/ReportsModule/ReportsComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | using AdminAssistant.UI.Modules.ReportsModule; 3 | 4 | namespace AdminAssistant.WPF.Modules.ReportsModule 5 | { 6 | public partial class ReportsComponent : UserControl 7 | { 8 | public ReportsComponent() => InitializeComponent(); 9 | 10 | public ReportsComponent(IReportsViewModel reportsViewModel) 11 | : this() => DataContext = reportsViewModel; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/TasksModule/TasksComponent.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Modules/TasksModule/TasksComponent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | using AdminAssistant.UI.Modules.TasksModule; 3 | 4 | namespace AdminAssistant.WPF.Modules.TasksModule 5 | { 6 | public partial class TasksComponent : UserControl 7 | { 8 | public TasksComponent() => InitializeComponent(); 9 | 10 | public TasksComponent(ITasksViewModel tasksViewModel) 11 | : this() => DataContext = tasksViewModel; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Shared/ModeExtensions.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.UI.Shared; 2 | using MahApps.Metro.IconPacks; 3 | 4 | namespace AdminAssistant.WPF.Shared; 5 | 6 | public static class ModeExtensions 7 | { 8 | public static PackIconFontAwesomeKind ToPackIconFontAwesomeKind(this Mode module) => module switch 9 | { 10 | Mode.Company => PackIconFontAwesomeKind.BuildingRegular, 11 | Mode.Personal => PackIconFontAwesomeKind.UserSolid, 12 | _ => PackIconFontAwesomeKind.None 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Shared/ModeImageExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Markup; 2 | using System.Windows.Media; 3 | using AdminAssistant.UI.Shared; 4 | using MahApps.Metro.IconPacks; 5 | 6 | namespace AdminAssistant.WPF.Shared; 7 | 8 | [MarkupExtensionReturnType(typeof(ImageSource))] 9 | public sealed class ModeImageExtension : FontAwesomeImageExtension 10 | { 11 | private Mode mode; 12 | 13 | [ConstructorArgument("mode")] 14 | public Mode Mode 15 | { 16 | get => mode; 17 | set 18 | { 19 | base.Kind = value.ToPackIconFontAwesomeKind(); 20 | mode = value; 21 | } 22 | } 23 | 24 | public ModeImageExtension() 25 | : base() 26 | { 27 | } 28 | 29 | public ModeImageExtension(Mode mode) 30 | : base(mode.ToPackIconFontAwesomeKind()) 31 | { 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Shared/ModuleExtensions.cs: -------------------------------------------------------------------------------- 1 | using AdminAssistant.UI.Shared; 2 | using MahApps.Metro.IconPacks; 3 | 4 | namespace AdminAssistant.WPF.Shared; 5 | 6 | public static class ModuleExtensions 7 | { 8 | public static PackIconFontAwesomeKind ToPackIconFontAwesomeKind(this Module module) => module switch 9 | { 10 | Module.Accounts => PackIconFontAwesomeKind.PoundSignSolid, 11 | Module.AssetRegister => PackIconFontAwesomeKind.GemRegular, 12 | Module.Billing => PackIconFontAwesomeKind.BullseyeSolid, 13 | Module.Budget => PackIconFontAwesomeKind.ChartLineSolid, 14 | Module.Calendar => PackIconFontAwesomeKind.CalendarAltRegular, 15 | Module.Contacts => PackIconFontAwesomeKind.AddressBookRegular, 16 | Module.Dashboard => PackIconFontAwesomeKind.TachometerAltSolid, 17 | Module.Documents => PackIconFontAwesomeKind.FileAltRegular, 18 | Module.Mail => PackIconFontAwesomeKind.EnvelopeRegular, 19 | Module.Reports => PackIconFontAwesomeKind.ChartBarRegular, 20 | Module.Tasks => PackIconFontAwesomeKind.FlagRegular, 21 | // Module.Setup => PackIconFontAwesomeKind.ToolsSolid, 22 | _ => PackIconFontAwesomeKind.None 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/AdminAssistant.WPF/Shared/ModuleImageExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Markup; 2 | using System.Windows.Media; 3 | using AdminAssistant.UI.Shared; 4 | using MahApps.Metro.IconPacks; 5 | 6 | namespace AdminAssistant.WPF.Shared; 7 | 8 | [MarkupExtensionReturnType(typeof(ImageSource))] 9 | public sealed class ModuleImageExtension : FontAwesomeImageExtension 10 | { 11 | private Module module; 12 | 13 | [ConstructorArgument("module")] 14 | public Module Module 15 | { 16 | get => module; 17 | set { 18 | base.Kind = value.ToPackIconFontAwesomeKind(); 19 | module = value; 20 | } 21 | } 22 | 23 | public ModuleImageExtension() 24 | : base() 25 | { 26 | } 27 | 28 | public ModuleImageExtension(Module module) 29 | : base(module.ToPackIconFontAwesomeKind()) 30 | { 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/AdminAssistant.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | Admin Assistant 5 | AdminAssistant 6 | enable 7 | enable 8 | latest 9 | AnyCPU 10 | AnyCPU 11 | true 12 | latest 13 | true 14 | 15 | $(NoWarn);S1133;S1135;S1125;1701;1702;1591;NU1605;CS1591 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/ApplicationBaseExceptionBase.cs: -------------------------------------------------------------------------------- 1 | namespace SimonGeering.Framework; 2 | 3 | public abstract class ApplicationBaseException : Exception 4 | { 5 | protected ApplicationBaseException(string? message) 6 | : base(message) 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/Configuration/ConfigurationException.cs: -------------------------------------------------------------------------------- 1 | namespace SimonGeering.Framework.Configuration; 2 | 3 | public class ConfigurationException(string? message) 4 | : ApplicationBaseException(message) { } 5 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace SimonGeering.Framework; 2 | 3 | /// 4 | /// Global Constants. 5 | /// 6 | public static class Constants 7 | { 8 | /// 9 | /// Represents the index of the first item in an array. 10 | /// 11 | /// Used to implement https://rules.sonarsource.com/csharp/RSPEC-6608/ 12 | public const int FirstItem = 0; 13 | 14 | /// 15 | /// The default value for a RecordID. 16 | /// 17 | public const int UnknownRecordID = default; 18 | 19 | /// 20 | /// The value for a RecordID on an un-saved record. 21 | /// 22 | public const int NewRecordID = default; 23 | 24 | /// 25 | /// The date format used throughout the application. 26 | /// 27 | /// 28 | /// The application does not currently support internationalization so this is sufficient for now. 29 | /// 30 | public const string DefaultDateFormat = "dd-MMM-yyyy"; 31 | } 32 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/Primitives/IDatabasePersistable.cs: -------------------------------------------------------------------------------- 1 | namespace SimonGeering.Framework.Primitives; 2 | 3 | /// 4 | /// Allows implementing class to be persisted to a relational database. 5 | /// 6 | public interface IPersistable 7 | { 8 | /// 9 | /// The Unique Identifier for the entity within its coresponding database table. 10 | /// 11 | Id PrimaryKey { get; } 12 | 13 | /// 14 | /// Flag to determine if the entity is newly created in memory or if it has been previously persisted to the database. 15 | /// 16 | bool IsNew => PrimaryKey.IsNewRecordID; 17 | } 18 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/Primitives/Id.cs: -------------------------------------------------------------------------------- 1 | namespace SimonGeering.Framework.Primitives; 2 | 3 | public abstract record Id(int Value) 4 | { 5 | public bool IsUnknownRecordID => Value == Constants.UnknownRecordID; 6 | 7 | /// 8 | /// Flag to determine if the entity is newly created in memory or if it has been previously persisted to the database. 9 | /// 10 | public bool IsNewRecordID => Value == Constants.NewRecordID; 11 | } 12 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/Primitives/ValueObject.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | 3 | namespace SimonGeering.Framework.Primitives; 4 | 5 | public abstract class ValueObject : IEqualityComparer, IEquatable 6 | { 7 | public abstract IEnumerable GetAtomicValues(); 8 | 9 | public bool Equals(ValueObject? other) 10 | => other is not null && ValuesAreEqual(other); 11 | 12 | public override bool Equals(object? obj) 13 | => obj is ValueObject other && ValuesAreEqual(other); 14 | 15 | public bool Equals(ValueObject? x, ValueObject? y) 16 | => x is not null && x.Equals(y); 17 | 18 | public override int GetHashCode() 19 | => GetAtomicValues().Aggregate(default(int), HashCode.Combine); 20 | 21 | public int GetHashCode([DisallowNull] ValueObject obj) 22 | => obj.GetHashCode(); 23 | 24 | private bool ValuesAreEqual(ValueObject other) 25 | => GetAtomicValues().SequenceEqual(other.GetAtomicValues()); 26 | } 27 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/SimonGeering.Framework.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SimonGeering.Framework 5 | SimonGeering.Framework.docs.xml 6 | $(NoWarn); 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/TypeMapping/IMapFrom.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace SimonGeering.Framework.TypeMapping; 4 | 5 | /// Maps from the given type to the implementing type. 6 | /// The type to map from. 7 | public interface IMapFrom 8 | { 9 | void MapFrom(Profile profile) => profile.CreateMap(typeof(TSource), GetType()); 10 | } 11 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/TypeMapping/IMapTo.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | 3 | namespace SimonGeering.Framework.TypeMapping; 4 | 5 | /// Maps from the implementing type to the given type. 6 | /// The type to map to. 7 | public interface IMapTo 8 | { 9 | void MapTo(Profile profile) => profile.CreateMap(GetType(), typeof(TDestination)); 10 | } 11 | -------------------------------------------------------------------------------- /src/SimonGeering.Framework/TypeMapping/TypeMappingException.cs: -------------------------------------------------------------------------------- 1 | namespace SimonGeering.Framework.TypeMapping; 2 | 3 | public class TypeMappingException(string? message) 4 | : ApplicationBaseException(message) { } 5 | -------------------------------------------------------------------------------- /src/dev.template.env: -------------------------------------------------------------------------------- 1 | MSSQL_SA_PASSWORD: "" 2 | ACCEPT_EULA: "Y" 3 | -------------------------------------------------------------------------------- /src/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.100" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/uml/AdminAssistant.EAP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimonGeering/AdminAssistant/f7102cebeacda68299adf3b62388c15e1dcfb357/src/uml/AdminAssistant.EAP -------------------------------------------------------------------------------- /src/uml/ComponentDependencies.mmd: -------------------------------------------------------------------------------- 1 | graph TD 2 | subgraph Framework 3 | id8([AdminAssistant.Framework]) 4 | id9(AdminAssistant.Framework.Test) 5 | style id9 fill:#FFE699 6 | id9 --> id8 7 | end 8 | 9 | subgraph Entry Points 10 | id1(AdminAssistant.Blazor.Server) 11 | style id1 fill:#C6E0B4 12 | id2(AdminAssistant.Blazor.Client) 13 | style id2 fill:#C6E0B4 14 | id6(AdminAssistant.Test) 15 | style id6 fill:#FFE699 16 | end 17 | 18 | subgraph Core 19 | id3([AdminAssistant]) 20 | style id3 fill:#B4C6E7 21 | id4([AdminAssistant.DAL]) 22 | style id4 fill:#B4C6E7 23 | id5([AdminAssistant.DomainModel]) 24 | style id5 fill:#B4C6E7 25 | id7([AdminAssistant.UI]) 26 | style id7 fill:#B4C6E7 27 | end 28 | 29 | id1 --> id2 30 | id1 --> id4 31 | id1 --> id5 32 | id1 --> id8 33 | 34 | id2 --> id5 35 | id2 --> id7 36 | 37 | id4 --> id3 38 | id4 --> id8 39 | 40 | id5 --> id3 41 | 42 | id6 --> id5 43 | 44 | id7 --> id3 45 | -------------------------------------------------------------------------------- /src/uml/Database Schema Design.mmd: -------------------------------------------------------------------------------- 1 | erDiagram 2 | CUSTOMER ||--o{ ORDER : places 3 | ORDER ||--|{ LINE-ITEM : contains 4 | CUSTOMER }|..|{ DELIVERY-ADDRESS : uses 5 | --------------------------------------------------------------------------------