Git Product home page Git Product logo

unchainedshop / unchained Goto Github PK

View Code? Open in Web Editor NEW
164.0 5.0 19.0 53.43 MB

The multi-language/multi-currency/multi-store, headless Node.js E-Commerce Framework with Native Web3 Integration

Home Page: https://unchained.shop

License: European Union Public License 1.2

Shell 0.01% JavaScript 34.87% Dockerfile 0.02% TypeScript 65.11%
e-commerce graphql marketplace headless docker shopping-cart node-js open-source digital-commerce cart

unchained's Introduction

Unchained Engine

Licensed under the EUPL 1.2

CLA assistant

Code of conduct

See our Contributor Covenant Code of Conduct to view our pledge, standards, responsibilites & more.

Contributing

Please see our Contribution Guidelines.

Quickstart

Prerequisites

Run the example

git clone https://github.com/unchainedshop/unchained.git
npm install
npm run build
cd examples/kitchensink
npm run build
npm start
  1. Navigate to http://localhost:4000/ to view the welcome screen. You can login with: user: [email protected] / password: password

  2. Navigate to http://localhost:4010/graphql to view the GraphQL Playground

Migration to Unchained 1.0

See changelog.md

## Migration to Unchained 2.0

  1. WHATWG Fetch Support required Update Node to 18 or enable Experimental Fetch support on Node.js 16+

  2. GraphQL Version & Express backed-in

npm install graphql@16
npm uninstall apollo-server-express body-parser graphql-scalars graphql-upload isomorphic-unfetch locale simpl-schema
  1. Switch to Battery-Included

Remove custom login-with-single-sign-on and remove all code that involves loading standard plugins and/or gridfs/datatrans webhooks. Furthermore startPlatform will not hook into express and it will not start the graphql server automatically anymore. This has been changed to support other backend frameworks than Express and to support Lambda Mode of Apollo. For those reasons, startPlatform has been changed and now returns an object containing unchainedAPI and the apolloGraphQLServer.

To make it boot with express and the default plugins, you have to do the following:

Import the connect functions and the defaultModules:

import { defaultModules, connectDefaultPluginsToExpress4 } from '@unchainedshop/plugins';
import { connectPlatformToExpress4 } from '@unchainedshop/platform';

Then pass defaultModules to the „modules“ prop of startPlatform:

const engine = await startPlatform({ modules: defaultModules, … });

Now, start the GraphQL server, connect it to Express and load the custom modules:

const engine = await startPlatform({ … });

await engine.apolloGraphQLServer.start(); // Counterintuitively, this has to be done before the platform is connected to express
  
connectPlatformToExpress4(app, engine);
connectDefaultPluginsToExpress4(app, engine);
  1. The userId’s that were used to set some internal db fields about updatedBy / createdBy need to be dropped from various functions. This will most propably affect seed code. Typescript will help you with that.

  2. Examine the API Breaking Changes in the Changelog for API incompatibilities between 1.2 and 2.0.

unchained's People

Contributors

aleksandra-unchained avatar claudiocro avatar fliptation avatar harryadel avatar joelmeiller avatar macrozone avatar mikearaya avatar omahs avatar opencorech avatar pozylon avatar rdttkab avatar schmidsi avatar stefanszasz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

unchained's Issues

[docs] provide a documentation at all 😝

  • Choose documentation systems/tools/helpers
  • Style documentation
  • Document core modules
  • Document common/default plugins
  • Build a guide
  • API Reference
  • Show link to spectrum chat, consider discourse?

Reflect actual field name in query

So instead of:

product(
  productId: ID
  slug: String
): Product

do:

product(
  _id: ID
  slug: String
): Product

or even bettter:

product(
  id: ID
  slug: String
): Product

(Why do we use _id instead of id anyways?)

?

[core] Investigate atmosphere dependencies (discussion encouraged)

Dependencies that need investigation:

  • aldeed's schema packages: collection2, schema-index & simpl-schema. These are still maintained but only on a irregular base. We should find out the cost and potential of getting rid of these packages. -> Currently the schemas are almost only used as input cleaning in update/insert operations to the db and migrating the code together with index creation would only take 1 or 2 days of work for the whole unchained-engine. We stick to the current usage to keep that window open (refactoring out the dependencies) but don't encourage a more intense usage of these packages

  • the dburles:collection-helpers package is very small and does not use any meteor specifics so it might make sense to just copy over the code and mention the licensor in the readme of unchained.
    -> PoC in form of a partial refactoring of the package core-countries in a functional style without collection-helpers

  • the dburles:factory package introduces further dependencies, espoecially one to minimongo for the LocalCollection. It might make sense to replace the package completely with an npm package

