import { Inject, Injectable, Logger } from '@nestjs/common'; import { RedmineTypes } from 'libs/redmine-types'; import nano from 'nano'; import { Subject } from 'rxjs'; import { SaveResponse } from './save-response'; @Injectable() export class RedmineIssuesCacheWriterService { private logger = new Logger(RedmineIssuesCacheWriterService.name); subject = new Subject(); constructor( @Inject('ISSUE_DOCUMENT_SCOPE') private issueDbProvider: () => Promise< nano.DocumentScope >, ) {} async saveIssue(issue: RedmineTypes.Issue): Promise { this.logger.debug( `Saving issue ${issue?.id || '-'} - ${ issue?.subject || '-' }, issue data = ${JSON.stringify(issue)}`, ); const id = Number(issue['id']); let prevIssue: (nano.DocumentGetResponse & RedmineTypes.Issue) | null; const issueDb = await this.issueDbProvider(); try { prevIssue = await issueDb.get(String(id)); } catch (ex) { prevIssue = null; } let newIssue: nano.DocumentGetResponse & RedmineTypes.Issue; if (!prevIssue) { newIssue = { ...(issue as any) }; newIssue._id = String(id); await issueDb.insert(newIssue); } else { newIssue = { ...(issue as any) }; newIssue._id = String(id); newIssue._rev = prevIssue._rev; await issueDb.insert(newIssue); } const res = { prev: prevIssue, current: newIssue, journalsDiff: this.getJournalsDiff(prevIssue, newIssue), }; this.logger.debug( `Saving issue success ${issue?.id || '-'} - ${issue?.subject || '-'}`, ); this.subject.next(res); return res; } getJournalsDiff( prev: (nano.DocumentGetResponse & RedmineTypes.Issue) | null, current: nano.DocumentGetResponse & RedmineTypes.Issue, ): RedmineTypes.Journal[] { if ( (!prev || !prev.journals || prev.journals.length === 0) && current?.journals ) { return current.journals; } else if (prev?.journals && current?.journals) { return this.calcJournalsDiff(prev?.journals, current?.journals); } return []; } private calcJournalsDiff( prev: RedmineTypes.Journal[], current: RedmineTypes.Journal[], ): RedmineTypes.Journal[] { const res: RedmineTypes.Journal[] = []; const prevIds = prev.map((item) => item.id); for (let i = 0; i < current.length; i++) { const currentItem = current[i]; if (!prevIds.includes(currentItem.id)) { res.push(currentItem); } } return res; } }