Giter VIP home page Giter VIP logo

ordercloud-dotnet-catalyst's People

Contributors

ajsuth avatar amrarick26 avatar crhistianramirez avatar djsteinmetz avatar erincdustin avatar ivanbrygar avatar lauerya avatar maxwmaher avatar oliverheywood451 avatar smitbmx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ordercloud-dotnet-catalyst's Issues

Serialization error in ListAll doesn't surface correctly

var allOrders = await _oc.Orders.ListAllAsync<HSOrder>(OrderDirection.Incoming);

"Error converting value "ShoppingList" to type Items[42].xp.OrderType response could not be deserialized into JSON"

This should be the primary error, not hidden in InnerException.InnerException.

Update to API release 1.0.225

We want to make sure a developer using catalyst can use the most recently created OrderCloud features. This means that we need to

  • Update the dependency on the OrderCloud SDK to the most recent version
  • Update the files that are generated based on the API spec, for example the ListAll() functions. These should include functions to listAll InventoryRecords (for example), a new API resource created in v 1.0.225

https://ordercloud.io/release-notes/v1.0.225

Multiple filter query string incorrectly generated

Issue

When passing multiple filter values with the same name (in the query) an error response is returned.

Examples of when this may be needed are:

  • Filtering on a numeric range (greater than 1, less than 5)
  • Filtering on text containing and not containing (containing "test" but not "user")

This is due to the fact that the value variable in ListArgsBinder.LoadFromQueryString() is actually a Microsoft.Extensions.Primitives.StringValues (ie can be multiple) but is treated like a string.

Steps to reproduce

  1. Create Product in OrderCloud with:
    • a numeric xp property (eg. testnumber with value of 2)
    • a text xp property (eg. author with value of test)
  2. Clone Headstart (or create your own API controller using Catalyst)
  3. Call /me/products?xp.testnumber=>1&xp.testnumber=<5 and observe the error
{
    "Errors": [
        {
            "ErrorCode": "Search.InvalidQuery",
            "Message": "Query is invalid.",
            "Data": {
                "Reason": "Invalid input: \"1,<5\"."
            }
        }
    ]
}
  1. Call /me/products?xp.author=test*&xp.author=!*user and debug the value of filters passed through to oc.Me.ListProductsAsync():
    xp.author=test*,!*user
    which is not the expected value of xp.author=test*&xp.author=!*user

The same issue occurs (for the same reason) if the filters are instead passed through using a JSON body with property filters .
Sample body:

{
  "filters": [
    {
      "propertyName": "xp.testnumber",
      "filterExpression": ">1"
    },
    {
      "propertyName": "xp.testnumber",
      "filterExpression": "<5"
    }
  ]
}

Add Integration Support for Order Returns

OrderCloud now supports Order Returns. There are some things in catalyst or the example middleware needed for this. First, OC has an integration event for calculating the return cost. Some example calculation should be put together in the example project. Second, Catalyst Lib should change so the Tax provider and Payment Processor are updated correctly when the return is finalized. That should happen in a webhook probably. And it probably involves updating the Tax interface with a new method.

Confirm that trying a route which does not exist results in a not found error that matches OC

This issue is about what happens if you try to hit a middleware route which does not exist. What should happen in that scenario is the the status should be 404 and there should be an error body with the message "Not Found" which matches OrderCloud's not found error.

I'm not sure if that's working correctly now or not. Either way, there needs to be an integration test for this scenario.

Authentication Attributes on Azure Functions

This is probably for the examples project. We need examples we can point to of how to use [OrderCloudUserAuth] and [OrderCloudWebhookAuth] attributes to protect http routes in an Azure Functions project.

Feature request: Allow the ability to define sortBy on ListAllAsync

I understand that under the hood ListAllAsync implements the last id method for performant querying. At the end of the output however we'll have all items in memory and should be able to perform a sort on those items. It would be great if as a user I am able to retain the ability to define sort. Additionally consider using the default sortBy when sortBy is not provided to mirror the api functionality.

New Methods on ISimpleCache

  • Add multiGet and multiPut methods-- super important (esp. with Redis) to have that setup,
  • Have a prefix key for each call-- so if the ISimpleCache is used in multiple places, you have a way to avoid key collisions-- so instance.multiGet('products', ['39043','43203','439023'])

Auto-Configure webhooks

Create webhook objects in the developer's OrderCloud marketplace based on the code in the project - meaning what webhook listener routes exist.

This should probably be done after this issue #40

The details of how to implement this are unclear.

Avalara Feedback

