From d55b2f9b2a561457e9fc9adee9b33def097e7fff Mon Sep 17 00:00:00 2001 From: Adrian Pilarczyk Date: Thu, 30 Mar 2023 13:12:52 +0200 Subject: [PATCH] fix/333 taxes not calculated (#345) * refactor: :loud_sound: improve logging in taxes * refactor: :fire: redundant channels call * refactor: :recycle: get app config from payload * build: add changeset * refactor: :loud_sound: routers info -> debug * refactor: :loud_sound: redact logs --- .changeset/many-numbers-smile.md | 5 +++ .../fragments/CalculateTaxesEvent.graphql | 6 +++ apps/taxes/src/lib/logger.ts | 6 +++ apps/taxes/src/lib/saleor/schema.ts | 8 ++++ .../app-configuration/get-app-config.ts | 39 +++++++++++++++++++ .../app-configuration/metadata-manager.ts | 11 ++++++ .../taxes/src/modules/avatax/avatax-client.ts | 12 ++++-- .../avatax/avatax-configuration.router.ts | 11 +++--- .../avatax/avatax-configuration.service.ts | 2 +- .../src/modules/avatax/avatax-provider.ts | 14 ++++--- .../channels-configuration/channels-config.ts | 2 +- .../channels-configuration.router.ts | 17 +++++--- .../get-channels-configuration.service.ts | 10 +---- .../crud-settings/crud-settings.service.ts | 12 +++--- .../providers-configuration.router.ts | 5 ++- .../src/modules/taxes/active-tax-provider.ts | 10 ++++- apps/taxes/src/modules/taxes/tax-provider.ts | 4 +- .../taxes/src/modules/taxjar/taxjar-client.ts | 11 ++++-- .../taxjar/taxjar-configuration.router.ts | 4 +- .../taxjar/taxjar-configuration.service.ts | 4 +- .../src/modules/taxjar/taxjar-provider.ts | 21 +++++----- .../api/webhooks/checkout-calculate-taxes.ts | 33 +++++----------- .../api/webhooks/order-calculate-taxes.ts | 32 +++++---------- 23 files changed, 174 insertions(+), 105 deletions(-) create mode 100644 .changeset/many-numbers-smile.md create mode 100644 apps/taxes/src/modules/app-configuration/get-app-config.ts diff --git a/.changeset/many-numbers-smile.md b/.changeset/many-numbers-smile.md new file mode 100644 index 0000000..ddbda8a --- /dev/null +++ b/.changeset/many-numbers-smile.md @@ -0,0 +1,5 @@ +--- +"saleor-app-taxes": minor +--- + +Improve webhook processing time by adding the app config to subscription payload instead of fetching it separately. diff --git a/apps/taxes/graphql/fragments/CalculateTaxesEvent.graphql b/apps/taxes/graphql/fragments/CalculateTaxesEvent.graphql index 353a53c..08c11e0 100644 --- a/apps/taxes/graphql/fragments/CalculateTaxesEvent.graphql +++ b/apps/taxes/graphql/fragments/CalculateTaxesEvent.graphql @@ -4,5 +4,11 @@ fragment CalculateTaxesEvent on Event { taxBase { ...TaxBase } + recipient { + privateMetadata { + key + value + } + } } } diff --git a/apps/taxes/src/lib/logger.ts b/apps/taxes/src/lib/logger.ts index 6ca89d9..f0ad112 100644 --- a/apps/taxes/src/lib/logger.ts +++ b/apps/taxes/src/lib/logger.ts @@ -11,6 +11,12 @@ export const logger = pino({ }, } : undefined, + redact: [ + "metadata", + "providerInstance.config.username", + "providerInstance.config.password", + "providerInstance.config.apiKey", + ], }); export const createLogger = logger.child.bind(logger); diff --git a/apps/taxes/src/lib/saleor/schema.ts b/apps/taxes/src/lib/saleor/schema.ts index 68749f9..c44d23a 100644 --- a/apps/taxes/src/lib/saleor/schema.ts +++ b/apps/taxes/src/lib/saleor/schema.ts @@ -65,6 +65,14 @@ const taxBaseLineSchema = z.object({ export const calculateTaxesPayloadSchema: z.ZodType = z.object({ __typename: z.literal("CalculateTaxes"), + recipient: z.object({ + privateMetadata: z.array( + z.object({ + key: z.string(), + value: z.string(), + }) + ), + }), taxBase: z.object({ currency: z.string(), channel: z.object({ diff --git a/apps/taxes/src/modules/app-configuration/get-app-config.ts b/apps/taxes/src/modules/app-configuration/get-app-config.ts new file mode 100644 index 0000000..91b8320 --- /dev/null +++ b/apps/taxes/src/modules/app-configuration/get-app-config.ts @@ -0,0 +1,39 @@ +import { decrypt } from "@saleor/app-sdk/settings-manager"; +import { ExpectedWebhookPayload } from "../../lib/saleor/schema"; +import { ChannelsConfig, channelsSchema } from "../channels-configuration/channels-config"; +import { ProvidersConfig, providersSchema } from "../providers-configuration/providers-config"; + +export const getAppConfig = (payload: ExpectedWebhookPayload) => { + const metadata = payload.recipient?.privateMetadata; + let providersConfig = [] as ProvidersConfig; + let channelsConfig = {} as ChannelsConfig; + + const secretKey = process.env.SECRET_KEY; + + if (!secretKey) { + throw new Error("SECRET_KEY env variable is not set"); + } + + // * The App Config contains two types of data: providers and channels. + // * We must recognize which one we are dealing with and parse it accordingly. + metadata?.forEach((item) => { + const decrypted = decrypt(item.value, secretKey); + const parsed = JSON.parse(decrypted); + + const providersValidation = providersSchema.safeParse(parsed); + + if (providersValidation.success) { + providersConfig = providersValidation.data; + return; + } + + const channelsValidation = channelsSchema.safeParse(parsed); + + if (channelsValidation.success) { + channelsConfig = channelsValidation.data; + return; + } + }); + + return { providers: providersConfig, channels: channelsConfig }; +}; diff --git a/apps/taxes/src/modules/app-configuration/metadata-manager.ts b/apps/taxes/src/modules/app-configuration/metadata-manager.ts index aeab097..9cf6a4c 100644 --- a/apps/taxes/src/modules/app-configuration/metadata-manager.ts +++ b/apps/taxes/src/modules/app-configuration/metadata-manager.ts @@ -5,12 +5,19 @@ import { FetchAppDetailsQuery, UpdateAppMetadataDocument, } from "../../../generated/graphql"; +import { logger as pinoLogger } from "../../lib/logger"; export async function fetchAllMetadata(client: Client): Promise { + const logger = pinoLogger.child({ service: "fetchAllMetadata" }); + logger.debug("Fetching metadata from Saleor"); + const { error, data } = await client .query(FetchAppDetailsDocument, {}) .toPromise(); + // * `metadata` name is required for secrets censorship + logger.debug({ error, metadata: data }, "Metadata fetched"); + if (error) { return []; } @@ -19,11 +26,15 @@ export async function fetchAllMetadata(client: Client): Promise } export async function mutateMetadata(client: Client, metadata: MetadataEntry[]) { + const logger = pinoLogger.child({ service: "mutateMetadata" }); + logger.debug({ metadata }, "Mutating metadata"); // to update the metadata, ID is required const { error: idQueryError, data: idQueryData } = await client .query(FetchAppDetailsDocument, {}) .toPromise(); + logger.debug({ error: idQueryError, data: idQueryData }, "Metadata mutated"); + if (idQueryError) { throw new Error( "Could not fetch the app id. Please check if auth data for the client are valid." diff --git a/apps/taxes/src/modules/avatax/avatax-client.ts b/apps/taxes/src/modules/avatax/avatax-client.ts index 8157589..d9cdeca 100644 --- a/apps/taxes/src/modules/avatax/avatax-client.ts +++ b/apps/taxes/src/modules/avatax/avatax-client.ts @@ -1,7 +1,8 @@ import Avatax from "avatax"; import { CreateTransactionModel } from "avatax/lib/models/CreateTransactionModel"; +import pino from "pino"; import packageJson from "../../../package.json"; -import { logger } from "../../lib/logger"; +import { createLogger } from "../../lib/logger"; import { AvataxConfig } from "./avatax-config"; type AvataxSettings = { @@ -36,9 +37,11 @@ const createAvataxSettings = (config: AvataxConfig): AvataxSettings => { export class AvataxClient { private client: Avatax; + private logger: pino.Logger; constructor(config: AvataxConfig) { - logger.debug("AvataxClient constructor"); + this.logger = createLogger({ service: "AvataxClient" }); + this.logger.trace("AvataxClient constructor"); const { username, password } = config; const credentials = { username, @@ -46,15 +49,18 @@ export class AvataxClient { }; const settings = createAvataxSettings(config); const avataxClient = new Avatax(settings).withSecurity(credentials); - logger.info({ client: avataxClient }, "External Avatax client created"); + this.logger.trace({ client: avataxClient }, "External Avatax client created"); this.client = avataxClient; } async fetchTaxesForOrder(model: CreateTransactionModel) { + this.logger.debug({ model }, "fetchTaxesForOrder called with:"); + return this.client.createTransaction({ model }); } async ping() { + this.logger.debug("ping called"); try { const result = await this.client.ping(); diff --git a/apps/taxes/src/modules/avatax/avatax-configuration.router.ts b/apps/taxes/src/modules/avatax/avatax-configuration.router.ts index 81a794f..b668344 100644 --- a/apps/taxes/src/modules/avatax/avatax-configuration.router.ts +++ b/apps/taxes/src/modules/avatax/avatax-configuration.router.ts @@ -37,14 +37,15 @@ export const avataxConfigurationRouter = router({ procedure: "avataxConfigurationRouter.get", }); - logger.debug("avataxConfigurationRouter.get called"); + logger.debug({ input }, "avataxConfigurationRouter.get called with:"); const { apiClient, saleorApiUrl } = ctx; const avataxConfigurationService = new AvataxConfigurationService(apiClient, saleorApiUrl); const result = await avataxConfigurationService.get(input.id); - logger.debug({ result }, "avataxConfigurationRouter.get finished"); + // * `providerInstance` name is required for secrets censorship + logger.debug({ providerInstance: result }, "avataxConfigurationRouter.get finished"); return { ...result, config: obfuscateAvataxConfig(result.config) }; }), @@ -54,7 +55,7 @@ export const avataxConfigurationRouter = router({ procedure: "avataxConfigurationRouter.post", }); - logger.debug("avataxConfigurationRouter.post called"); + logger.debug({ input }, "avataxConfigurationRouter.post called with:"); const { apiClient, saleorApiUrl } = ctx; const avataxConfigurationService = new AvataxConfigurationService(apiClient, saleorApiUrl); @@ -71,7 +72,7 @@ export const avataxConfigurationRouter = router({ procedure: "avataxConfigurationRouter.delete", }); - logger.debug("avataxConfigurationRouter.delete called"); + logger.debug({ input }, "avataxConfigurationRouter.delete called with:"); const { apiClient, saleorApiUrl } = ctx; const avataxConfigurationService = new AvataxConfigurationService(apiClient, saleorApiUrl); @@ -88,7 +89,7 @@ export const avataxConfigurationRouter = router({ procedure: "avataxConfigurationRouter.patch", }); - logger.debug("avataxConfigurationRouter.patch called"); + logger.debug({ input }, "avataxConfigurationRouter.patch called with:"); const { apiClient, saleorApiUrl } = ctx; const avataxConfigurationService = new AvataxConfigurationService(apiClient, saleorApiUrl); diff --git a/apps/taxes/src/modules/avatax/avatax-configuration.service.ts b/apps/taxes/src/modules/avatax/avatax-configuration.service.ts index dce1fe9..6038587 100644 --- a/apps/taxes/src/modules/avatax/avatax-configuration.service.ts +++ b/apps/taxes/src/modules/avatax/avatax-configuration.service.ts @@ -45,7 +45,7 @@ export class AvataxConfigurationService { async get(id: string): Promise { this.logger.debug(`.get called with id: ${id}`); const { data } = await this.crudSettingsConfigurator.read(id); - this.logger.debug({ setting: data }, `Fetched setting from crudSettingsConfigurator`); + this.logger.debug(`Fetched setting from crudSettingsConfigurator`); const validation = getSchema.safeParse(data); diff --git a/apps/taxes/src/modules/avatax/avatax-provider.ts b/apps/taxes/src/modules/avatax/avatax-provider.ts index a312ad1..4da8add 100644 --- a/apps/taxes/src/modules/avatax/avatax-provider.ts +++ b/apps/taxes/src/modules/avatax/avatax-provider.ts @@ -1,5 +1,6 @@ +import pino from "pino"; import { TaxBaseFragment } from "../../../generated/graphql"; -import { logger } from "../../lib/logger"; +import { createLogger } from "../../lib/logger"; import { ChannelConfig } from "../channels-configuration/channels-config"; import { TaxProvider } from "../taxes/tax-provider"; import { avataxCalculate } from "./avatax-calculate"; @@ -10,21 +11,24 @@ export class AvataxProvider implements TaxProvider { readonly name = "avatax"; config = defaultAvataxConfig; client: AvataxClient; + private logger: pino.Logger; constructor(config: AvataxConfig) { + this.logger = createLogger({ + service: "AvataxProvider", + }); const avataxClient = new AvataxClient(config); - logger.info({ client: avataxClient }, "Internal Avatax client created"); + this.logger.trace({ client: avataxClient }, "Internal Avatax client created"); this.config = config; this.client = avataxClient; } async calculate(payload: TaxBaseFragment, channel: ChannelConfig) { - logger.info("Avatax calculate"); + this.logger.debug({ payload, channel }, "Avatax calculate called with:"); const model = avataxCalculate.preparePayload(payload, channel, this.config); - logger.info(model, "Payload used for Avatax fetchTaxesForOrder"); const result = await this.client.fetchTaxesForOrder(model); - logger.info({ createOrderTransaction: result }, "Avatax createOrderTransaction response"); + this.logger.debug({ createOrderTransaction: result }, "Avatax createOrderTransaction response"); return avataxCalculate.prepareResponse(result); } } diff --git a/apps/taxes/src/modules/channels-configuration/channels-config.ts b/apps/taxes/src/modules/channels-configuration/channels-config.ts index 63b61d8..f11a3e9 100644 --- a/apps/taxes/src/modules/channels-configuration/channels-config.ts +++ b/apps/taxes/src/modules/channels-configuration/channels-config.ts @@ -9,7 +9,7 @@ export const channelSchema = z.object({ }); export type ChannelConfig = z.infer; -const channelsSchema = z.record(channelSchema); +export const channelsSchema = z.record(channelSchema); export type ChannelsConfig = z.infer; export const defaultChannelConfig: ChannelConfig = { diff --git a/apps/taxes/src/modules/channels-configuration/channels-configuration.router.ts b/apps/taxes/src/modules/channels-configuration/channels-configuration.router.ts index 7f9d7db..d9d7bff 100644 --- a/apps/taxes/src/modules/channels-configuration/channels-configuration.router.ts +++ b/apps/taxes/src/modules/channels-configuration/channels-configuration.router.ts @@ -7,9 +7,13 @@ import { setAndReplaceChannelsInputSchema } from "./channels-config-input-schema import { TaxChannelsConfigurator } from "./channels-configurator"; import { GetChannelsConfigurationService } from "./get-channels-configuration.service"; +// todo: refactor with crud-settings export const channelsConfigurationRouter = router({ fetch: protectedClientProcedure.query(async ({ ctx, input }) => { - const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl }); + const logger = pinoLogger.child({ + saleorApiUrl: ctx.saleorApiUrl, + procedure: "channelsConfigurationRouter.fetch", + }); logger.debug("channelsConfigurationRouter.fetch called"); @@ -21,14 +25,17 @@ export const channelsConfigurationRouter = router({ upsert: protectedClientProcedure .input(setAndReplaceChannelsInputSchema) .mutation(async ({ ctx, input }) => { - const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl }); - logger.info(input, "channelsConfigurationRouter.upsert called with input"); + const logger = pinoLogger.child({ + saleorApiUrl: ctx.saleorApiUrl, + procedure: "channelsConfigurationRouter.upsert", + }); + logger.debug(input, "channelsConfigurationRouter.upsert called with input"); const config = await new GetChannelsConfigurationService({ apiClient: ctx.apiClient, saleorApiUrl: ctx.saleorApiUrl, }).getConfiguration(); - logger.info(config, "Fetched current channels config to update it"); + logger.debug(config, "Fetched current channels config to update it"); const taxChannelsConfigurator = new TaxChannelsConfigurator( createSettingsManager(ctx.apiClient), @@ -43,7 +50,7 @@ export const channelsConfigurationRouter = router({ }, }; - logger.info(channelsConfig, "Merged configs. Will set it now"); + logger.debug(channelsConfig, "Merged configs. Will set it now"); await taxChannelsConfigurator.setConfig(channelsConfig); diff --git a/apps/taxes/src/modules/channels-configuration/get-channels-configuration.service.ts b/apps/taxes/src/modules/channels-configuration/get-channels-configuration.service.ts index 0ebdb67..35ef53a 100644 --- a/apps/taxes/src/modules/channels-configuration/get-channels-configuration.service.ts +++ b/apps/taxes/src/modules/channels-configuration/get-channels-configuration.service.ts @@ -1,8 +1,6 @@ import { Client } from "urql"; import { logger as pinoLogger } from "../../lib/logger"; import { createSettingsManager } from "../app-configuration/metadata-manager"; -import { ChannelsFetcher } from "../channels/channels-fetcher"; -import { createDefaultChannelsConfig } from "./channels-config"; import { TaxChannelsConfigurator } from "./channels-configurator"; export class GetChannelsConfigurationService { @@ -26,17 +24,11 @@ export class GetChannelsConfigurationService { saleorApiUrl ); - const channelsFetcher = new ChannelsFetcher(apiClient); - const channels = await channelsFetcher.fetchChannels(); - logger.info({ channels }, "Fetched Saleor channels that use TAX_APP for tax calculation"); - const defaultConfig = createDefaultChannelsConfig(channels ?? []); - logger.info({ defaultConfig }, "Generated config from Saleor channels"); - // todo: validate config const appChannelsConfig = (await taxConfigurator.getConfig()) ?? null; logger.debug(appChannelsConfig, "Retrieved channels config from Metadata"); - return { ...defaultConfig, ...appChannelsConfig }; + return { ...appChannelsConfig }; } } diff --git a/apps/taxes/src/modules/crud-settings/crud-settings.service.ts b/apps/taxes/src/modules/crud-settings/crud-settings.service.ts index ccdfa26..130d759 100644 --- a/apps/taxes/src/modules/crud-settings/crud-settings.service.ts +++ b/apps/taxes/src/modules/crud-settings/crud-settings.service.ts @@ -20,11 +20,11 @@ export class CrudSettingsConfigurator { } async readAll() { - this.logger.debug(".readAll called"); + this.logger.trace(".readAll called"); const result = await this.metadataManager.get(this.metadataKey, this.saleorApiUrl); if (!result) { - this.logger.debug("No metadata found"); + this.logger.trace("No metadata found"); return { data: [] }; } @@ -42,7 +42,7 @@ export class CrudSettingsConfigurator { } async read(id: string) { - this.logger.debug(".read called"); + this.logger.trace(".read called"); const result = await this.readAll(); const { data: settings } = result; @@ -58,7 +58,7 @@ export class CrudSettingsConfigurator { } async create(data: any) { - this.logger.debug(data, ".create called with:"); + this.logger.trace(data, ".create called with:"); const settings = await this.readAll(); const prevData = settings.data; @@ -77,7 +77,7 @@ export class CrudSettingsConfigurator { } async delete(id: string) { - this.logger.debug(`.delete called with: ${id}`); + this.logger.trace(`.delete called with: ${id}`); const settings = await this.readAll(); const prevData = settings.data; @@ -91,7 +91,7 @@ export class CrudSettingsConfigurator { } async update(id: string, data: any) { - this.logger.debug(data, `.update called with: ${id}`); + this.logger.trace(data, `.update called with: ${id}`); const { data: settings } = await this.readAll(); const nextData = settings.map((item) => { if (item.id === id) { diff --git a/apps/taxes/src/modules/providers-configuration/providers-configuration.router.ts b/apps/taxes/src/modules/providers-configuration/providers-configuration.router.ts index d119b54..ef63877 100644 --- a/apps/taxes/src/modules/providers-configuration/providers-configuration.router.ts +++ b/apps/taxes/src/modules/providers-configuration/providers-configuration.router.ts @@ -5,7 +5,10 @@ import { PublicTaxProvidersConfigurationService } from "./public-providers-confi export const providersConfigurationRouter = router({ getAll: protectedClientProcedure.query(async ({ ctx }) => { - const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl }); + const logger = pinoLogger.child({ + saleorApiUrl: ctx.saleorApiUrl, + procedure: "providersConfigurationRouter.getAll", + }); logger.debug("providersConfigurationRouter.fetch called"); diff --git a/apps/taxes/src/modules/taxes/active-tax-provider.ts b/apps/taxes/src/modules/taxes/active-tax-provider.ts index 4ccc0e0..7fe233a 100644 --- a/apps/taxes/src/modules/taxes/active-tax-provider.ts +++ b/apps/taxes/src/modules/taxes/active-tax-provider.ts @@ -6,15 +6,19 @@ import { AvataxProvider } from "../avatax/avatax-provider"; import { TaxJarProvider } from "../taxjar/taxjar-provider"; import { TaxProvider } from "./tax-provider"; import { TaxProviderError } from "./tax-provider-error"; +import pino from "pino"; export class ActiveTaxProvider { private client: TaxProvider; + private logger: pino.Logger; constructor(providerInstance: ProviderConfig) { - const logger = createLogger({}); + this.logger = createLogger({ + service: "ActiveTaxProvider", + }); const taxProviderName = providerInstance.provider; - logger.info({ taxProviderName }, "Constructing tax provider: "); + this.logger.trace({ taxProviderName }, "Constructing tax provider: "); switch (taxProviderName) { case "taxjar": @@ -34,6 +38,8 @@ export class ActiveTaxProvider { } async calculate(payload: TaxBaseFragment, channel: ChannelConfig) { + this.logger.debug({ payload, channel }, ".calculate called"); + return this.client.calculate(payload, channel); } } diff --git a/apps/taxes/src/modules/taxes/tax-provider.ts b/apps/taxes/src/modules/taxes/tax-provider.ts index 7600741..bede921 100644 --- a/apps/taxes/src/modules/taxes/tax-provider.ts +++ b/apps/taxes/src/modules/taxes/tax-provider.ts @@ -1,9 +1,7 @@ import { TaxBaseFragment } from "../../../generated/graphql"; -import { ResponseTaxPayload } from "./types"; import { ChannelConfig } from "../channels-configuration/channels-config"; import { TaxProviderName } from "./providers/config"; - -type ExternalValidationResult = { ok: boolean; error?: string }; +import { ResponseTaxPayload } from "./types"; export interface TaxProvider { name: TaxProviderName; diff --git a/apps/taxes/src/modules/taxjar/taxjar-client.ts b/apps/taxes/src/modules/taxjar/taxjar-client.ts index 1cafc4b..4cf7ada 100644 --- a/apps/taxes/src/modules/taxjar/taxjar-client.ts +++ b/apps/taxes/src/modules/taxjar/taxjar-client.ts @@ -1,6 +1,7 @@ +import pino from "pino"; import TaxJar from "taxjar"; import { Config, TaxForOrderRes, TaxParams } from "taxjar/dist/util/types"; -import { logger } from "../../lib/logger"; +import { createLogger } from "../../lib/logger"; import { TaxJarConfig } from "./taxjar-config"; const createTaxJarSettings = (config: TaxJarConfig): Config => { @@ -14,21 +15,25 @@ const createTaxJarSettings = (config: TaxJarConfig): Config => { export class TaxJarClient { private client: TaxJar; + private logger: pino.Logger; constructor(providerConfig: TaxJarConfig) { - logger.debug("TaxJarClient constructor"); + this.logger = createLogger({ service: "TaxJarClient" }); + this.logger.trace("TaxJarClient constructor"); const settings = createTaxJarSettings(providerConfig); const taxJarClient = new TaxJar(settings); - logger.info({ client: taxJarClient }, "External TaxJar client created"); + this.logger.trace({ client: taxJarClient }, "External TaxJar client created"); this.client = taxJarClient; } async fetchTaxesForOrder(params: TaxParams) { + this.logger.debug({ params }, "fetchTaxesForOrder called with:"); const response: TaxForOrderRes = await this.client.taxForOrder(params); return response; } async ping() { + this.logger.debug("ping called"); try { await this.client.categories(); return { authenticated: true }; diff --git a/apps/taxes/src/modules/taxjar/taxjar-configuration.router.ts b/apps/taxes/src/modules/taxjar/taxjar-configuration.router.ts index 38d55d5..6e94c29 100644 --- a/apps/taxes/src/modules/taxjar/taxjar-configuration.router.ts +++ b/apps/taxes/src/modules/taxjar/taxjar-configuration.router.ts @@ -43,8 +43,8 @@ export const taxjarConfigurationRouter = router({ const result = await taxjarConfigurationService.get(input.id); - logger.debug({ result }, "taxjarConfigurationRouter.get finished"); - + // * `providerInstance` name is required for secrets censorship + logger.debug({ providerInstance: result }, "taxjarConfigurationRouter.get finished"); return { ...result, config: obfuscateTaxJarConfig(result.config) }; }), post: protectedClientProcedure.input(postInputSchema).mutation(async ({ ctx, input }) => { diff --git a/apps/taxes/src/modules/taxjar/taxjar-configuration.service.ts b/apps/taxes/src/modules/taxjar/taxjar-configuration.service.ts index d543d93..6134f79 100644 --- a/apps/taxes/src/modules/taxjar/taxjar-configuration.service.ts +++ b/apps/taxes/src/modules/taxjar/taxjar-configuration.service.ts @@ -29,7 +29,7 @@ export class TaxJarConfigurationService { async getAll(): Promise { this.logger.debug(".getAll called"); const { data } = await this.crudSettingsConfigurator.readAll(); - this.logger.debug({ settings: data }, `Fetched settings from crudSettingsConfigurator`); + this.logger.debug(`Fetched settings from crudSettingsConfigurator`); const validation = providersSchema.safeParse(data); if (!validation.success) { @@ -47,7 +47,7 @@ export class TaxJarConfigurationService { async get(id: string): Promise { this.logger.debug(`.get called with id: ${id}`); const { data } = await this.crudSettingsConfigurator.read(id); - this.logger.debug({ setting: data }, `Fetched setting from crudSettingsConfigurator`); + this.logger.debug(`Fetched setting from crudSettingsConfigurator`); const validation = getSchema.safeParse(data); diff --git a/apps/taxes/src/modules/taxjar/taxjar-provider.ts b/apps/taxes/src/modules/taxjar/taxjar-provider.ts index 495f264..cbb7d7a 100644 --- a/apps/taxes/src/modules/taxjar/taxjar-provider.ts +++ b/apps/taxes/src/modules/taxjar/taxjar-provider.ts @@ -1,35 +1,36 @@ +import pino from "pino"; import { TaxBaseFragment } from "../../../generated/graphql"; -import { logger } from "../../lib/logger"; -import { ChannelConfig, defaultChannelConfig } from "../channels-configuration/channels-config"; +import { createLogger } from "../../lib/logger"; +import { ChannelConfig } from "../channels-configuration/channels-config"; import { TaxProvider } from "../taxes/tax-provider"; import { taxJarCalculate } from "./taxjar-calculate"; import { TaxJarClient } from "./taxjar-client"; -import { defaultTaxJarConfig, TaxJarConfig } from "./taxjar-config"; +import { TaxJarConfig } from "./taxjar-config"; export class TaxJarProvider implements TaxProvider { - readonly name = "taxjar"; - config = defaultTaxJarConfig; - channel = defaultChannelConfig; client: TaxJarClient; + readonly name = "taxjar"; + private logger: pino.Logger; constructor(config: TaxJarConfig) { const avataxClient = new TaxJarClient(config); - this.config = config; this.client = avataxClient; + this.logger = createLogger({ + service: "TaxJarProvider", + }); } async calculate(payload: TaxBaseFragment, channel: ChannelConfig) { - logger.info("TaxJar calculate"); + this.logger.debug({ payload, channel }, "TaxJar calculate called with:"); const linesWithDiscount = taxJarCalculate.prepareLinesWithDiscountPayload( payload.lines, payload.discounts ); const linesWithChargeTaxes = linesWithDiscount.filter((line) => line.chargeTaxes === true); const taxParams = taxJarCalculate.preparePayload(payload, channel, linesWithDiscount); - logger.info(taxParams, "Payload used for TaxJar fetchTaxesForOrder"); const fetchedTaxes = await this.client.fetchTaxesForOrder(taxParams); - logger.info({ fetchedTaxes }, "TaxJar createOrderTransaction response"); + this.logger.debug({ fetchedTaxes }, "TaxJar createOrderTransaction response"); return taxJarCalculate.prepareResponse( payload, diff --git a/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts b/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts index 20e2029..09d1933 100644 --- a/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts +++ b/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts @@ -1,11 +1,9 @@ import { SaleorSyncWebhook } from "@saleor/app-sdk/handlers/next"; import { UntypedCalculateTaxesDocument } from "../../../../generated/graphql"; import { saleorApp } from "../../../../saleor-app"; -import { createClient } from "../../../lib/graphql"; import { createLogger } from "../../../lib/logger"; import { calculateTaxesPayloadSchema, ExpectedWebhookPayload } from "../../../lib/saleor/schema"; -import { GetChannelsConfigurationService } from "../../../modules/channels-configuration/get-channels-configuration.service"; -import { PrivateTaxProvidersConfigurationService } from "../../../modules/providers-configuration/private-providers-configuration-service"; +import { getAppConfig } from "../../../modules/app-configuration/get-app-config"; import { ActiveTaxProvider } from "../../../modules/taxes/active-tax-provider"; @@ -25,7 +23,7 @@ export const checkoutCalculateTaxesSyncWebhook = new SaleorSyncWebhook { const logger = createLogger({ event: ctx.event }); - const { authData, payload } = ctx; + const { payload } = ctx; logger.info({ payload }, "Handler called with payload"); const validation = calculateTaxesPayloadSchema.safeParse(payload); @@ -37,27 +35,14 @@ export default checkoutCalculateTaxesSyncWebhook.createHandler(async (req, res, } const { data } = validation; - logger.info({ data }, "Payload is valid."); + logger.info("Payload validated succesfully"); + + const { providers, channels } = getAppConfig(data); + logger.debug("Successfully parsed providers & channels from payload"); try { - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); - - const providersConfig = await new PrivateTaxProvidersConfigurationService( - client, - authData.saleorApiUrl - ).getAll(); - - const channelsConfig = await new GetChannelsConfigurationService({ - saleorApiUrl: authData.saleorApiUrl, - apiClient: client, - }).getConfiguration(); - - logger.info({ providersConfig }, "Providers configuration returned"); - - const channelSlug = payload.taxBase.channel.slug; - const channelConfig = channelsConfig[channelSlug]; + const channelSlug = data.taxBase.channel.slug; + const channelConfig = channels[channelSlug]; if (!channelConfig) { logger.error(`Channel config not found for channel ${channelSlug}`); @@ -65,7 +50,7 @@ export default checkoutCalculateTaxesSyncWebhook.createHandler(async (req, res, return res.send({}); } - const providerInstance = providersConfig.find( + const providerInstance = providers.find( (instance) => instance.id === channelConfig.providerInstanceId ); diff --git a/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts b/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts index 513eb7e..0f3d66a 100644 --- a/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts +++ b/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts @@ -1,11 +1,9 @@ import { SaleorSyncWebhook } from "@saleor/app-sdk/handlers/next"; import { UntypedCalculateTaxesDocument } from "../../../../generated/graphql"; import { saleorApp } from "../../../../saleor-app"; -import { createClient } from "../../../lib/graphql"; import { createLogger } from "../../../lib/logger"; import { calculateTaxesPayloadSchema, ExpectedWebhookPayload } from "../../../lib/saleor/schema"; -import { GetChannelsConfigurationService } from "../../../modules/channels-configuration/get-channels-configuration.service"; -import { PrivateTaxProvidersConfigurationService } from "../../../modules/providers-configuration/private-providers-configuration-service"; +import { getAppConfig } from "../../../modules/app-configuration/get-app-config"; import { ActiveTaxProvider } from "../../../modules/taxes/active-tax-provider"; export const config = { @@ -24,7 +22,7 @@ export const orderCalculateTaxesSyncWebhook = new SaleorSyncWebhook { const logger = createLogger({ event: ctx.event }); - const { authData, payload } = ctx; + const { payload } = ctx; logger.info({ payload }, "Handler called with payload"); const validation = calculateTaxesPayloadSchema.safeParse(payload); @@ -36,26 +34,14 @@ export default orderCalculateTaxesSyncWebhook.createHandler(async (req, res, ctx } const { data } = validation; - logger.info({ data }, "Payload is valid."); + logger.info("Payload validated succesfully"); + + const { providers, channels } = getAppConfig(data); + logger.debug("Parsed providers & channels from payload"); try { - const client = createClient(authData.saleorApiUrl, async () => - Promise.resolve({ token: authData.token }) - ); - const providersConfig = await new PrivateTaxProvidersConfigurationService( - client, - authData.saleorApiUrl - ).getAll(); - - const channelsConfig = await new GetChannelsConfigurationService({ - saleorApiUrl: authData.saleorApiUrl, - apiClient: client, - }).getConfiguration(); - - logger.info({ providersConfig }, "Providers configuration returned"); - - const channelSlug = payload.taxBase.channel.slug; - const channelConfig = channelsConfig[channelSlug]; + const channelSlug = data.taxBase.channel.slug; + const channelConfig = channels[channelSlug]; if (!channelConfig) { logger.error(`Channel config not found for channel ${channelSlug}`); @@ -63,7 +49,7 @@ export default orderCalculateTaxesSyncWebhook.createHandler(async (req, res, ctx return res.send({}); } - const providerInstance = providersConfig.find( + const providerInstance = providers.find( (instance) => instance.id === channelConfig.providerInstanceId );