From df03453ad05a3f534eafcfb947f2b5c56354ecc9 Mon Sep 17 00:00:00 2001 From: Dev Singh Date: Fri, 3 Oct 2025 13:27:21 -0500 Subject: [PATCH 1/2] Create store inventory tables --- terraform/modules/dynamo/main.tf | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/terraform/modules/dynamo/main.tf b/terraform/modules/dynamo/main.tf index 73a1a77e..169b9621 100644 --- a/terraform/modules/dynamo/main.tf +++ b/terraform/modules/dynamo/main.tf @@ -339,3 +339,22 @@ resource "aws_dynamodb_table" "sig_info" { projection_type = "KEYS_ONLY" } } + +resource "aws_dynamodb_table" "store_inventory" { + billing_mode = "PAY_PER_REQUEST" + name = "${var.ProjectId}-store-inventory" + deletion_protection_enabled = true + hash_key = "productId" + range_key = "variantId" + point_in_time_recovery { + enabled = true + } + attribute { + name = "productId" + type = "S" + } + attribute { + name = "variantId" + type = "S" + } +} From 80b09c55cf1bf4cdaab67974b5b2394e7b9b5b65 Mon Sep 17 00:00:00 2001 From: Dev Singh Date: Fri, 3 Oct 2025 13:56:31 -0500 Subject: [PATCH 2/2] Add templated code --- src/api/functions/store.ts | 47 ++++++++++++++++++++++++++++++++++++++ src/common/config.ts | 3 +++ 2 files changed, 50 insertions(+) create mode 100644 src/api/functions/store.ts diff --git a/src/api/functions/store.ts b/src/api/functions/store.ts new file mode 100644 index 00000000..ebdb09e6 --- /dev/null +++ b/src/api/functions/store.ts @@ -0,0 +1,47 @@ +// TODO: (store) Create a function to check if a given product and variant are sellable to a given user +// If it is sellable, return the price ID to create a stripe checkout session for + +import { type DynamoDBClient } from "@aws-sdk/client-dynamodb"; +import { type Redis } from "api/types.js"; + +// If not, return null. +export type CheckItemSellableInputs = { + userId: string; // This is generally their Illinois email + productId: string; + variantId: string; + dynamoClient: DynamoDBClient; + redisClient: Redis; +}; + +export type CheckItemSellableOutputs = null | string; + +export async function checkItemSellable({ + userId, + productId, + variantId, + dynamoClient, + redisClient, +}: CheckItemSellableInputs): Promise { + // In a transaction: + // First, check if there is stock. + // If there is stock, check that the user is still under their limit. + // If there is, check if they are a paid member. + // If paid member return member_price_id for the variant request, if not return the nonmember_price_id + return null; +} + +export type CreateCheckoutSessionInputs = { + priceId: string; + username: string; + stripeApiKey: string; +}; + +export type CreateCheckoutSessionOutputs = string; + +export async function createCheckoutSession({ + priceId, +}: CreateCheckoutSessionInputs): Promise { + // Check stripe modules createCheckoutSession function + // initatior string should be "acm-store" + return ""; +} diff --git a/src/common/config.ts b/src/common/config.ts index 0d1801da..423f1b5d 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -64,6 +64,8 @@ export type GenericConfigType = { UserInfoTable: string; SigInfoTableName: string; EntraHostedDomainName: string; + StoreInventoryTableName: string; + // TODO: (store) add other tables }; type EnvironmentConfigType = { @@ -106,6 +108,7 @@ const genericConfig: GenericConfigType = { UserInfoTable: "infra-core-api-user-info", SigInfoTableName: "infra-core-api-sigs", EntraHostedDomainName: "acmillinois.onmicrosoft.com", + StoreInventoryTableName: "infra-core-api-store-inventory" } as const; const environmentConfig: EnvironmentConfigType = {