Currently considered non-replaceable:

  • percolate:migrations (used by core-payment, core-delivery, core-logger, core-users)
  • ostrio:files (abstracted by core-files)

Salutation in address

Take the situation where we have a different billing oder shipping address it would be helpful to add a salution field to the address to address the Customer correctly at the given address.

addCartProduct should return cart

sorry, i forgot about that one.

If i call addCartProduct i have to to use refetchQueries to see the new cart items, because apolloClient does not know what to do with the new OrderItem that gets returned from addCartProduct

if we would return the new cart, we could have the correct cart on the client in one request.

in general, every mutation that changes the cart/order should return an Order

error in Docker build in minimal

Hi, I am using Meteor 1.8.1 and I am trying to use the provided Dockerfile, but I am getting an error:

$ meteor --version
Meteor 1.8.1
$ cd examples/minimal/
$ docker build .
Sending build context to Docker daemon  350.7kB
Step 1/22 : FROM pozylon/meteor-docker-auto as bundler
 ---> 704f05487600
Step 2/22 : ADD . /source
 ---> Using cache
 ---> 4d9ca08c4ec7
Step 3/22 : WORKDIR /source
 ---> Using cache
 ---> 08793f16362f
Step 4/22 : RUN meteor npm install &&   meteor build --server-only --allow-superuser --directory /bundle
 ---> Running in bc86fd24b17f

> [email protected] install /source/node_modules/bcrypt
> node-pre-gyp install --fallback-to-build

node-pre-gyp WARN Using request for node-pre-gyp https download 
[bcrypt] Success: "/source/node_modules/bcrypt/lib/binding/bcrypt_lib.node" is installed via remote

> [email protected] postinstall /source/node_modules/core-js
> node scripts/postinstall || echo "ignore"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> [email protected] postinstall /source/node_modules/core-js-pure
> node scripts/postinstall || echo "ignore"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> [email protected] postinstall /source/node_modules/protobufjs
> node scripts/postinstall

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

added 901 packages from 590 contributors and audited 14246 packages in 26.929s
found 7 vulnerabilities (1 low, 6 moderate)
  run `npm audit fix` to fix them, or `npm audit` for details

Even with METEOR_ALLOW_SUPERUSER or --allow-superuser, permissions in your app
directory will be incorrect if you ever attempt to perform any Meteor tasks as
a normal user. If you need to fix your permissions, run the following command
from the root of your project:

  sudo chown -Rh <username> .meteor/local

/root/.meteor/packages/meteor-tool/.1.8.1.ani1yi.p0f9s++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/meteor-promise/promise_server.js:218
      throw error;
      ^

TypeError: Cannot read property 'filter' of null
    at filterDirectoryContents (/tools/fs/watch.js:309:19)
    at readDirectory (/tools/fs/watch.js:328:10)
    at Object.readAndWatchDirectory (/tools/fs/watch.js:754:18)
    at /tools/packaging/catalog/catalog-local.js:285:41
    at Array.forEach (<anonymous>)
    at Function._.each._.forEach (/root/.meteor/packages/meteor-tool/.1.8.1.ani1yi.p0f9s++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/underscore/underscore.js:79:11)
    at /tools/packaging/catalog/catalog-local.js:284:9
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at LocalCatalog._computeEffectiveLocalPackages (/tools/packaging/catalog/catalog-local.js:263:18)
    at LocalCatalog.initialize (/tools/packaging/catalog/catalog-local.js:118:10)
    at /tools/project-context.js:708:29
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at /tools/project-context.js:700:20
    at /tools/packaging/catalog/catalog.js:100:5
    at Object.capture (/tools/utils/buildmessage.js:283:5)
    at Object.catalog.runAndRetryWithRefreshIfHelpful (/tools/packaging/catalog/catalog.js:99:31)
    at ProjectContext._initializeCatalog (/tools/project-context.js:699:13)
    at /tools/project-context.js:300:9
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at ProjectContext._completeStagesThrough (/tools/project-context.js:290:18)
    at Profile.run (/tools/project-context.js:282:12)
    at Function.run (/tools/tool-env/profile.js:490:12)
    at ProjectContext.prepareProjectForBuild (/tools/project-context.js:281:13)
    at /tools/cli/commands.js:971:20
    at Object.capture (/tools/utils/buildmessage.js:283:5)
    at Object.main.captureAndExit (/tools/cli/main.js:275:29)
    at buildCommand (/tools/cli/commands.js:968:8)
    at Profile.run (/tools/cli/commands.js:909:25)
    at Function.run (/tools/tool-env/profile.js:490:12)
    at Promise.asyncApply (/tools/cli/commands.js:907:18)
    at /root/.meteor/packages/meteor-tool/.1.8.1.ani1yi.p0f9s++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/meteor-promise/fiber_pool.js:43:40
 => awaited here:
    at Promise.await (/root/.meteor/packages/meteor-tool/.1.8.1.ani1yi.p0f9s++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/meteor-promise/promise_server.js:60:12)
    at /tools/cli/main.js:1530:15
