import { DyFM_Error, DyFM_RelativeDate, DyFM_Time } from '@futdevpro/fsm-dynamo'; import { DyFM_DailyUsageData, DyFM_UsageData, DyFM_UsageSession, DyFM_usageSession_dataParams } from '@futdevpro/fsm-dynamo/usage'; import { Request } from 'express'; import { DyNTS_DataService } from '../../_services/base/data.service'; import { DyNTS_Shared } from '../../_services/shared.static-service'; import { DyNTS_global_settings } from '../../_collections/global-settings.const'; export class DyNTS_Usage_DataService extends DyNTS_DataService { usageData: DyFM_UsageData[] = []; simplifiedDailyUsage: DyFM_DailyUsageData[] = []; constructor( set: { usageSession?: DyFM_UsageSession, usageData?: DyFM_UsageData[], issuer: string, } ) { super( new DyFM_UsageSession(set?.usageSession), DyFM_usageSession_dataParams, set.issuer ); this.usageData = set?.usageData ?? []; } getLocationDataFromRequest(req: Request): void { try { this.data.address = DyNTS_Shared.getIpFromRequest(req); this.data.locationData = DyNTS_Shared.getLocationDataByRequest(req); /* console.log(`...getLocationDataFromRequest... ip: ${this.data.address}`, this.data.locationData); */ } catch (error) { throw new DyFM_Error({ ...this.getDefaultErrorSettings('getLocationDataFromRequest', error), errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-US0-GLD`, userMessage: `We were unable to deep analyze your request.`, }); } } async getUsage(range: DyFM_RelativeDate = DyFM_RelativeDate.lastWeek): Promise { try { await this.dataDBService.find({ sessionStart: { $gte: DyFM_Time.getDateByRelativeDate(range) }, }).then((res: DyFM_UsageSession[]): void => { this.dataList = res; }); this.simplifiedDailyUsage = []; this.dataList.forEach((session: DyFM_UsageSession): void => { let dateIndex = this.simplifiedDailyUsage.findIndex( (dailyData: DyFM_DailyUsageData): boolean => dailyData.date === session.date ); if (-1 < dateIndex) { this.simplifiedDailyUsage[dateIndex].visitations.push(session); } else { const newUsageSimple = new DyFM_DailyUsageData({ date: session.date, visitations: [ session ], }); this.simplifiedDailyUsage.push(newUsageSimple); dateIndex = this.simplifiedDailyUsage.length - 1; } if (session?.locationData?.country) { if (session.locationData.country === 'HU') { this.simplifiedDailyUsage[dateIndex].visitorsHun++; } else { this.simplifiedDailyUsage[dateIndex].visitorsElse++; } } this.simplifiedDailyUsage[dateIndex].totalVisitTime += session.totalSessionTime; this.simplifiedDailyUsage[dateIndex].averageVisitTime = Math.round( (this.simplifiedDailyUsage[dateIndex].totalVisitTime / this.simplifiedDailyUsage[dateIndex].visitations.length) * 100 ) / 100; }); this.simplifiedDailyUsage.sort( (a: DyFM_DailyUsageData, b: DyFM_DailyUsageData): number => +new Date(b.date) - +new Date(a.date) ); this.simplifiedDailyUsage.forEach((daily: DyFM_DailyUsageData): void => { daily.visitations.sort( (a: DyFM_UsageSession, b: DyFM_UsageSession): number => +a.sessionStart - +b.sessionStart ); }); } catch (error) { throw new DyFM_Error({ ...this.getDefaultErrorSettings('getLastWeekUsage', error), errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-US0-GLW`, userMessage: `We've failed to collect last week's usage data.`, }); } } async updateUsageData(req: Request): Promise { try { const data: DyFM_UsageSession = await this.getDataById(); if (!data) { throw new DyFM_Error({ ...this.getDefaultErrorSettings( 'updateUsageData', new Error('usage session NOT FOUND!') ), errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-US0-UU0`, userMessage: `The attempt to update Usage Data was unsuccessful.`, }); } data.usageData = this.usageData; let totalTime = 0; data.usageData.forEach((data: DyFM_UsageData): void => { totalTime += data.timeSpentOnPage; }); if (!data.locationData) { this.getLocationDataFromRequest(req); } data.totalSessionTime = totalTime; await this.saveData(data); } catch (error) { throw new DyFM_Error({ ...this.getDefaultErrorSettings('updateUsageData', error), errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-US0-UU0`, userMessage: `The attempt to update Usage Data was unsuccessful.`, }); } } async closeSession(req: Request): Promise { try { const data: DyFM_UsageSession = await this.getDataById(); if (!data) { throw new DyFM_Error({ ...this.getDefaultErrorSettings('closeSession', new Error('usage session NOT FOUND!')), errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-US0-CS0`, userMessage: `The attempt to close Usage Session was unsuccessful.`, }); } data.sessionEnd = new Date(); const newTotalSessionTime = +data.sessionEnd - +data.sessionStart; data.usageData[data.usageData.length - 1].timeSpentOnPage = newTotalSessionTime - data.totalSessionTime; if (!data.locationData) { this.getLocationDataFromRequest(req); } data.usageData.sort( (a: DyFM_UsageData, b: DyFM_UsageData): number => +a.opened - +b.opened ); data.totalSessionTime = newTotalSessionTime; await this.saveData(data); } catch (error) { throw new DyFM_Error({ ...this.getDefaultErrorSettings('closeSession', error), errorCode: `${DyNTS_global_settings.systemShortCodeName}|DyNTS-US0-CS0`, userMessage: `The attempt to close Usage Session was unsuccessful.`, }); } } }