Here is the feedback from the Avalara review

  • Make sure OrderCloud's Product.Name field is mapped to Avalara's LineItem.Description field.
  • Make sure OrderCloud's Address.ID field is mapped to Avalara's reportingLocationCode
  • Add this client header (https://developer.avalara.com/avatax/client-headers/). App name and app version are required, the rest are optional. App name is "a0o33000003vpfvAAA".
  • Add a field to the request that maps to Avalara's EntityUseCode in order to enable tax exemptions on a line by line basis

Fix the should_deny_access_if_past_expiry unit-test

The unit-test should_deny_access_if_past_expiry is failing because of the next exception:

System.ArgumentException : IDX12401: Expires: 'System.DateTime' must be after NotBefore: 'System.DateTime'.
   at System.IdentityModel.Tokens.Jwt.JwtPayload.AddFirstPriorityClaims(String issuer, String audience, Nullable`1 notBefore, Nullable`1 expires, Nullable`1 issuedAt)
   at System.IdentityModel.Tokens.Jwt.JwtPayload..ctor(String issuer, String audience, IEnumerable`1 claims, Nullable`1 notBefore, Nullable`1 expires, Nullable`1 issuedAt)
   at System.IdentityModel.Tokens.Jwt.JwtPayload..ctor(String issuer, String audience, IEnumerable`1 claims, Nullable`1 notBefore, Nullable`1 expires)
   at 

Need to fix and keep all the unit tests in the green state.

Fix the 3 failing use cases of the ordercloud_error_should_be_forwarded test.

The 3 Use-Cases of the ordercloud_error_should_be_forwarded test are failing;

  1. [TestCase(false, 401)]
  2. [TestCase(false, 403)]
  3. [TestCase(false, 500)]

Exception:

Flurl.Http.FlurlParsingException : Response could not be deserialized to JSON: GET http://localhost/demo/shop
  ----> Newtonsoft.Json.JsonSerializationException : Error converting value "hello shopper!" to type 'OrderCloud.Catalyst.ErrorList'. Path '', line 1, position 16.
  ----> System.ArgumentException : Could not cast or convert from System.String to OrderCloud.Catalyst.ErrorList.

Ability to hook into exception handler

This is a placeholder for a thought that's still developing.

How can Catalyst support useful logging of API error responses? It should not depend on any one storage option. But it could provide some means to hook into GlobalExceptionHandler and do custom logging without totally replacing that class.

In azure, application insights is pretty good, but is missing stack traces. Crhist is investigating if that can be added.

Simple framework for XP definitions

Intro

This is a potential opinion on how strongly-typed XP should be defined in a C# project. It would include adding code to the catalyst library and creating a guide for solutions. The goals are

  • Make it more likely XP will be consistent within resources and avoid indexing issues
  • Make it easy to take an inventory of all XP used within a project
  • Reduce boilerplate code

The framework

Currently, strongly-typed xp requires code like below for every resource.

// Boilerplate
public class OrderCalculateResponseWithXp : OrderCalculateResponse<OrderCalculateResponseXp, LineItemOverrideWithXp> { }
public class LineItemOverrideWithXp : LineItemOverride<AdHocProductWithXp> { }
public class AdHocProductWithXp : AdHocProduct<AdHocProductXp> { }

// boilerplate if empty, but still required
public class  OrderCalculateResponseXp { }

// Not Boilerplate
public class AdHocProductXp
{
     // put xp here
}
  1. The first suggestion is to put all the boilerplate code above into a library like Catalyst so that the meaningful code - definitions of XP - are clear and unobstructed. Classes like AdHocProductXp would be defined in the library as empty partials, with the solution also defining them as partials and including the xp details.

  2. The second suggestion is to define a convention of putting all the partial <Resource>Xp classes in a single file called Xp.cs. Putting them all in one file makes it easy to be confident there are no other xp definitions hiding in other parts of the project. It also means that source control will produce merge conflicts if two people edit xp simultaneously. This is actually a benefit because it means changes in xp are considered in the context of all existing xp. This reduces the likelihood of conflicting or duplicated definitions. It would look something like this

https://github.com/ordercloud-api/dotnet-middleware/blob/dev/Customer.OrderCloud.Common/Models/Xp.cs

New library code

ModelWithXp.cs

public class OrderCalculateResponseWithXp : OrderCalculateResponse<OrderCalculateResponseXp, LineItemOverrideWithXp> { }
public class LineItemOverrideWithXp : LineItemOverride<AdHocProductWithXp> { }
public class AdHocProductWithXp : AdHocProduct<AdHocProductXp> { }
...

Xp.cs

public partial class OrderCalculateResponseXp { }
public partial class AdHocProductXp { }
...

New client project code

Xp.cs

public partial class AdHocProductXp 
{
    public string MyProperty { get; set; }
}
...

MyServerSideCommand.cs

// same as before, but dev needs to understand the connection between AdHocProductXp and AdHocProductWithXp.
AdHocProductWithXp product = await _oc.AdHocProduct.GetAsync<AdHocProductWithXp>(myID);

Gotchas

  • Multiple OC models will need to be mapped to a single xp schema. A good example are the Product and BuyerProduct models (which serve the same underlying data from two different endpoints). This is strictly necessary. Formalizing all the examples in a framework could reduce coding errors.
public class BuyerProductWithXp : BuyerProduct<ProductXp> { }
public class ProductWithXp: Product<ProductXp> { }
  • A single OC model might reasonably be mapped to multiple different xp schemas. A good example is the singular Address model (which is used for multiple endpoints). This is not strictly necessary, but more open to opinions. The framework would try to create a generally good opinion but would limit options. For example, what if Admin and Supplier addresses should have the same xp schema? Of course, devs can always define their own classes outside the framework.
public class BuyerAddressWithXp : Address<BuyerAddressXp> { }
public class SupplierAddressWithXp : Address<SupplierAddressXp> { }
public class AdminAddressWithXp : Address<AdminAddressXp> { }

There are failed authentication scenarios that are unclear to the user

Does it make sense to provide a more helpful error message in these scenarios? Is it a security concern to expose these errors? (Sometimes verbose auth errors can reveal too much and aid a brute force discovery of secrets.

  1. You may be missing an OrderCloud setting in middleware. Please set a breakpoint here, and start your server. Confirm ApiUrl, MiddlewareClientID, and MiddlewareClientSecret are all defined

  2. Your API client may not be have an admin user as the default context user. Check your API client and confirm the username associated with the API client is an admin user, and that admin user has FullAccess assigned to him. If you went through the seeding process this should be done for you automatically

  3. You are calling the middleware with a token that doesn't match the marketplace for which middleware is set up for. Confirm that the clientID encoded in the token belongs to the same marketplace as the MiddlewareClientID

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.