The command '/bin/sh -c meteor npm install &&   meteor build --server-only --allow-superuser --directory /bundle' returned a non-zero code: 1

[core] Add tests

Summary

  • integration tests for the api package

Integration Tests

Queries:

  • me: User
  • users(...): [User!]!
  • user(...): User
  • products(...): [Product!]!
  • product(...): Product
  • productCatalogPrices(...): [ProductPrice!]!
  • translatedProductTexts(...): [ProductTexts!]!
  • translatedProductMediaTexts(...): [ProductMediaTexts!]!
  • translatedProductVariationTexts(...): [ProductVariationTexts!]!
  • languages(...): [Language]!
  • language(...): Language
  • countries(...): [Country!]!
  • country(...): Country
  • currencies(...): [Currency!]!
  • currency(...): Currency
  • deliveryProviders(...): [DeliveryProvider!]!
  • deliveryProvider(...): DeliveryProvider
  • deliveryInterfaces(...): [DeliveryInterface!]!
  • warehousingProviders(...): [WarehousingProvider!]!
  • warehousingProvider(...): WarehousingProvider
  • warehousingInterfaces(...): [WarehousingInterface!]!
  • paymentProviders(...): [PaymentProvider!]!
  • paymentProvider(...): PaymentProvider
  • paymentInterfaces(...): [PaymentInterface!]!
  • orders(...): [Order!]!
  • order(...): Order
  • logs(...): [Log!]!
  • shopInfo: Shop!
  • assortments(...): [Assortment!]!
  • assortment(...): Assortment
  • translatedAssortmentTexts(...): [AssortmentTexts!]!
  • translatedFilterTexts(...): [FilterTexts!]!
  • filters(...): [Filter!]!
  • filter(...): Filter
  • productReviews(...): [ProductReview!]!
  • productReview(...): [ProductReview!]!
  • quotations(...): [Quotation!]!
  • quotation(...): Quotation
  •  search: SearchResult

