From 9b4cc66c53d7e7b8e08be26864a540e833dfac5e Mon Sep 17 00:00:00 2001 From: p Date: Sat, 21 Feb 2026 11:43:02 +0200 Subject: [PATCH] feat: old spec --- .../model/catalog/article/article-apis.smithy | 78 ++++++++++ .../model/catalog/article/article-io.smithy | 60 ++++++++ .../catalog/article/article-types.smithy | 42 ++++++ .../model/catalog/product/product-apis.smithy | 81 ++++++++++ .../model/catalog/product/product-io.smithy | 52 +++++++ .../catalog/product/product-types.smithy | 41 +++++ .../model/catalog/stand/stand-apis.smithy | 87 +++++++++++ .../model/catalog/stand/stand-io.smithy | 85 +++++++++++ .../model/catalog/stand/stand-types.smithy | 29 ++++ spec/smithy/model/common.smithy | 140 ++++++++++++++++++ spec/smithy/model/errors.smithy | 38 +++++ spec/smithy/model/main.smithy | 27 ++++ .../model/marketing/offer/offer-apis.smithy | 95 ++++++++++++ .../model/marketing/offer/offer-io.smithy | 52 +++++++ .../model/marketing/offer/offer-types.smithy | 61 ++++++++ .../model/outlet/brand/brand-apis.smithy | 76 ++++++++++ .../smithy/model/outlet/brand/brand-io.smithy | 42 ++++++ .../model/outlet/brand/brand-types.smithy | 32 ++++ .../model/outlet/store/store-apis.smithy | 104 +++++++++++++ .../smithy/model/outlet/store/store-io.smithy | 79 ++++++++++ .../model/outlet/store/store-types.smithy | 107 +++++++++++++ spec/smithy/model/smithy-build.json | 6 + spec/smithy/model/tsp/tsp-apis.smithy | 19 +++ spec/smithy/model/tsp/tsp-io.smithy | 15 ++ spec/smithy/model/tsp/tsp-types.smithy | 16 ++ 25 files changed, 1464 insertions(+) create mode 100644 spec/smithy/model/catalog/article/article-apis.smithy create mode 100644 spec/smithy/model/catalog/article/article-io.smithy create mode 100644 spec/smithy/model/catalog/article/article-types.smithy create mode 100644 spec/smithy/model/catalog/product/product-apis.smithy create mode 100644 spec/smithy/model/catalog/product/product-io.smithy create mode 100644 spec/smithy/model/catalog/product/product-types.smithy create mode 100644 spec/smithy/model/catalog/stand/stand-apis.smithy create mode 100644 spec/smithy/model/catalog/stand/stand-io.smithy create mode 100644 spec/smithy/model/catalog/stand/stand-types.smithy create mode 100644 spec/smithy/model/common.smithy create mode 100644 spec/smithy/model/errors.smithy create mode 100644 spec/smithy/model/main.smithy create mode 100644 spec/smithy/model/marketing/offer/offer-apis.smithy create mode 100644 spec/smithy/model/marketing/offer/offer-io.smithy create mode 100644 spec/smithy/model/marketing/offer/offer-types.smithy create mode 100644 spec/smithy/model/outlet/brand/brand-apis.smithy create mode 100644 spec/smithy/model/outlet/brand/brand-io.smithy create mode 100644 spec/smithy/model/outlet/brand/brand-types.smithy create mode 100644 spec/smithy/model/outlet/store/store-apis.smithy create mode 100644 spec/smithy/model/outlet/store/store-io.smithy create mode 100644 spec/smithy/model/outlet/store/store-types.smithy create mode 100644 spec/smithy/model/smithy-build.json create mode 100644 spec/smithy/model/tsp/tsp-apis.smithy create mode 100644 spec/smithy/model/tsp/tsp-io.smithy create mode 100644 spec/smithy/model/tsp/tsp-types.smithy diff --git a/spec/smithy/model/catalog/article/article-apis.smithy b/spec/smithy/model/catalog/article/article-apis.smithy new file mode 100644 index 0000000..f168def --- /dev/null +++ b/spec/smithy/model/catalog/article/article-apis.smithy @@ -0,0 +1,78 @@ +$version: "2" + +namespace shopping.inandout.catalog.article + +use shopping.inandout#DeleteRestrictedError +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#PositiveDouble +use shopping.inandout#ResourceAlreadyExistsError +use shopping.inandout#ResourceNotFoundError +use shopping.inandout#UUID +use shopping.inandout.catalog.product#ProductSummary + +resource Article { + identifiers: { + articleId: UUID + } + properties: { + productSummary: ProductSummary + brandId: UUID + price: PositiveDouble + currency: String + createdAt: Timestamp + updatedAt: Timestamp + } + create: CreateArticle + read: GetArticle + update: UpdateArticle + delete: DeleteArticle +} + +@http(method: "POST", uri: "/brands/{brandId}/articles") +operation CreateArticle { + input: CreateArticleInput + output: CreateArticleOutput + errors: [ + InvalidInputError + ResourceAlreadyExistsError + InternalServerError + ] +} + +@readonly +@http(method: "GET", uri: "/brands/{brandId}/articles/{articleId}") +operation GetArticle { + input: GetArticleInput + output: GetArticleOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@http(method: "PATCH", uri: "/brands/{brandId}/articles/{articleId}") +operation UpdateArticle { + input: UpdateArticleInput + output: UpdateArticleOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@idempotent +@http(method: "DELETE", uri: "/brands/{brandId}/articles/{articleId}") +@documentation("Restricted cascading operation, references for stands should NOT exist") +operation DeleteArticle { + input: DeleteArticleInput + output: DeleteArticleOutput + errors: [ + InvalidInputError + ResourceNotFoundError + DeleteRestrictedError + InternalServerError + ] +} diff --git a/spec/smithy/model/catalog/article/article-io.smithy b/spec/smithy/model/catalog/article/article-io.smithy new file mode 100644 index 0000000..f4d6095 --- /dev/null +++ b/spec/smithy/model/catalog/article/article-io.smithy @@ -0,0 +1,60 @@ +$version: "2" + +namespace shopping.inandout.catalog.article + +use shopping.inandout#BrandIdMixin +use shopping.inandout#PositiveDouble +use shopping.inandout#UUID +use shopping.inandout.catalog.product#CreateProductInput +use shopping.inandout.catalog.product#Product + +@references([ + { + resource: Product + } +]) +structure CreateArticleInput with [BrandIdMixin, ArticleInputMixin] { + @required + price: PositiveDouble + + // Clients must choose between providing a product id/details. + // Not none, not both, one field must be filled. + @notProperty + @documentation("Existing product referenced in a new article") + productId: UUID + + @notProperty + @documentation("Creates a new product") + createProductInput: CreateProductInput +} + +structure CreateArticleOutput { + @required + articleId: UUID +} + +structure GetArticleInput with [BrandIdMixin] { + @required + @httpLabel + articleId: UUID +} + +structure GetArticleOutput with [ArticleOutputMixin] {} + +structure UpdateArticleInput with [BrandIdMixin, ArticleInputMixin] { + @required + @httpLabel + articleId: UUID + + price: PositiveDouble +} + +structure UpdateArticleOutput with [ArticleOutputMixin] {} + +structure DeleteArticleInput with [BrandIdMixin] { + @required + @httpLabel + articleId: UUID +} + +structure DeleteArticleOutput {} diff --git a/spec/smithy/model/catalog/article/article-types.smithy b/spec/smithy/model/catalog/article/article-types.smithy new file mode 100644 index 0000000..b69995c --- /dev/null +++ b/spec/smithy/model/catalog/article/article-types.smithy @@ -0,0 +1,42 @@ +$version: "2" + +namespace shopping.inandout.catalog.article + +use shopping.inandout#AuditMetadata +use shopping.inandout#PositiveDouble +use shopping.inandout#UUID +use shopping.inandout.catalog.product#ProductSummary +use shopping.inandout.outlet.brand#Brand + +@mixin +structure ArticleMixin { + currency: String +} + +@mixin +structure ArticleInputMixin with [ArticleMixin] {} + +@mixin +@references([ + { + resource: Brand + } + { + resource: Article + } +]) +structure ArticleOutputMixin with [AuditMetadata, ArticleMixin] { + @required + brandId: UUID + + @required + articleId: UUID + + @required + productSummary: ProductSummary + + @required + price: PositiveDouble +} + +structure ArticleSummary with [ArticleOutputMixin] {} diff --git a/spec/smithy/model/catalog/product/product-apis.smithy b/spec/smithy/model/catalog/product/product-apis.smithy new file mode 100644 index 0000000..610488a --- /dev/null +++ b/spec/smithy/model/catalog/product/product-apis.smithy @@ -0,0 +1,81 @@ +$version: "2" + +namespace shopping.inandout.catalog.product + +use shopping.inandout#DeleteRestrictedError +use shopping.inandout#Description +use shopping.inandout#ImageUrl +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#ResourceAlreadyExistsError +use shopping.inandout#ResourceName +use shopping.inandout#ResourceNotFoundError +use shopping.inandout#UUID + +resource Product { + identifiers: { + productId: UUID + } + properties: { + name: ResourceName + subcategory: ResourceName + category: ResourceName + vendor: ResourceName + imageUrl: ImageUrl + description: Description + createdAt: Timestamp + updatedAt: Timestamp + } + create: CreateProduct + read: GetProduct + update: UpdateProduct + delete: DeleteProduct +} + +@http(method: "POST", uri: "/products") +operation CreateProduct { + input: CreateProductInput + output: CreateProductOutput + errors: [ + InvalidInputError + ResourceAlreadyExistsError + InternalServerError + ] +} + +@readonly +@http(method: "GET", uri: "/products/{productId}") +operation GetProduct { + input: GetProductInput + output: GetProductOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@http(method: "PATCH", uri: "/products/{productId}") +operation UpdateProduct { + input: UpdateProductInput + output: UpdateProductOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@idempotent +@http(method: "DELETE", uri: "/products/{productId}") +@documentation("Restricted cascading operation, references for articles should NOT exist") +operation DeleteProduct { + input: DeleteProductInput + output: DeleteProductOutput + errors: [ + InvalidInputError + ResourceNotFoundError + DeleteRestrictedError + InternalServerError + ] +} diff --git a/spec/smithy/model/catalog/product/product-io.smithy b/spec/smithy/model/catalog/product/product-io.smithy new file mode 100644 index 0000000..81530fb --- /dev/null +++ b/spec/smithy/model/catalog/product/product-io.smithy @@ -0,0 +1,52 @@ +$version: "2" + +namespace shopping.inandout.catalog.product + +use shopping.inandout#ResourceName +use shopping.inandout#UUID + +structure CreateProductInput with [ProductInputMixin] { + @required + name: ResourceName + + @required + subcategory: ResourceName + + @required + category: ResourceName +} + +structure CreateProductOutput { + @required + productId: UUID +} + +structure GetProductInput { + @required + @httpLabel + productId: UUID +} + +structure GetProductOutput with [ProductOutputMixin] {} + +structure UpdateProductInput with [ProductInputMixin] { + @required + @httpLabel + productId: UUID + + name: ResourceName + + subcategory: ResourceName + + category: ResourceName +} + +structure UpdateProductOutput with [ProductOutputMixin] {} + +structure DeleteProductInput { + @required + @httpLabel + productId: UUID +} + +structure DeleteProductOutput {} diff --git a/spec/smithy/model/catalog/product/product-types.smithy b/spec/smithy/model/catalog/product/product-types.smithy new file mode 100644 index 0000000..ba09ca1 --- /dev/null +++ b/spec/smithy/model/catalog/product/product-types.smithy @@ -0,0 +1,41 @@ +$version: "2" + +namespace shopping.inandout.catalog.product + +use shopping.inandout#AuditMetadata +use shopping.inandout#Description +use shopping.inandout#ImageUrl +use shopping.inandout#ResourceName +use shopping.inandout#UUID + +@mixin +structure ProductMixin { + vendor: ResourceName + imageUrl: ImageUrl + description: Description +} + +@mixin +structure ProductInputMixin with [ProductMixin] {} + +@mixin +@references([ + { + resource: Product + } +]) +structure ProductOutputMixin with [AuditMetadata, ProductMixin] { + @required + productId: UUID + + @required + name: ResourceName + + @required + subcategory: ResourceName + + @required + category: ResourceName +} + +structure ProductSummary with [ProductOutputMixin] {} diff --git a/spec/smithy/model/catalog/stand/stand-apis.smithy b/spec/smithy/model/catalog/stand/stand-apis.smithy new file mode 100644 index 0000000..c6b85e3 --- /dev/null +++ b/spec/smithy/model/catalog/stand/stand-apis.smithy @@ -0,0 +1,87 @@ +$version: "2" + +namespace shopping.inandout.catalog.stand + +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#PositiveDouble +use shopping.inandout#ResourceAlreadyExistsError +use shopping.inandout#ResourceNotFoundError +use shopping.inandout#UUID +use shopping.inandout.catalog.article#ArticleSummary + +resource Stand { + identifiers: { + standId: UUID + } + properties: { + edgeId: UUID + sourceNodeDistance: PositiveDouble + articleSummary: ArticleSummary + createdAt: Timestamp + updatedAt: Timestamp + } + create: CreateStand + read: GetStand + list: ListStands + update: UpdateStand + delete: DeleteStand +} + +@http(method: "POST", uri: "/stores/{storeId}/stands") +operation CreateStand { + input: CreateStandInput + output: CreateStandOutput + errors: [ + InvalidInputError + ResourceAlreadyExistsError + InternalServerError + ] +} + +@readonly +@http(method: "GET", uri: "/stores/{storeId}/stands/{standId}") +operation GetStand { + input: GetStandInput + output: GetStandOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@readonly +@paginated +@http(method: "GET", uri: "/stores/{storeId}/stands") +operation ListStands { + input: ListStandsInput + output: ListStandsOutput + errors: [ + InvalidInputError + InternalServerError + ] +} + +@http(method: "PATCH", uri: "/stores/{storeId}/stands/{standId}") +operation UpdateStand { + input: UpdateStandInput + output: UpdateStandOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@idempotent +@http(method: "DELETE", uri: "/stores/{storeId}/stands/{standId}") +operation DeleteStand { + input: DeleteStandInput + output: DeleteStandOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} diff --git a/spec/smithy/model/catalog/stand/stand-io.smithy b/spec/smithy/model/catalog/stand/stand-io.smithy new file mode 100644 index 0000000..72de21b --- /dev/null +++ b/spec/smithy/model/catalog/stand/stand-io.smithy @@ -0,0 +1,85 @@ +$version: "2" + +namespace shopping.inandout.catalog.stand + +use shopping.inandout#InputPagination +use shopping.inandout#OutputPagination +use shopping.inandout#PositiveDouble +use shopping.inandout#StoreIdMixin +use shopping.inandout#UUID +use shopping.inandout.catalog.article#Article +use shopping.inandout.catalog.article#CreateArticleInput + +@references([ + { + resource: Article + } +]) +structure CreateStandInput with [StoreIdMixin] { + @required + edgeId: UUID + + @required + sourceNodeDistance: PositiveDouble + + // Clients must choose between providing an article id/details. + // Not none, not both, one field must be filled. + @notProperty + @documentation("Existing article referenced in a new stand") + articleId: UUID + + @notProperty + @documentation("Creates a new article") + createArticleInput: CreateArticleInput +} + +structure CreateStandOutput { + @required + standId: UUID +} + +structure GetStandInput with [StoreIdMixin] { + @required + @httpLabel + standId: UUID +} + +structure GetStandOutput with [StandOutputMixin] {} + +@references([ + { + resource: Article + } +]) +structure ListStandsInput with [StoreIdMixin, InputPagination] { + @httpQuery("edgeId") + edgeId: UUID + + @httpQuery("articleId") + articleId: UUID +} + +structure ListStandsOutput with [OutputPagination] { + @required + tokens: StandSummaryList +} + +structure UpdateStandInput with [StoreIdMixin] { + @required + @httpLabel + standId: UUID + + edgeId: UUID + + sourceNodeDistance: PositiveDouble +} + +structure UpdateStandOutput with [StandOutputMixin] {} + +structure DeleteStandInput with [StoreIdMixin] { + @required + @httpLabel + standId: UUID +} + +structure DeleteStandOutput {} diff --git a/spec/smithy/model/catalog/stand/stand-types.smithy b/spec/smithy/model/catalog/stand/stand-types.smithy new file mode 100644 index 0000000..1e7a85a --- /dev/null +++ b/spec/smithy/model/catalog/stand/stand-types.smithy @@ -0,0 +1,29 @@ +$version: "2" + +namespace shopping.inandout.catalog.stand + +use shopping.inandout#AuditMetadata +use shopping.inandout#PositiveDouble +use shopping.inandout#UUID +use shopping.inandout.catalog.article#ArticleSummary + +@mixin +structure StandOutputMixin with [AuditMetadata] { + @required + standId: UUID + + @required + edgeId: UUID + + @required + sourceNodeDistance: PositiveDouble + + @required + articleSummary: ArticleSummary +} + +structure StandSummary with [StandOutputMixin] {} + +list StandSummaryList { + member: StandSummary +} diff --git a/spec/smithy/model/common.smithy b/spec/smithy/model/common.smithy new file mode 100644 index 0000000..81be9b3 --- /dev/null +++ b/spec/smithy/model/common.smithy @@ -0,0 +1,140 @@ +$version: "2" + +namespace shopping.inandout + +use shopping.inandout.outlet.brand#Brand +use shopping.inandout.outlet.store#Store + +@pattern("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") +@length(min: 32, max: 32) +string UUID + +@pattern("^[a-zA-Z0-9\\- ]+$") +@length(min: 3, max: 63) +string ResourceName + +@pattern("^https?://[a-zA-Z0-9\\-._~:/?#\\[\\]@!$&'()*+,;=%]+\\.(jpg|jpeg|png|gif)$") +@length(min: 8, max: 255) +string ImageUrl + +@pattern("^[a-zA-Z0-9\\-, ]+$") +@length(min: 8, max: 255) +string Description + +// All UTC offsets fall between this interval: [-12, 14]. +// See: https://en.wikipedia.org/wiki/List_of_UTC_offsets. +@range(min: -12, max: 14) +integer UTCTimezone + +@range(min: 0, max: 59) +integer Minute + +@range(min: 0, max: 23) +integer Hour + +@range(min: -180, max: 180) +double Longitude + +@range(min: -90, max: 90) +double Latitude + +@range(min: 0, max: 100) +double Percentage + +@range(min: 0) +integer NaturalNumber + +@range(min: 0) +double PositiveDouble + +enum DayType { + MON = "MON" + TUE = "TUE" + WED = "WED" + THU = "THU" + FRI = "FRI" + SAT = "SAT" + SUN = "SUN" +} + +list UUIDList { + member: UUID +} + +structure Time { + @required + hour: Hour + + @required + minute: Minute +} + +structure TimeRange { + @required + begin: Time + + @required + end: Time +} + +@mixin +structure AuditMetadata { + @required + createdAt: Timestamp + + @required + updatedAt: Timestamp +} + +@mixin +@documentation("Parameters sent by the client to control pagination of the list results") +structure InputPagination { + @httpQuery("nextToken") + @documentation("An id used to retrieve the next page of results; leave empty for the first request") + nextToken: String + + @httpQuery("pageSize") + @default(100) + @documentation("The maximum number of items the client is requesting to be returned in this page") + pageSize: NaturalNumber +} + +@mixin +@documentation("Metadata returned to the client to assist in navigating paginated results") +structure OutputPagination { + @documentation("An id to be passed in the subsequent request to retrieve the next page; null if no more pages exist") + nextToken: String + + @required + @documentation("The actual number of items returned in the current response page.") + tokenCount: NaturalNumber +} + +// The below mixins are used for uri labels poiting to external resources. +// Internal entity used in offer/stand operations' input structures. +@mixin +@references([ + { + resource: Store + } +]) +@documentation("Internal helper structure used to diminish the verbosity of the storeId field") +structure StoreIdMixin { + @required + @httpLabel + storeId: UUID +} + +// Internal entity used in article operations' input structures. +@mixin +@references([ + { + resource: Brand + } +]) +@documentation("Internal helper structure used to diminish the verbosity of the brandId field") +structure BrandIdMixin { + @required + @httpLabel + brandId: UUID +} diff --git a/spec/smithy/model/errors.smithy b/spec/smithy/model/errors.smithy new file mode 100644 index 0000000..9ed456a --- /dev/null +++ b/spec/smithy/model/errors.smithy @@ -0,0 +1,38 @@ +$version: "2" + +namespace shopping.inandout + +@error("client") +@httpError(400) +structure InvalidInputError { + @required + message: String +} + +@error("client") +@httpError(404) +structure ResourceNotFoundError { + @required + message: String +} + +@error("client") +@httpError(409) +structure ResourceAlreadyExistsError { + @required + message: String +} + +@error("client") +@httpError(409) +structure DeleteRestrictedError { + @required + message: String +} + +@error("server") +@httpError(500) +structure InternalServerError { + @required + message: String +} diff --git a/spec/smithy/model/main.smithy b/spec/smithy/model/main.smithy new file mode 100644 index 0000000..979e107 --- /dev/null +++ b/spec/smithy/model/main.smithy @@ -0,0 +1,27 @@ +$version: "2" + +namespace shopping.inandout + +use shopping.inandout.catalog.article#Article +use shopping.inandout.catalog.product#Product +use shopping.inandout.catalog.stand#Stand +use shopping.inandout.marketing.offer#Offer +use shopping.inandout.outlet.brand#Brand +use shopping.inandout.outlet.store#Store +use shopping.inandout.tsp#FindTspSolution + +@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize", items: "tokens") +service InAndOut { + version: "2026-04-01" + resources: [ + Store + Brand + Stand + Article + Product + Offer + ] + operations: [ + FindTspSolution + ] +} diff --git a/spec/smithy/model/marketing/offer/offer-apis.smithy b/spec/smithy/model/marketing/offer/offer-apis.smithy new file mode 100644 index 0000000..0f028ce --- /dev/null +++ b/spec/smithy/model/marketing/offer/offer-apis.smithy @@ -0,0 +1,95 @@ +$version: "2" + +namespace shopping.inandout.marketing.offer + +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#NaturalNumber +use shopping.inandout#Percentage +use shopping.inandout#ResourceAlreadyExistsError +use shopping.inandout#ResourceNotFoundError +use shopping.inandout#TimeRange +use shopping.inandout#UUID +use shopping.inandout#UUIDList + +// Does NOT contain the store data, only its id is necessary for logical grouping. +resource Offer { + identifiers: { + offerId: UUID + } + properties: { + storeId: UUID + percentage: Percentage + articleIdList: UUIDList + dependencyList: DependencyList + timeRange: TimeRange + lifetime: NaturalNumber + createdAt: Timestamp + updatedAt: Timestamp + } + create: CreateOffer + read: GetOffer + list: ListOffers + update: UpdateOffer + delete: DeleteOffer +} + +@http(method: "POST", uri: "/stores/{storeId}/offers") +operation CreateOffer { + input: CreateOfferInput + output: CreateOfferOutput + errors: [ + InvalidInputError + ResourceAlreadyExistsError + InternalServerError + ] +} + +@readonly +@http(method: "GET", uri: "/stores/{storeId}/offers/{offerId}") +operation GetOffer { + input: GetOfferInput + output: GetOfferOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@readonly +@paginated +@http(method: "GET", uri: "/stores/{storeId}/offers") +operation ListOffers { + input: ListOffersInput + output: ListOffersOutput + errors: [ + InvalidInputError + InternalServerError + ] +} + +@http(method: "PATCH", uri: "/stores/{storeId}/offers/{offerId}") +@documentation("Non-idempotent cascading operation, creates/deletes internal resources as needed") +operation UpdateOffer { + input: UpdateOfferInput + output: UpdateOfferOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@idempotent +@http(method: "DELETE", uri: "/stores/{storeId}/offers/{offerId}") +@documentation("Not restricted cascading operation, deletes discounts, dependencies, etc.") +operation DeleteOffer { + input: DeleteOfferInput + output: DeleteOfferOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} diff --git a/spec/smithy/model/marketing/offer/offer-io.smithy b/spec/smithy/model/marketing/offer/offer-io.smithy new file mode 100644 index 0000000..6d3d72d --- /dev/null +++ b/spec/smithy/model/marketing/offer/offer-io.smithy @@ -0,0 +1,52 @@ +$version: "2" + +namespace shopping.inandout.marketing.offer + +use shopping.inandout#InputPagination +use shopping.inandout#OutputPagination +use shopping.inandout#Percentage +use shopping.inandout#StoreIdMixin +use shopping.inandout#UUID + +structure CreateOfferInput with [StoreIdMixin, OfferInputMixin] { + @required + percentage: Percentage +} + +structure CreateOfferOutput { + @required + offerId: UUID +} + +structure GetOfferInput with [StoreIdMixin] { + @required + @httpLabel + offerId: UUID +} + +structure GetOfferOutput with [OfferOutputMixin] {} + +structure ListOffersInput with [StoreIdMixin, InputPagination] {} + +structure ListOffersOutput with [OutputPagination] { + @required + tokens: OfferSummaryList +} + +structure UpdateOfferInput with [StoreIdMixin, OfferInputMixin] { + @required + @httpLabel + offerId: UUID + + percentage: Percentage +} + +structure UpdateOfferOutput with [OfferOutputMixin] {} + +structure DeleteOfferInput with [StoreIdMixin] { + @required + @httpLabel + offerId: UUID +} + +structure DeleteOfferOutput {} diff --git a/spec/smithy/model/marketing/offer/offer-types.smithy b/spec/smithy/model/marketing/offer/offer-types.smithy new file mode 100644 index 0000000..8c3f3cd --- /dev/null +++ b/spec/smithy/model/marketing/offer/offer-types.smithy @@ -0,0 +1,61 @@ +$version: "2" + +namespace shopping.inandout.marketing.offer + +use shopping.inandout#AuditMetadata +use shopping.inandout#NaturalNumber +use shopping.inandout#Percentage +use shopping.inandout#TimeRange +use shopping.inandout#UUID +use shopping.inandout#UUIDList +use shopping.inandout.catalog.article#Article +use shopping.inandout.outlet.store#Store + +list DependencyList { + member: Dependency +} + +@references([ + { + resource: Article + } +]) +@documentation("Product dependency; it must be bought in order for the offer to activate") +structure Dependency { + articleId: UUID + quantity: NaturalNumber +} + +@mixin +structure OfferMixin { + articleIdList: UUIDList + dependencyList: DependencyList + timeRange: TimeRange + lifetime: NaturalNumber +} + +@mixin +structure OfferInputMixin with [OfferMixin] {} + +@mixin +@references([ + { + resource: Store + } +]) +structure OfferOutputMixin with [AuditMetadata, OfferMixin] { + @required + storeId: UUID + + @required + offerId: UUID + + @required + percentage: Percentage +} + +structure OfferSummary with [OfferOutputMixin] {} + +list OfferSummaryList { + member: OfferSummary +} diff --git a/spec/smithy/model/outlet/brand/brand-apis.smithy b/spec/smithy/model/outlet/brand/brand-apis.smithy new file mode 100644 index 0000000..a7a3ed5 --- /dev/null +++ b/spec/smithy/model/outlet/brand/brand-apis.smithy @@ -0,0 +1,76 @@ +$version: "2" + +namespace shopping.inandout.outlet.brand + +use shopping.inandout#DeleteRestrictedError +use shopping.inandout#ImageUrl +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#ResourceAlreadyExistsError +use shopping.inandout#ResourceName +use shopping.inandout#ResourceNotFoundError +use shopping.inandout#UUID + +resource Brand { + identifiers: { + brandId: UUID + } + properties: { + name: ResourceName + logoUrl: ImageUrl + createdAt: Timestamp + updatedAt: Timestamp + } + create: CreateBrand + read: GetBrand + update: UpdateBrand + delete: DeleteBrand +} + +@http(method: "POST", uri: "/brands") +operation CreateBrand { + input: CreateBrandInput + output: CreateBrandOutput + errors: [ + InvalidInputError + ResourceAlreadyExistsError + InternalServerError + ] +} + +@readonly +@http(method: "GET", uri: "/brands/{brandId}") +operation GetBrand { + input: GetBrandInput + output: GetBrandOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@http(method: "PATCH", uri: "/brands/{brandId}") +operation UpdateBrand { + input: UpdateBrandInput + output: UpdateBrandOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@idempotent +@http(method: "DELETE", uri: "/brands/{brandId}") +@documentation("Restricted cascading operation, references for stores and articles should NOT exist") +operation DeleteBrand { + input: DeleteBrandInput + output: DeleteBrandOutput + errors: [ + InvalidInputError + ResourceNotFoundError + DeleteRestrictedError + InternalServerError + ] +} diff --git a/spec/smithy/model/outlet/brand/brand-io.smithy b/spec/smithy/model/outlet/brand/brand-io.smithy new file mode 100644 index 0000000..3ad1acf --- /dev/null +++ b/spec/smithy/model/outlet/brand/brand-io.smithy @@ -0,0 +1,42 @@ +$version: "2" + +namespace shopping.inandout.outlet.brand + +use shopping.inandout#ResourceName +use shopping.inandout#UUID + +structure CreateBrandInput with [BrandInputMixin] { + @required + name: ResourceName +} + +structure CreateBrandOutput { + @required + brandId: UUID +} + +structure GetBrandInput { + @required + @httpLabel + brandId: UUID +} + +structure GetBrandOutput with [BrandOutputMixin] {} + +structure UpdateBrandInput with [BrandInputMixin] { + @required + @httpLabel + brandId: UUID + + name: ResourceName +} + +structure UpdateBrandOutput with [BrandOutputMixin] {} + +structure DeleteBrandInput { + @required + @httpLabel + brandId: UUID +} + +structure DeleteBrandOutput {} diff --git a/spec/smithy/model/outlet/brand/brand-types.smithy b/spec/smithy/model/outlet/brand/brand-types.smithy new file mode 100644 index 0000000..94b8817 --- /dev/null +++ b/spec/smithy/model/outlet/brand/brand-types.smithy @@ -0,0 +1,32 @@ +$version: "2" + +namespace shopping.inandout.outlet.brand + +use shopping.inandout#AuditMetadata +use shopping.inandout#ImageUrl +use shopping.inandout#ResourceName +use shopping.inandout#UUID + +@mixin +structure BrandMixin { + logoUrl: ImageUrl +} + +@mixin +structure BrandInputMixin with [BrandMixin] {} + +@mixin +@references([ + { + resource: Brand + } +]) +structure BrandOutputMixin with [AuditMetadata, BrandMixin] { + @required + brandId: UUID + + @required + name: ResourceName +} + +structure BrandSummary with [BrandOutputMixin] {} diff --git a/spec/smithy/model/outlet/store/store-apis.smithy b/spec/smithy/model/outlet/store/store-apis.smithy new file mode 100644 index 0000000..e2e31b5 --- /dev/null +++ b/spec/smithy/model/outlet/store/store-apis.smithy @@ -0,0 +1,104 @@ +$version: "2" + +namespace shopping.inandout.outlet.store + +use shopping.inandout#Description +use shopping.inandout#ImageUrl +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#Latitude +use shopping.inandout#Longitude +use shopping.inandout#NaturalNumber +use shopping.inandout#ResourceAlreadyExistsError +use shopping.inandout#ResourceName +use shopping.inandout#ResourceNotFoundError +use shopping.inandout#UTCTimezone +use shopping.inandout#UUID +use shopping.inandout.outlet.brand#BrandSummary + +resource Store { + identifiers: { + storeId: UUID + } + properties: { + name: ResourceName + brandSummary: BrandSummary + description: Description + imageUrl: ImageUrl + timezone: UTCTimezone + operatingHoursMap: OperatingHoursMap + locationMapping: LocationMapping + mappingVersion: NaturalNumber + longitude: Longitude + latitude: Latitude + createdAt: Timestamp + updatedAt: Timestamp + } + create: CreateStore + read: GetStore + list: ListStores + update: UpdateStore + delete: DeleteStore +} + +@http(method: "POST", uri: "/stores") +operation CreateStore { + input: CreateStoreInput + output: CreateStoreOutput + errors: [ + InvalidInputError + ResourceAlreadyExistsError + InternalServerError + ] +} + +@readonly +@http(method: "GET", uri: "/stores/{storeId}") +@documentation("Returns additional brand details in order to avoid multiple network round-trips") +operation GetStore { + input: GetStoreInput + output: GetStoreOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@readonly +@paginated +@http(method: "GET", uri: "/stores") +@documentation("Returns additional brand details in order to avoid multiple network round-trips") +operation ListStores { + input: ListStoresInput + output: ListStoresOutput + errors: [ + InvalidInputError + InternalServerError + ] +} + +@http(method: "PATCH", uri: "/stores/{storeId}") +@documentation("Non-idempotent cascading operation, creates/deletes internal resources as needed") +operation UpdateStore { + input: UpdateStoreInput + output: UpdateStoreOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} + +@idempotent +@http(method: "DELETE", uri: "/stores/{storeId}") +@documentation("Not restricted cascading operation, deletes floors, stands, etc.") +operation DeleteStore { + input: DeleteStoreInput + output: DeleteStoreOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} diff --git a/spec/smithy/model/outlet/store/store-io.smithy b/spec/smithy/model/outlet/store/store-io.smithy new file mode 100644 index 0000000..bb1331c --- /dev/null +++ b/spec/smithy/model/outlet/store/store-io.smithy @@ -0,0 +1,79 @@ +$version: "2" + +namespace shopping.inandout.outlet.store + +use shopping.inandout#InputPagination +use shopping.inandout#Latitude +use shopping.inandout#Longitude +use shopping.inandout#NaturalNumber +use shopping.inandout#OutputPagination +use shopping.inandout#ResourceName +use shopping.inandout#UUID +use shopping.inandout.outlet.brand#Brand + +// The creation of the brand is independent of the creation of the store. +@references([ + { + resource: Brand + } +]) +structure CreateStoreInput with [StoreInputMixin] { + @required + @notProperty + brandId: UUID +} + +structure CreateStoreOutput { + @required + storeId: UUID +} + +structure GetStoreInput { + @required + @httpLabel + storeId: UUID +} + +structure GetStoreOutput with [StoreOutputMixin] {} + +@documentation("Retrieve a list of stores based on the provided queries") +structure ListStoresInput with [InputPagination] { + @httpQuery("name") + name: ResourceName + + @httpQuery("userLongitude") + userLongitude: Longitude + + @httpQuery("userLatitude") + userLatitude: Latitude + + // ! User location must be provided in order for the below queries to work. + @httpQuery("isOpen") + @documentation("Based on user location, his timezone is computed and then the list of open markets") + isOpen: Boolean + + @httpQuery("maxDistance") + @documentation("Distance measured in kilometers") + maxDistance: NaturalNumber +} + +structure ListStoresOutput with [OutputPagination] { + @required + tokens: StoreSummaryList +} + +structure UpdateStoreInput with [StoreInputMixin] { + @required + @httpLabel + storeId: UUID +} + +structure UpdateStoreOutput with [StoreOutputMixin] {} + +structure DeleteStoreInput { + @required + @httpLabel + storeId: UUID +} + +structure DeleteStoreOutput {} diff --git a/spec/smithy/model/outlet/store/store-types.smithy b/spec/smithy/model/outlet/store/store-types.smithy new file mode 100644 index 0000000..268e5c2 --- /dev/null +++ b/spec/smithy/model/outlet/store/store-types.smithy @@ -0,0 +1,107 @@ +$version: "2" + +namespace shopping.inandout.outlet.store + +use shopping.inandout#AuditMetadata +use shopping.inandout#DayType +use shopping.inandout#Description +use shopping.inandout#ImageUrl +use shopping.inandout#Latitude +use shopping.inandout#Longitude +use shopping.inandout#NaturalNumber +use shopping.inandout#ResourceName +use shopping.inandout#TimeRange +use shopping.inandout#UTCTimezone +use shopping.inandout#UUID +use shopping.inandout.outlet.brand#BrandSummary + +map OperatingHoursMap { + key: DayType + value: TimeRange +} + +structure LocationMapping { + floorList: FloorList +} + +list FloorList { + member: Floor +} + +structure Floor { + @required + floorId: UUID + + @required + level: Byte + + edgeList: EdgeList +} + +list EdgeList { + member: Edge +} + +structure Edge { + @required + sourceNode: Node + + @required + targetNode: Node + + name: ResourceName + + weight: Double +} + +structure Node { + @required + name: ResourceName + + type: NodeType +} + +enum NodeType { + NAVIGATION = "NAVIGATION" + ELEVATION = "ELEVATION" + DESCENT = "DESCENT" +} + +@mixin +structure StoreMixin { + description: Description + imageUrl: ImageUrl + timezone: UTCTimezone + operatingHoursMap: OperatingHoursMap + longitude: Longitude + latitude: Latitude +} + +@mixin +structure StoreInputMixin with [StoreMixin] { + name: ResourceName + locationMapping: LocationMapping +} + +@mixin +@documentation("Retrieves store and its associated brand details") +structure StoreOutputMixin with [AuditMetadata, StoreMixin] { + @required + storeId: UUID + + @required + name: ResourceName + + @required + brandSummary: BrandSummary + + @required + mappingVersion: NaturalNumber +} + +// Needed for the list method. +structure StoreSummary with [StoreOutputMixin] {} + +list StoreSummaryList { + member: StoreSummary +} diff --git a/spec/smithy/model/smithy-build.json b/spec/smithy/model/smithy-build.json new file mode 100644 index 0000000..06575a3 --- /dev/null +++ b/spec/smithy/model/smithy-build.json @@ -0,0 +1,6 @@ +{ + "version": "1.0", + "sources": [ + "." + ] +} \ No newline at end of file diff --git a/spec/smithy/model/tsp/tsp-apis.smithy b/spec/smithy/model/tsp/tsp-apis.smithy new file mode 100644 index 0000000..5e61169 --- /dev/null +++ b/spec/smithy/model/tsp/tsp-apis.smithy @@ -0,0 +1,19 @@ +$version: "2" + +namespace shopping.inandout.tsp + +use shopping.inandout#InternalServerError +use shopping.inandout#InvalidInputError +use shopping.inandout#ResourceNotFoundError + +@http(method: "POST", uri: "/tsp") +@documentation("Travelling salesman problem solution creation/retrieval operation") +operation FindTspSolution { + input: FindTspSolutionInput + output: FindTspSolutionOutput + errors: [ + InvalidInputError + ResourceNotFoundError + InternalServerError + ] +} diff --git a/spec/smithy/model/tsp/tsp-io.smithy b/spec/smithy/model/tsp/tsp-io.smithy new file mode 100644 index 0000000..1a430b8 --- /dev/null +++ b/spec/smithy/model/tsp/tsp-io.smithy @@ -0,0 +1,15 @@ +$version: "2" + +namespace shopping.inandout.tsp + +use shopping.inandout#UUIDList + +structure FindTspSolutionInput { + @required + standIdList: UUIDList +} + +structure FindTspSolutionOutput { + @required + soltuionList: SoltuionList +} diff --git a/spec/smithy/model/tsp/tsp-types.smithy b/spec/smithy/model/tsp/tsp-types.smithy new file mode 100644 index 0000000..333820a --- /dev/null +++ b/spec/smithy/model/tsp/tsp-types.smithy @@ -0,0 +1,16 @@ +$version: "2" + +namespace shopping.inandout.tsp + +use shopping.inandout#UUIDList + +@documentation("Optimal market route") +structure Soltuion { + @required + @documentation("Ordered location list of the selected articles") + nodeIdList: UUIDList +} + +list SoltuionList { + member: Soltuion +}