Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Channels #12

Closed
michaelbromley opened this issue Aug 29, 2018 · 4 comments
Closed

Channels #12

michaelbromley opened this issue Aug 29, 2018 · 4 comments
Labels
design 📐 This issue deals with high-level design of a feature

Comments

@michaelbromley
Copy link
Member

michaelbromley commented Aug 29, 2018

Channels represent distinct sales outlets. Many web shops will just have a single, default channel, which is the website. However, there are cases when it would be desirable to be able to define distinct sales channels, such as:

  • Websites for a foreign markets
  • Alternative websites marketed to different audiences selling subset of all products in catalog
  • Mobile app with different (but overlapping) product range

Thus the following aspects could vary from one channel to the next:

  • Product availability
  • Taxes
  • Payment methods
  • Shipping methods
  • Default language
  • Default currency code
  • User role

Prior Art

Design

Adding Channels would quite significantly increase the complexity of the models. Here is a rough idea for an implementation:

  • A Channel entity is created, which has (among other properties) an id and name. By default, there is a "default" channel which must exist. Any number of additional channels may be created.
  • A Product has an available property relative to each Channel. This could be as simple as a one-to-many relationship from Product -> Channels.
  • A ProductVariant's price would now be associated with a particular Channel.
  • Likewise, TaxAdjustment and ShippingAdjustment entities (once implemented) would need to relate to a particular Channel.
  • A User's role would be relative to a given Channel. Thus you can have Administrators who can view and administrate only selected Channels. This will be tricky to get right.
  • The current Channel should somehow be implicit, so that we don't need to go and add a channelId argument to every query / mutation. Perhaps the active channel id can be stored in the JWT info so that it can be figured out once and then just persists for the session.
@michaelbromley michaelbromley added the design 📐 This issue deals with high-level design of a feature label Aug 29, 2018
@michaelbromley
Copy link
Member Author

Some real-life use-cases for Channels:

I am a merchant that is on M2 commerce cloud edition. We have 5 websites, one with 2 separate store views. Moving to Magento from Volusion, the major draw was multi site. We have sites that sell the same product just to different audiences and marketed different. And one site is 100% a different product line. I can not imagine trying to manage those as separate stores. source

I will have store A, B and
Each will have it's own url i.e www.a.com, www.b.com and www.c.
Each of the stores will share some products and some products will be exclusive to each particular
Each store will have it's own identity but will share physical addresses and general information. source

@michaelbromley
Copy link
Member Author

michaelbromley commented Aug 30, 2018

Determining the active Channel

Consider the following:

  1. There are 2 Channels, "default" and "special".
  2. There are 100 products in total. All are assigned to "default" but only 50 are assigned to "special".
  3. A client makes a products() query. How do we decide which set of products to return?

In general: How do we determine the active channel for a request?

Possible solutions:

  1. Send a channelId (or token) argument with all API calls as an argument or a header, for example.
    • ✅ Relatively simple, familiar pattern (like passing an API key to a SaaS service)
    • 👎 It would be trivial for an end-user to change the channelId manually with possibly unwanted consequences.
  2. Generate distinct API endpoints for each Channel

Implementation ideas

  1. A Channel has a generated token property (a random hash)
  2. When a client makes a call, it must set a header containing this token. This sets the context of the request to be the specified Channel.
  3. At the Resolver layer, this token is resolved into a channelId and forwarded to the Service layer.
  4. The DB call is amended with a filter by channelId. E.g. "select products where product is assigned to channel with id channelId"
  5. In the case of Administrators, the role(s) of that User will be associated with one or more Channels (in the case of a "Channel Administrator" - someone in charge of one or more Channels only). The AdminUI should allow clear switching between Channels as a top-level UI control.
  6. For "Super Administrators" (or whatever we call them), they will be able to see all products since they always have access to the default Channel

determining-active-channel

@michaelbromley
Copy link
Member Author

Concept for Channels in the Admin UI

channels admin ui

superadmin channels admin ui

michaelbromley added a commit that referenced this issue Sep 6, 2018
This merge includes the basic infrastructure for Channels (see #12).
There is further work to be done to implement Channels fully, but this
can be done in the course of regular development on master, hence this
branch is now being merged.
michaelbromley added a commit that referenced this issue Nov 5, 2019
This commit adds a new ChannelSwitcherComponent which displays a channel switcher when the current Administrator has permissions on more than one Channel. Switching channel updates local client state in the Apollo cache, and also triggers a re-fetch of any active queries. Relates to #12
michaelbromley added a commit that referenced this issue Nov 12, 2019
michaelbromley added a commit that referenced this issue Nov 13, 2019
@michaelbromley
Copy link
Member Author

A lot of work has been done on Channels over the past week. Here's a current status report:

  • Channels can be created and deleted
  • Roles can be assigned to one or more Channels, meaning Administrators can be created which are limited to specified channels.
  • Products can be added to and removed from Channels. Doing so will update the search index for the DefaultSearchPlugin and ElasticsearchPlugin.

Outstanding tasks:

  • Adding/removing Promotions & ShippingMethods to Channels, plus the additional logic needed to ensure that only valid ones are used for the active Channel when calculating Order totals in the Shop API.
  • Orders should be channel-aware, which they are currently not.
  • A more user-friendly way for bulk-managing product channels assignment/removal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design 📐 This issue deals with high-level design of a feature
Projects
None yet
Development

No branches or pull requests

1 participant