Mutations:

  • loginWithPassword(...): LoginMethodResponse
  • createUser(...): LoginMethodResponse
  • changePassword(...): SuccessResponse
  • forgotPassword(...): SuccessResponse
  • resetPassword(...): LoginMethodResponse
  • logout(...): SuccessResponse
  • verifyEmail(...): LoginMethodResponse
  • resendVerificationEmail(...): SuccessResponse
  • loginAsGuest: LoginMethodResponse
  • createCart(...): Order!
  • addCartProduct(...): OrderItem!
  • addMultipleCartProducts(...): [OrderItem]!
  • addCartDiscount(...): OrderDiscount!
  • addCartQuotation(...): OrderItem!
  • updateCart(...): Order!
  • emptyCart(...): Order
  • checkoutCart(...): Order!
  • updateCartItem(...): OrderItem!
  • removeCartItem(...): OrderItem!
  • removeCartDiscount(...): OrderDiscount!
  • setOrderDeliveryProvider(...): Order!
  • setOrderPaymentProvider(...): Order!
  • updateOrderDeliveryShipping(...): OrderDeliveryShipping!
  • updateOrderDeliveryPickUp(...): OrderDeliveryPickUp!
  • updateOrderPaymentCard(...): OrderPaymentCard!
  • updateOrderPaymentInvoice(...): OrderPaymentInvoice!
  • updateOrderPaymentGeneric(...): OrderPaymentGeneric!
  • removeOrder(...): Order!
  • confirmOrder(...): Order!
  • payOrder(...): Order!
  • deliverOrder(...): Order!
  • updateUserAvatar(...): User
  • updateEmail(...): User
  • updateUserTags(...): User
  • updateUserProfile(...): User
  • enrollUser(...): User
  • setPassword(...): User
  • setRoles(...): User
  • createProduct(...): Product!
  • publishProduct(...): Product!
  • unpublishProduct(...): Product!
  • removeProduct(...): Product!
  • updateProduct(...): Product
  • updateProductCommerce(...): Product
  • updateProductSupply(...): Product
  • updateProductWarehousing(...): Product
  • updateProductTexts(...): [ProductTexts!]!
  • addProductMedia(...): ProductMedia!
  • removeProductMedia(...): ProductMedia!
  • reorderProductMedia(...): [ProductMedia!]!
  • updateProductMediaTexts(...): [ProductMediaTexts!]!
  • removeProductVariation(...): ProductVariation!
  • removeProductVariationOption(...): ProductVariation!
  • updateProductVariationTexts(...): [ProductVariationTexts!]!
  • createProductVariation(...): ProductVariation!
  • createProductBundleItem(...): Product!
  • removeBundleItem(...): Product!
  • createProductVariationOption(...): ProductVariation!
  • addProductAssignment(...): Product!
  • removeProductAssignment(...): Product!
  • createLanguage(...): Language!
  • updateLanguage(...): Language!
  • setBaseLanguage(...): Language!
  • removeLanguage(...): Language!
  • createCountry(...): Country!
  • updateCountry(...): Country!
  • setBaseCountry(...): Country!
  • removeCountry(...): Country!
  • createCurrency(...): Currency!
  • updateCurrency(...): Currency!
  • removeCurrency(...): Currency!
  • createPaymentProvider(...): PaymentProvider!
  • updatePaymentProvider(...): PaymentProvider!
  • removePaymentProvider(...): PaymentProvider!
  • createDeliveryProvider(...): DeliveryProvider!
  • updateDeliveryProvider(...): DeliveryProvider!
  • removeDeliveryProvider(...): DeliveryProvider!
  • createWarehousingProvider(...): WarehousingProvider!
  • updateWarehousingProvider(...): WarehousingProvider!
  • removeWarehousingProvider(...): WarehousingProvider!
  • createAssortment(...): Assortment!
  • updateAssortment(...): Assortment!
  • setBaseAssortment(...): Assortment!
  • removeAssortment(...): Assortment!
  • updateAssortmentTexts(...): [AssortmentTexts!]!
  • addAssortmentProduct(...): AssortmentProduct!
  • removeAssortmentProduct(...): AssortmentProduct!
  • reorderAssortmentProducts(...): [AssortmentProduct!]!
  • addAssortmentLink(...): AssortmentLink!
  • removeAssortmentLink(...): AssortmentLink!
  • reorderAssortmentLinks(...): [AssortmentLink!]!
  • addAssortmentFilter(...): AssortmentFilter!
  • removeAssortmentFilter(...): AssortmentFilter!
  • reorderAssortmentFilters(...): [AssortmentFilter!]!
  • createFilter(...): Filter!
  • updateFilter(...): Filter!
  • removeFilter(...): Filter!
  • removeFilterOption(...): Filter!
  • updateFilterTexts(...): [FilterTexts!]!
  • createFilterOption(...): Filter!
  • createProductReview(...): ProductReview!
  • updateProductReview(...): ProductReview!
  • removeProductReview(...): ProductReview!
  • addProductReviewVote(...): ProductReviewVote!
  • requestQuotation(...): Quotation!
  • verifyQuotation(...): Quotation!
  • rejectQuotation(...): Quotation!
  • makeQuotationProposal(...): Quotation!

change address on order to billingAddress

an order has currently a property address, but its actually the billingAddress. also it is billingAddress in the database.

i would suggest to deprecate the address-field on the order type and replace it with billingAddress, which would remove much confusion

its possible to add items to cart with negative quantity

this will create order_positions with negative quantity. The me.cart resolver however does not show this product.

the mutation should probably throw an error if the quantity goes below 0.

This happens if you use addCartProduct with negative quantity

add resolver minPrice to Products

this returns the minimal price for a product

  • for simple products its just the catalog price
  • for bundle products its probably the sum of the bundlet items
  • for configurable products its the price of the assigned products which is the lowest

