diff --git a/apps/avatax/graphql/fragments/CalculateTaxesEvent.graphql b/apps/avatax/graphql/fragments/CalculateTaxesEvent.graphql index 6481de46b0..aecac79077 100644 --- a/apps/avatax/graphql/fragments/CalculateTaxesEvent.graphql +++ b/apps/avatax/graphql/fragments/CalculateTaxesEvent.graphql @@ -6,6 +6,7 @@ fragment CalculateTaxesEvent on Event { ...TaxBase } recipient { + # Entire metadata is fetched to provide app configuration. This can be moved to DB privateMetadata { key value diff --git a/apps/avatax/graphql/fragments/TaxBase.graphql b/apps/avatax/graphql/fragments/TaxBase.graphql index 174d42da02..69443ae8f2 100644 --- a/apps/avatax/graphql/fragments/TaxBase.graphql +++ b/apps/avatax/graphql/fragments/TaxBase.graphql @@ -63,7 +63,9 @@ fragment TaxBase on TaxableObject { __typename ... on Checkout { id + # TODO what was that avataxEntityCode: metafield(key: "avataxEntityCode") + # Legacy field - moved to user avataxCustomerCode: metafield(key: "avataxCustomerCode") user { ...User @@ -71,7 +73,9 @@ fragment TaxBase on TaxableObject { } ... on Order { id + # TODO what was that avataxEntityCode: metafield(key: "avataxEntityCode") + # Legacy field - moved to user avataxCustomerCode: metafield(key: "avataxCustomerCode") user { ...User diff --git a/apps/avatax/graphql/fragments/User.graphql b/apps/avatax/graphql/fragments/User.graphql index 2e25390eba..4fc1b0c2cd 100644 --- a/apps/avatax/graphql/fragments/User.graphql +++ b/apps/avatax/graphql/fragments/User.graphql @@ -1,5 +1,6 @@ fragment User on User { id email + # Metadata is fetched with user. This is on purpose - must be set on the frontend. avataxCustomerCode: metafield(key: "avataxCustomerCode") } diff --git a/apps/avatax/graphql/queries/FetchAppDetails.graphql b/apps/avatax/graphql/queries/FetchAppDetails.graphql index b4bad820a2..3a63db3aef 100644 --- a/apps/avatax/graphql/queries/FetchAppDetails.graphql +++ b/apps/avatax/graphql/queries/FetchAppDetails.graphql @@ -1,6 +1,7 @@ query FetchAppDetails { app { id + # Programmatic fetch of metadata -> to fetch config privateMetadata { key value diff --git a/apps/avatax/graphql/queries/FetchAppMetafields.graphql b/apps/avatax/graphql/queries/FetchAppMetafields.graphql index c2982823d8..3535b08eb3 100644 --- a/apps/avatax/graphql/queries/FetchAppMetafields.graphql +++ b/apps/avatax/graphql/queries/FetchAppMetafields.graphql @@ -1,6 +1,7 @@ query FetchAppMetafields($keys: [String!]) { app { id + # Programmatic fetch of metadata -> to fetch config privateMetafields(keys: $keys) } } diff --git a/apps/avatax/graphql/subscriptions/OrderCancelled.graphql b/apps/avatax/graphql/subscriptions/OrderCancelled.graphql index 9558f61299..cda40d92e9 100644 --- a/apps/avatax/graphql/subscriptions/OrderCancelled.graphql +++ b/apps/avatax/graphql/subscriptions/OrderCancelled.graphql @@ -1,5 +1,6 @@ fragment OrderCancelledSubscription on Order { id + # Reference to Avatax transaction. Can be stored in the DB? avataxId: metafield(key: "avataxId") channel { id diff --git a/apps/avatax/saleor-app.ts b/apps/avatax/saleor-app.ts index 96a4166bbc..a090d82c57 100644 --- a/apps/avatax/saleor-app.ts +++ b/apps/avatax/saleor-app.ts @@ -20,6 +20,10 @@ switch (process.env.APL) { throw new Error("Rest APL is not configured - missing env variables. Check saleor-app.ts"); } + /** + * APL: + * - Call REST service every time request to app is executed (webhook, frontend call) + */ apl = new SaleorCloudAPL({ resourceUrl: process.env.REST_APL_ENDPOINT, token: process.env.REST_APL_TOKEN, diff --git a/apps/avatax/src/lib/app-config-extractor.ts b/apps/avatax/src/lib/app-config-extractor.ts index 3e0456aab2..39eacf0142 100644 --- a/apps/avatax/src/lib/app-config-extractor.ts +++ b/apps/avatax/src/lib/app-config-extractor.ts @@ -14,6 +14,9 @@ export interface IAppConfigExtractor { /** * Extracts app configuration from metadata. Performs initial validation, shared by all clients + * + * It takes metadata from event (or programmatic call) and maps it to the object. + * This can be replaced by similar entity, calling DB */ export class AppConfigExtractor implements IAppConfigExtractor { static AppConfigExtractorError = BaseError.subclass("AppConfigExtractorError"); diff --git a/apps/avatax/src/modules/app/order-metadata-manager.ts b/apps/avatax/src/modules/app/order-metadata-manager.ts index b5a7102299..ae2a46daab 100644 --- a/apps/avatax/src/modules/app/order-metadata-manager.ts +++ b/apps/avatax/src/modules/app/order-metadata-manager.ts @@ -22,6 +22,8 @@ export class OrderMetadataManager { * @param orderId - Saleor order id * @param externalId - Provider order id * @deprecated - This will not be needed when we move to the new webhook flow because the transactions will be commited during OrderConfirmed + * + * Do we need to store this value? It seems like its stored to cancel order in order-cancelled. So we can store this in DB */ async updateOrderMetadataWithExternalId(orderId: string, externalId: string) { const variables: UpdatePublicMetadataMutationVariables = { diff --git a/apps/avatax/src/modules/avatax/configuration/avatax-connection-repository.ts b/apps/avatax/src/modules/avatax/configuration/avatax-connection-repository.ts index 6c98d71b08..26d7dd10e3 100644 --- a/apps/avatax/src/modules/avatax/configuration/avatax-connection-repository.ts +++ b/apps/avatax/src/modules/avatax/configuration/avatax-connection-repository.ts @@ -15,6 +15,7 @@ import { const getSchema = avataxConnectionSchema.strict(); +// Uses metadata to CRUD settings export class AvataxConnectionRepository { private crudSettingsManager: CrudSettingsManager; private logger = createLogger("AvataxConnectionRepository", { diff --git a/apps/avatax/src/modules/avatax/configuration/avatax-patch-input-transformer.ts b/apps/avatax/src/modules/avatax/configuration/avatax-patch-input-transformer.ts index 7aaeb93ad2..68db499ecf 100644 --- a/apps/avatax/src/modules/avatax/configuration/avatax-patch-input-transformer.ts +++ b/apps/avatax/src/modules/avatax/configuration/avatax-patch-input-transformer.ts @@ -35,6 +35,7 @@ export class AvataxPatchInputTransformer { } async patchCredentials(id: string, input: AvataxConfig["credentials"]) { + // Metadata call const connection = await this.connection.getById(id); const credentials: AvataxConfig["credentials"] = { diff --git a/apps/avatax/src/modules/avatax/tax-code/avatax-tax-codes.router.ts b/apps/avatax/src/modules/avatax/tax-code/avatax-tax-codes.router.ts index 2e89dfcd52..7beb22f5dd 100644 --- a/apps/avatax/src/modules/avatax/tax-code/avatax-tax-codes.router.ts +++ b/apps/avatax/src/modules/avatax/tax-code/avatax-tax-codes.router.ts @@ -17,7 +17,10 @@ const getAllForIdSchema = z.object({ uniqueKey: z.string(), }); -// TODO: Add test, but create dependency injection first, so services can be injected in ctx +/* + * TODO: Add test, but create dependency injection first, so services can be injected in ctx + * Client router - only CRUD from frontend handled here + */ export const avataxTaxCodesRouter = router({ getAllForId: protectedClientProcedure.input(getAllForIdSchema).query(async ({ ctx, input }) => { const logger = createLogger("avataxTaxCodesRouter.getAllForId"); diff --git a/apps/avatax/src/modules/crud-settings/crud-settings.service.ts b/apps/avatax/src/modules/crud-settings/crud-settings.service.ts index 030b93f0e0..65826613d3 100644 --- a/apps/avatax/src/modules/crud-settings/crud-settings.service.ts +++ b/apps/avatax/src/modules/crud-settings/crud-settings.service.ts @@ -7,6 +7,7 @@ import { createLogger } from "../../logger"; const settingSchema = z.record(z.any()).and(z.object({ id: z.string() })); const settingsSchema = z.array(settingSchema); +// Abstraction on CRUD operations - writing to Saleor metadata export class CrudSettingsManager { private logger = createLogger("CrudSettingsManager"); diff --git a/apps/avatax/src/pages/api/webhooks/order-confirmed.ts b/apps/avatax/src/pages/api/webhooks/order-confirmed.ts index 7abc1f60d8..3a52f98b5e 100644 --- a/apps/avatax/src/pages/api/webhooks/order-confirmed.ts +++ b/apps/avatax/src/pages/api/webhooks/order-confirmed.ts @@ -78,6 +78,7 @@ export default wrapWithLoggerContext( .json({ message: `Order ${payload.order?.id} has flat rates tax strategy.` }); } + // metadata passed through subscription payload const appMetadata = payload.recipient?.privateMetadata ?? []; const configExtractor = new AppConfigExtractor(); @@ -155,6 +156,7 @@ export default wrapWithLoggerContext( const orderMetadataManager = new OrderMetadataManager(client); + // We run metadata mutation here. Its public metadata - result from Avatax attached to Saleor entity await orderMetadataManager.updateOrderMetadataWithExternalId( confirmedOrderEvent.getOrderId(), confirmedOrder.id,