Skip to content

Instantly share code, notes, and snippets.

@laser
Last active January 25, 2017 16:51
Show Gist options
  • Save laser/d3ee1e9fab2d9c2f91f6bef39d8cd6de to your computer and use it in GitHub Desktop.
Save laser/d3ee1e9fab2d9c2f91f6bef39d8cd6de to your computer and use it in GitHub Desktop.

Create an SPM Overide: Proposal to Modify Catalog Service HTTP Interface

As part of implementing PAG-1353 we propose an addition to the In Season Catalog Customer Choice HTTP API that will permit the creation of Store Planning Management (SPM) overrides.

Things that the final implementation must permit:

  • Create an SPM override-value for a SKU + location combo
  • Create an SPM override-value for a CC + location combo

(Existing) Create SPM override for CC + Location

Adam and Jim began adding SPM override capabilities to the Catalog Service. The following example demonstrates how a user would create a a single SPM override associated with a customer choice w/id f9a45623-f427-4405-a6c7-efc7f9ffe776:

Request:

HTTP POST
/allocation/in-season/allocated-customer-choices/ti-overrides

{
    "id": "f9a45623-f427-4405-a6c7-efc7f9ffe776",
    "ccOverrides": [
        {
            "locationId": "01d13476-793b-4220-8a57-00425d6b9af6",
            "overrideValue": 24.0,
            "overrideFactor": null,
            "expirationDate": "2017-06-15",
            "effectiveDate": "2017-01-01"
        }
    ]
}

Response:

HTTP 200 OK "TI overrides successfully saved"

Thoughts on this design:

  1. It is not immediately apparent (to me) how this design would be extended to support SKU + location-level overrides
  2. overrideFactor can be applied by clients for purposes of effecting a new overrideValue - as such, it can be removed from the API
  3. effectiveDate can be removed from the API if overrideFactor is removed from the API
  4. It is not clear to me if this design permits clients to remove SPM overrides from locations after they've been created (the PDM states that they expect a planner to nullify an override by setting its expiry date to sometime in the past)
  5. Unsure if this is a goal: It is not immediately apparent to me how this design could be extended to admit New Store overrides

Alternative A: Create SPM Override for (SKU or CC) + Location

This proposal addresses items #1, #2, #3 and #4 from above - but admits only SPM overrides (does not address #5):

Request:

HTTP POST
/allocation/in-season/allocated-customer-choices/ti-overrides

{
    "level_identifier_type": "CUSTOMER_CHOICE_ID",
    "level_identifier_value": "f9a45623-f427-4405-a6c7-efc7f9ffe776",
    "location_id": "01d13476-793b-4220-8a57-00425d6b9af6",
    "expiry_date": "2016-06-15",
    "value": 25.6
}

Response:

HTTP 204 No Content
Request:

HTTP POST
/allocation/in-season/allocated-customer-choices/ti-overrides

{
    "level_identifier_type": "SKU_NBR",
    "level_identifier_value": "1895510210000",
    "location_id": "01d13476-793b-4220-8a57-00425d6b9af6",
    "expiry_date": "2016-06-15",
    "value": 15
}

Response:

HTTP 204 No Content

Notes:

  • "Create SPM" is an idempotent operation; previous override matching location and customer choice id is replaced (note: overrides cannot be deleted, only replaced)
  • SKU and CC-level overrides are visible in the In Season Catalog Customer Choice JSON (implementation: TBD)
  • Overrides do not have identity (they are subordinate to/embedded within some other HTTP "resource")
  • URL handles creation of SPM overrides only (you'll note that there's no way to specify a version or that the override relates to a new-location instead of location)

Alternative B: Create SPM Override for (SKU or CC) + Location

This proposal addresses items #1, #2, #3, #4, and #5 from above:

Request:

HTTP POST
/allocation/in-season/allocated-customer-choices/ti-overrides

{
    "version": "STORE_PLANNING_MANAGEMENT",
    "level_identifier_type": "CUSTOMER_CHOICE_ID",
    "level_identifier_value": "f9a45623-f427-4405-a6c7-efc7f9ffe776",
    "location_identifier_type": "LOCATION_ID",
    "location_identifier_value": "01d13476-793b-4220-8a57-00425d6b9af6",
    "expiry_date": "2016-06-15",
    "value": 25.6
}

Response:

HTTP 204 No Content
Request:

HTTP POST
/allocation/in-season/allocated-customer-choices/ti-overrides