this helps to do something like: "Pricing starting at ..."

Create user is not persiting the profile

Take this mutation:

mutation CreateUser($profile: ShopUserProfileInput) {
  createUser(email: "[email protected]", plainPassword: "asdf", profile: $profile) {
    id
    token
    tokenExpires
  }
}

with this variables:

"profile":{
    "phoneMobile":"786981729",
    "address": {
      "lastName":"Romano",
      "firstName":"Claudio",
      "company":"compa",
      "addressLine":"Steinhaldestrasse 52",
      "postalCode":"8002",
      "city":"Zürich",
      "countryCode":"Schweiz"
    }
  }
}

If you query:

{
  me {
    _id
    profile {
      gender
      birthday
      address {
        firstName
        lastName
        company
        addressLine
        postalCode
        countryCode
        regionCode
        city
      }
    }
  }
}

The profile is empty

Refactor Discounting system

  • Replace Flag with Methods (isTriggerSystem)
  • Solve the context puzzle in discounts as a future direction for all modules
  • Replace static isDeletionAllowed, ... with non-static
  • Rethink / review naming and code abstraction levels for: DiscountDirector.discountConfigurationForCalculation, discountForPricingAdapterKey, resolveDiscountKeyFromStaticCode....

error when deploy to meteor galaxy

hi, i got these error when make an deploy to my galaxy,

C:\Users\Administrator\Desktop\unchained\examples\minimal>meteor deploy my-meteor-app.meteorapp.com --settings settings.json
unchained:core-settings: updating npm dependencies -- lodash.get...
unchained:core-files: updating npm dependencies -- lodash.merge...
=> Errors while initializing project:

While building package unchained:core-settings:
error: couldn't install npm packages from npm-shrinkwrap: Command failed: C:\Windows\system32\cmd.exe /c
C:\Users\Administrator\AppData\Local.meteor\packages\meteor-tool\1.8.1\mt-os.windows.x86_64\dev_bundle\bin\npm.cmd
install

While building package unchained:core-files:
error: couldn't install npm packages from npm-shrinkwrap: Command failed: C:\Windows\system32\cmd.exe /c
C:\Users\Administrator\AppData\Local.meteor\packages\meteor-tool\1.8.1\mt-os.windows.x86_64\dev_bundle\bin\npm.cmd
install

C:\Users\Administrator\Desktop\unchained\examples\minimal>meteor build --architecture os.linux.x86_64 --directory .build
unchained:core-settings: updating npm dependencies -- lodash.get...
unchained:core-files: updating npm dependencies -- lodash.merge...
=> Errors while initializing project:

While building package unchained:core-settings:
error: couldn't install npm packages from npm-shrinkwrap: Command failed: C:\Windows\system32\cmd.exe /c
C:\Users\Administrator\AppData\Local.meteor\packages\meteor-tool\1.8.1\mt-os.windows.x86_64\dev_bundle\bin\npm.cmd
install

While building package unchained:core-files:
error: couldn't install npm packages from npm-shrinkwrap: Command failed: C:\Windows\system32\cmd.exe /c
C:\Users\Administrator\AppData\Local.meteor\packages\meteor-tool\1.8.1\mt-os.windows.x86_64\dev_bundle\bin\npm.cmd
install

Please help?

updateCart

currently, checkout and addCartProduct works without providing the orderId of the cart.

on the other hand, if you want to update the order with e.g. the billig address, you have to know the orderID.

introduce a updateCart mutation to fix that

Introduce Soft deletion across core collections

See #48 for initial discussion

At the moment, only some collections support soft deletion, I think we should enforce this basically to almost all collections which have to live long and are referenced in orders, like:

Countries
Languages
Currencies
Assortments
Users

And at the same time, introduce a general inconsistency cleaning job, which tries to wipe unreferenced or deleted items of all kinds from the database:

  • Old Products that are not referenced in any important record (treshhold controlled)
  • Old Assortments that are not referenced in any important record (treshhold controlled)
  • ProductVariations, ProductMedia, Media
  • AssortmentTexts, AssortmentProducts, AssortmentLinks
  • Bookmarks, Filters, Credentials

Users (this will be hard but important):
Will have to move the referenced items to a "trash user" or completely anonymize the user for archival purposes? This also depends on laws in europe (right to forget)

allow to update cart item confiugration

