Skip to content

ARCH-001 Phase 26: consolidate Admin/Store OnlineCustomerController - #827

Merged
KrzysztofPajak merged 1 commit into
developfrom
arch001/phase26-onlinecustomer-consolidation
Sep 11, 2026
Merged

KrzysztofPajak merged 1 commit into
developfrom
arch001/phase26-onlinecustomer-consolidation

Conversation

@KrzysztofPajak

Copy link
Copy Markdown
Member

ARCH-001 Phase 26: OnlineCustomerController consolidation

One of several fresh candidates found by a repo-wide Admin/Store/Vendor controller survey. Admin's
and Store's OnlineCustomerController were near-identical (~80 lines each) — same List GET/POST
grid action, same GetOnlineCustomers call and model mapping. No domain entity, no per-store/
per-vendor scope beyond the StaffStoreId filter both hosts already applied identically, so — like
BasePictureController — no IAdminDataScope<TEntity> is needed. Vendor never had its own copy.

The one real difference

Admin restricts the online-customer list to the current Sales-Manager's own customers via
GetOnlineCustomers's salesEmployeeId parameter; Store has no such concept and always passes
null. Parameterized with a protected virtual SalesEmployeeIdFilter member on the new
BaseOnlineCustomerController — the same idiom this repo's pre-existing BaseLoginController
already uses for its own host-specific GetCurrentArea() value. Admin's thin subclass overrides it
to the current customer's SeId; Store keeps the base's null default.

Change

Both List actions moved into BaseOnlineCustomerController (Grand.Web.AdminShared), carrying
[PermissionAuthorize(PermissionSystemName.Customers)] and [AutoValidateAntiforgeryToken].
Admin/Store OnlineCustomerController are now thin subclasses restating their host's
[AuthorizeAdmin|AuthorizeStore]/[Area]/[AuthorizeMenu] attribute set — same shape as
BaseProductController, BasePictureController, etc. No behavior change (the LINQ-vs-foreach
style difference between the two originals produced identical output; unified on Store's LINQ form).

Tests

No prior test coverage existed for either controller. Added:

  • BaseOnlineCustomerControllerTests — default vs overridden SalesEmployeeIdFilter branches,
    guest-email fallback mapping, StoreLastVisitedPage on/off.
  • OnlineCustomerControllerAttributeTests (Admin + Store) — subclass/attribute wiring, same shape
    as EmailAccountControllerAttributeTests.

Verification

dotnet build GrandNode.sln — 0 errors. Per-project test runs (parallel full-solution runs are
known-flaky, see repo history):

  • Grand.Web.Admin.Tests: 1436/1436
  • Grand.Web.Store.Tests: 141/141

No live smoke test run this phase — disclosed as an open item, not silently skipped. This
controller is a read-only admin/store online-customer list with no cross-tenant write surface, but
per this initiative's standing "green build proves nothing about routing/wiring" lesson, a live
check is still the more rigorous bar; deferred here to keep this phase's turnaround fast, open for
follow-up before merge if the reviewer wants it.

…nto BaseOnlineCustomerController

Admin's and Store's OnlineCustomerController were near-identical (~80 lines
each) - same List(GET)/List(POST) grid action, same GetOnlineCustomers call
and model mapping. No entity, no per-store/per-vendor scope beyond the
StaffStoreId filter both hosts already applied identically, so no
IAdminDataScope is needed here (same shape as BasePictureController). Vendor
never had its own copy.

The one real difference: Admin restricts the online-customer list to the
current Sales-Manager's own customers via GetOnlineCustomers' salesEmployeeId
parameter; Store has no such concept and always passes null. Parameterized
with a protected virtual SalesEmployeeIdFilter member on the new
BaseOnlineCustomerController (Grand.Web.AdminShared) - the same idiom this
repo's pre-existing BaseLoginController already uses for its own
host-specific GetCurrentArea() value. Admin's thin subclass overrides it to
the current customer's SeId; Store keeps the base's null default.

Both List actions moved verbatim (aside from field -> primary-constructor-
parameter renames and the LINQ vs foreach style difference, which produce
identical output - unified on Store's LINQ form). Base carries
[PermissionAuthorize(PermissionSystemName.Customers)] and
[AutoValidateAntiforgeryToken]; Admin/Store subclasses restate their host's
[AuthorizeAdmin|AuthorizeStore]/[Area]/[AuthorizeMenu] attribute set, matching
the established ARCH-001 pattern.

No prior test coverage existed for either controller. Added:
- BaseOnlineCustomerControllerTests: default vs overridden SalesEmployeeIdFilter
  branches, guest-email fallback mapping, StoreLastVisitedPage on/off.
- OnlineCustomerControllerAttributeTests (Admin + Store): subclass/attribute
  wiring, same shape as EmailAccountControllerAttributeTests.

No behavior change. Verified: dotnet build GrandNode.sln 0 errors; Admin
1436/1436, Store 141/141 (run separately, per known parallel-run flakiness).
No live smoke test run this phase - deferred, disclosed in the PR body (this
controller is a read-only admin/store list with no cross-tenant write
surface).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013y3MqvZq7y1Uc5p4JZad2i
Copilot AI lite review requested due to automatic review settings September 11, 2026 01:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@KrzysztofPajak
KrzysztofPajak merged commit 9ec8003 into develop Sep 11, 2026
6 checks passed
@KrzysztofPajak
KrzysztofPajak deleted the arch001/phase26-onlinecustomer-consolidation branch September 11, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants