UNPKG

@accounter/server

Version:

The test suite is split into three Vitest projects for efficiency and isolation:

110 lines (98 loc) 3.36 kB
import DataLoader from 'dataloader'; import { format } from 'date-fns'; import { Injectable, Scope } from 'graphql-modules'; import { sql } from '@pgtyped/runtime'; import { getCacheInstance } from '../../../shared/helpers/index.js'; import { DBProvider } from '../../app-providers/db.provider.js'; import { IGetReportByBusinessIdAndDatesQuery, IInsertReportParams, IInsertReportQuery, IUpdateReportParams, IUpdateReportQuery, } from '../types.js'; const getReportByBusinessIdAndDates = sql<IGetReportByBusinessIdAndDatesQuery>` SELECT * FROM accounter_schema.pcn874 WHERE business_id = $businessId AND month_date IN $$monthDates;`; const updateReport = sql<IUpdateReportQuery>` UPDATE accounter_schema.pcn874 SET content = $content WHERE business_id = $businessId AND month_date = $monthDate RETURNING *;`; const insertReport = sql<IInsertReportQuery>` INSERT INTO accounter_schema.pcn874 (business_id, month_date, content) VALUES ($businessId, $monthDate, $content) RETURNING *;`; @Injectable({ scope: Scope.Singleton, global: true, }) export class VatReportProvider { cache = getCacheInstance({ stdTTL: 60 * 60 * 5, }); constructor(private dbProvider: DBProvider) {} private async batchReportsByBusinessIdAndMonthDatesLoader( businessAndDates: readonly [string, string][], ) { const businessIdsMap = new Map<string, Set<string>>(); businessAndDates.map(([businessId, monthDate]) => { if (businessIdsMap.has(businessId)) { businessIdsMap.get(businessId)?.add(monthDate); } else { businessIdsMap.set(businessId, new Set<string>([monthDate])); } }); const reports = ( await Promise.all( Array.from(businessIdsMap.entries()).map(async ([businessId, monthDates]) => getReportByBusinessIdAndDates.run( { businessId, monthDates: Array.from(monthDates) }, this.dbProvider, ), ), ) ).flat(); return businessAndDates.map( ([businessId, monthDate]) => reports.find( report => report.business_id === businessId && format(report.month_date, 'yyyy-MM-dd') === monthDate, )?.content, ); } public getReportByBusinessIdAndMonthDateLoader = new DataLoader( (businessAndDates: readonly [string, string][]) => this.batchReportsByBusinessIdAndMonthDatesLoader(businessAndDates), { cacheKeyFn: ([businessId, monthDate]) => `pcn-${businessId}-${monthDate}`, cacheMap: this.cache, }, ); public async updateReport(params: IUpdateReportParams) { if (params.businessId && params.monthDate) { await this.invalidateByBusinessIdAndMonth( params.businessId, format(params.monthDate, 'yyyy-MM-dd'), ); } return updateReport.run(params, this.dbProvider); } public async insertReport(params: IInsertReportParams) { if (params.businessId && params.monthDate) { await this.invalidateByBusinessIdAndMonth( params.businessId, format(params.monthDate, 'yyyy-MM-dd'), ); } return insertReport.run(params, this.dbProvider); } public async invalidateByBusinessIdAndMonth(businessId: string, monthDate: string) { this.cache.delete(`pcn-${businessId}-${monthDate}`); } public clearCache() { this.cache.clear(); } }