feat: Email Accounts per Store#680
Conversation
- Add StoreId property to EmailAccount domain entity - Add GetEmailAccountsByStore(storeId) method to IEmailAccountService and EmailAccountService - Add EMAILACCOUNT_BY_STORE_KEY cache key - Update MessageProviderService to use store-specific email account as fallback - Update EmailAccountModel with StoreId and AvailableStores - Update EmailAccountProfile mapper to include StoreId - Update EmailAccountViewModelService to be async and populate available stores - Add EmailAccountController to Grand.Web.Store with CRUD + store isolation - Add EmailAccount views (List, Create, Edit, Partials/CreateOrUpdate) in Store area - Add Messages namespace to Store _ViewImports.cshtml - Update Admin EmailAccountController for async PrepareEmailAccountModel Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/094d04cc-7d75-4a00-af14-f5bb77f05736 Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/094d04cc-7d75-4a00-af14-f5bb77f05736 Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…vent dirty data Instead of caching per-store results separately (which could hold stale/mutated objects when an account's StoreId changes), filter directly from the already correctly-invalidated GetAllEmailAccounts cache. Also removes the now-unused EMAILACCOUNT_BY_STORE_KEY constant. Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/5697bb0d-b979-44be-8f1a-2f8c98ad8b5e Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
|
@copilot Grand.Web.Store should not see all available store |
…lableStores/PrepareEmailAccountModel calls Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/d1fe358f-d64b-47c9-af25-cea72fae9de0 Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
Fixed in 84fdff0. The Store controller was calling Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot check my comments |
…tEmailAccountsByStore, pass store?.Id to GetEmailAccountOfMessageTemplate callers Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/dba495a6-918d-4de2-8bc5-ae0409bfb8ff Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
Both comments addressed in 5994a60:
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot GetEmailAccountOfMessageTemplate remove param storeId |
Done in 50dfcbc. |
There was a problem hiding this comment.
Pull request overview
Adds store-scoped email accounts across domain/service layers and exposes CRUD management in the Store area UI, while updating Admin UI to support selecting a store scope for each email account.
Changes:
- Introduces
StoreIdonEmailAccountand extendsGetAllEmailAccountswith an optional store filter. - Updates AdminShared model/mapping and view-model service to support store selection (available stores list).
- Adds Store-area
EmailAccountControllerplus corresponding views for store-isolated management.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Web/Grand.Web.Store/Controllers/EmailAccountController.cs | New Store-area CRUD controller for email accounts filtered to current staff store |
| src/Web/Grand.Web.Store/Areas/Store/Views/_ViewImports.cshtml | Adds messages model namespace for Store-area views |
| src/Web/Grand.Web.Store/Areas/Store/Views/EmailAccount/Partials/CreateOrUpdate.cshtml | New create/edit partial for Store area (hidden StoreId) |
| src/Web/Grand.Web.Store/Areas/Store/Views/EmailAccount/List.cshtml | New Kendo grid list view for Store area |
| src/Web/Grand.Web.Store/Areas/Store/Views/EmailAccount/Edit.cshtml | New Store-area edit view |
| src/Web/Grand.Web.Store/Areas/Store/Views/EmailAccount/Create.cshtml | New Store-area create view |
| src/Web/Grand.Web.AdminShared/Services/EmailAccountViewModelService.cs | Makes model preparation async and populates available stores for selection |
| src/Web/Grand.Web.AdminShared/Models/Messages/EmailAccountModel.cs | Adds StoreId + AvailableStores to the model |
| src/Web/Grand.Web.AdminShared/Mapper/EmailAccountProfile.cs | Updates mapping to ignore AvailableStores |
| src/Web/Grand.Web.AdminShared/Interfaces/IEmailAccountViewModelService.cs | Makes PrepareEmailAccountModel async; adds PrepareAvailableStores |
| src/Web/Grand.Web.Admin/Controllers/EmailAccountController.cs | Uses async model preparation and populates stores on Edit GET |
| src/Web/Grand.Web.Admin/Areas/Admin/Views/EmailAccount/Partials/CreateOrUpdate.cshtml | Adds Store selector dropdown to Admin email account editor |
| src/Tests/Grand.Business.Messages.Tests/Services/MessageProviderServiceTest.cs | Updates mock setup for the new GetAllEmailAccounts signature |
| src/Core/Grand.Domain/Messages/EmailAccount.cs | Adds StoreId to the domain entity |
| src/Business/Grand.Business.Messages/Services/MessageProviderService.cs | Simplifies email account resolution for message templates |
| src/Business/Grand.Business.Messages/Services/EmailAccountService.cs | Adds optional store filter to GetAllEmailAccounts |
| src/Business/Grand.Business.Core/Interfaces/Messages/IEmailAccountService.cs | Updates interface signature/documentation for store-filtered retrieval |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot Do not cache email accounts, add paggination from db |
…ailAccounts Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/4d8b440d-2667-411f-b545-771aa6e92352 Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Already done in 779107e:
|
|
@copilot Grand.Business.Messages.Tests.Services.EmailAccountServiceTests.DeleteEmailAccount_InvokeExpectedMethods |
…elete checks Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/9732f29d-bac6-466a-b11d-52f4683a11e7 Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
Fixed in ce8ffbc. The two
All 4 |
|
@copilot when I click Send test email I get excepion page instead errors |
…functionality-per-store
Agent-Logs-Url: https://github.com/grandnode/grandnode2/sessions/6727ccd0-9afa-441f-a749-799b26e59f11 Co-authored-by: KrzysztofPajak <16772986+KrzysztofPajak@users.noreply.github.com>
Fixed in e9e6d0a. The Store Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
DeleteEmailAccount_InvokeExpectedMethods— replaced stale cache mock with_repository.Setup(r => r.Table).Returns(...)returning 2 accountsDeleteEmailAccount_ExistOnlyOneAccount_ThrowException— proper Table mock and awaited assertionSendTestEmailin StoreEmailAccountController— catchExceptioninstead of onlyGrandExceptionso SMTP errors (e.g.ArgumentException: host name cannot be empty) are shown as inline error notifications instead of the global error page, matching the Admin controller's pattern