currently we have updateCartItemQuantity, but other property can't be updated.

introduce

updateCartItem(
itemId: ID!
quantity: Int = 1
configuration: ...

): OrderItem!

Where should i host unchained?

hello,

I would like to try unchained for family shop, but still have no idea where to host, please guide me.

Can i deploy unchained on netlify.com?
Or meteojs.com hosting or digitalocean?

[api] Inconsistent Error Types

We started introducing error codes to help UI's with localization of error messages, but stopped at a certain point, to see the problem, have a look at these two files:

https://github.com/unchainedshop/unchained/blob/master/packages/api/resolvers/mutations/removeOrder.js

https://github.com/unchainedshop/unchained/blob/master/packages/api/resolvers/mutations/removeCountry.js

As you can see, when removing orders that don't exist, clean error codes get reported. The same is not true when you remove countries.

send more errors to the client

e.g. when doing

mutation {
  checkout {
    _id
    confirmed
  }
}

you get an error, if you did not update the deliveryProvider and paymentProvider of the cart. The error is logged on the server ("No payment provider selected") but the client has no further information.

we should send the error "No payment provider selected" to the client, no matter if in debug or prod

query packages with multiple tags should do an AND, not an OR

query PackageProdcuts($tags: [String!], $limit: Int = 100000) {
  products(tags: ["foo", "bar"]) {

  }
}

this should query products having both tags, not products that have either tag.

reasoning: you can mimick the current behaviour with multiple queries, wheras it is impossible to query the products containing both tags at once

Enhance Mutation.updateCart to set payment- and deliveryProvider

It would probably make sense to have to possibility to set the payment- and deliveryProvider through Mutation.updateCart in order to only need one mutation to set the cart ready to checkout.

From:

Mutation.updateCart(
  orderId: ID
  billingAddress: AddressInput
  contact: ContactInput
  meta: JSON
): Order!

To:

Mutation.updateCart(
  orderId: ID
  billingAddress: AddressInput
  contact: ContactInput
  meta: JSON
  paymentProviderId: ID
  deliveryProviderId: ID
): Order!

refactor payments

what about the following packages:

  • unchained:payment-invoice
  • unchained:payment-stripe
  • unchained:payment-paypal
  • ...

instead of one unchained:core-payment?

the idea is, that you could just add the packages you need, without needing to import the plugins. This would fit more how meteor packages work.

the single payment-* packages would then require unchained:payment-core where base classes, etc. are defined.

add lastContact to user

a user has lastBillingAddress and lastDeliveryAddress, but not lastContact.

I will send in a pull request that saves lastContact and exposes it as resolver.

also I noticed that the naming is inconsistent.

Contact as in lastContact has telNumber and emailAddress, while in other places, phoneMobile is used for phone

Maybe the whole contact thing has to be removed and email and phone should be added to deliveryAddress (or billingAddress).

add typescript

Issues like #31 show that some type checking is necessary for a project like that.

maybe we can start with porting some packages like order and delivery to typescript

refactor Product-variants

While the default apis uf unchained are very self-explanatory, handling product variants is not and is entirely technically driven instead of being business-driven.

The issues with the current implementation:

  • its not obvious what to add to a cart. It seems that adding a ConfigurableProduct to the cart is not intended, yet possible and the api totally suggest that you should be able to do that. After all, its just a Product see also #19
  • if you have added a varant to the cart, you don't know its other variants if you add the linked variant's product to the cart
  • similar problem for bundles

I would view that entirly from the api perspective, not how it is implemented internaly. So from that perspective i would suggest:

  • Everything that is returned by queries product() or products() can be added to the cart, checked out and ordered
  • a product that has variants has property variants or similar, where you can lookup the matrix of variants. Every leave of this matrix has a ProductVariant with some variantId.
  • a ProductVariant can internally be the same as a Product, but you can't add it to a cart directly. You add it by specifiying the productId and some kind of variantId. Maybe you can derive the variantId from the options: "color:blue|size:m"
  • a ProductVariant can't itself have variants

and maybe (more a braindump)

  • a ProductVariant has some baseProduct field that resolves to the base configurable product
  • some fields of a Product resolve on a variant, maybe they have an optional argument variant (sku, catalogPrice, texts maybe, etc.)
  • if no variantId is given in that fields (or in addToCart), but the product has variants, an error is thrown or a default variant is used, which might use the properties on the base product itself

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.