{
    "version": "NEW_STORE",
    "level_identifier_type": "SKU_NBR",
    "level_identifier_value": "1895510210000",
    "location_identifier_type": "NEW_LOCATION_ID",
    "location_identifier_value": "fdbb9d86-34a8-47d2-b498-b4b5dbac82cc",
    "expiry_date": "2016-06-15",
    "value": 25.6
}

Response:

HTTP 204 No Content

Notes:

  • Permits associating the override with either a new-location or a location (NEW_LOCATION_ID or LOCATION_ID)
  • Permits different override "verions": NEW_STORE and STORE_PLANNING_MANAGEMENT
@bentona
Copy link

bentona commented Jan 23, 2017

Some questions, most of which are for my own information :)

  1. Did you mean to omit expiry_date from Alternative B?
  2. Why does Create SPM Override (that's what you mean instead of just "Create SPM", right?) being idempotent preclude a Delete SPM action? BTW, making this idempotent is awesome & makes a lot more sense IMO.
  3. Is it necessary to refer to these override types as "versions"? It's only been touched on in the meetings I've attended, but "Type" (or even "kind" or something else) seems more appropriate.
  4. The current implementation allows for creating overrides in bulk. What's our general approach to bulk-wise endpoints vs. requiring a bunch of requests?
  5. What is the difference between a new "Location" and a "New Location"?
  6. Super pedantic, but can we use level_type and level_identifier instead? I don't think we lose descriptiveness and it's a bit shorter.

@laser
Copy link
Author

laser commented Jan 23, 2017

@bentona

Did you mean to omit expiry_date from Alternative B?

Nope, that's a typo.

Is it necessary to refer to these override types as "versions"?

Nope, not strictly necessary. The Business has been using the term "versioned TI" to mean some grouping of TI-calculation-or-override-application-outputs that might have included a "New Store override" or an "SPM override." We should probably get some consensus on this term before codifying it into source code.

Why does Create SPM Override (that's what you mean instead of just "Create SPM", right?) being idempotent preclude a Delete SPM action? BTW, making this idempotent is awesome & makes a lot more sense IMO.

I tried to use the fancy word "corollary" after using the fancy word "idempotent" and I failed; the fact that the create-override action is idempotent has nothing to do with the lack of an explicit delete-override function. My bad.

The current implementation allows for creating overrides in bulk. What's our general approach to bulk-wise endpoints vs. requiring a bunch of requests?

The current implementation would allow a client to create, in bulk, lots of overrides for the same CC - but different stores - in the same HTTP request. I don't think our designs actually show that as a common access pattern, do they?

Anyhow, Daniel and Peter's guidance to us has been: Make lots of little HTTP requests [between services] instead of fewer, larger HTTP requests. I don't have a strategy for creating overrides in bulk - because I don't think we need to create overrides in bulk.

What is the difference between a new "Location" and a "New Location"?

Good question.

A "location" is the name of a thingy that the Store Service gives us.

A "new-location" is a thingy that the Catalog Service gives us.

A location typically corresponds to a store that Gap will do business at - either already, or in the future.

A new-location is a grab-bag of data imported from various places when a store planner initiates the "New Store process" using the tool that C5 LA built, New Store. It includes a copy of some of the information about a location, some information about customer choices, and some copied TI information.

A new-location must be associated with only one location.

There must exist no two new-location associated with the same location.

There may exist a a location that no new-location is associated with.

Super pedantic, but can we use level_type and level_identifier instead? I don't think we lose descriptiveness and it's a bit shorter.

We could, but I like level_identifier_type better.

@bentona
Copy link

bentona commented Jan 23, 2017

All makes sense, thank you! No further questions.

@shamus
Copy link

shamus commented Jan 25, 2017

Some quick thoughts:

Is a general purpose endpoint appropriate?

  • Do we know if all overrides look the same? Does an inventory push override look like an SPM override?
  • What does it mean to set an override for a CC? Does it make sense to only support setting an override for a sku/location at the API level?
  • If setting an override does make sense at a CC level, is there logic associated with how the factor or the value is applied to each sku? Is that logic consistent between override types (new store, spm, inventory push)
  • If this endpoint is general purpose, does it make sense to drop effective date and factor from the API? Perhaps inventory push can create overrides that start in the future.
  • I see you're attempting to eliminate factor, but I wonder if factor is a value that can be applied to the base TI at any point between the start and end date.
  • Is the logic of applying the factor something that should be pushed to clients of this API? Or is applying the factor something that is best consolidated inside of the TI service.

I like the idea of an idempot endpoint, but...

  • Can there be more than one SPM override for a cc/location? Idempotent collection resources are, you know, fussy.
  • I wonder how this would work if overrides need to be persisted to maintain a history / audit trail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment