From 5ed35bbeff5dfd985f5573698881c6fa260de02b Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 31 Jan 2024 13:32:37 +0800 Subject: [PATCH] create a job for update labels in library item --- packages/api/src/jobs/update_db.ts | 10 ++--- packages/api/src/queue-processor.ts | 9 ++--- packages/api/src/resolvers/labels/index.ts | 12 +++--- packages/api/src/services/labels.ts | 47 ++++++++++++++++++++-- packages/api/src/services/library_item.ts | 33 +++++++++++++++ packages/api/src/utils/createTask.ts | 25 +++++++----- 6 files changed, 103 insertions(+), 33 deletions(-) diff --git a/packages/api/src/jobs/update_db.ts b/packages/api/src/jobs/update_db.ts index 096111606..03e670b25 100644 --- a/packages/api/src/jobs/update_db.ts +++ b/packages/api/src/jobs/update_db.ts @@ -1,20 +1,18 @@ import { authTrx } from '../repository' -export const UPDATE_LABELS_IN_LIBRARY_ITEM_JOB = 'update-labels-in-library-item' +export const UPDATE_LABELS_JOB = 'update-labels' -export interface UpdateLabelsInLibraryItemData { +export interface UpdateLabelsData { libraryItemId: string userId: string } -export const updateLabelsInLibraryItem = async ( - data: UpdateLabelsInLibraryItemData -) => { +export const updateLabels = async (data: UpdateLabelsData) => { return authTrx( async (tx) => tx.query( `WITH labels_agg AS ( - SELECT array_agg(l.name) AS names_agg + SELECT array_agg(DISTINCT l.name) AS names_agg FROM omnivore.labels l INNER JOIN omnivore.entity_labels el ON el.label_id = l.id LEFT JOIN omnivore.highlight h ON h.id = el.highlight_id diff --git a/packages/api/src/queue-processor.ts b/packages/api/src/queue-processor.ts index c2379c432..f4458e53e 100644 --- a/packages/api/src/queue-processor.ts +++ b/packages/api/src/queue-processor.ts @@ -12,10 +12,7 @@ import { refreshAllFeeds } from './jobs/rss/refreshAllFeeds' import { refreshFeed } from './jobs/rss/refreshFeed' import { savePageJob } from './jobs/save_page' import { triggerRule, TRIGGER_RULE_JOB_NAME } from './jobs/trigger_rule' -import { - updateLabelsInLibraryItem, - UPDATE_LABELS_IN_LIBRARY_ITEM_JOB, -} from './jobs/update_db' +import { updateLabels, UPDATE_LABELS_JOB } from './jobs/update_db' import { updatePDFContentJob } from './jobs/update_pdf_content' import { redisDataSource } from './redis_data_source' import { CustomTypeOrmLogger } from './utils/logger' @@ -129,8 +126,8 @@ const main = async () => { return findThumbnail(job.data) case TRIGGER_RULE_JOB_NAME: return triggerRule(job.data) - case UPDATE_LABELS_IN_LIBRARY_ITEM_JOB: - return updateLabelsInLibraryItem(job.data) + case UPDATE_LABELS_JOB: + return updateLabels(job.data) } }, { diff --git a/packages/api/src/resolvers/labels/index.ts b/packages/api/src/resolvers/labels/index.ts index 6a6860940..cf9d6e3b6 100644 --- a/packages/api/src/resolvers/labels/index.ts +++ b/packages/api/src/resolvers/labels/index.ts @@ -31,6 +31,7 @@ import { import { labelRepository } from '../../repository/label' import { userRepository } from '../../repository/user' import { + deleteLabelById, findOrCreateLabels, saveLabelsInHighlight, saveLabelsInLibraryItem, @@ -118,13 +119,10 @@ export const deleteLabelResolver = authorized< DeleteLabelSuccess, DeleteLabelError, MutationDeleteLabelArgs ->(async (_, { id: labelId }, { authTrx, log, uid }) => { +>(async (_, { id: labelId }, { log, uid }) => { try { - const deleteResult = await authTrx(async (tx) => { - return tx.withRepository(labelRepository).deleteById(labelId) - }) - - if (!deleteResult.affected) { + const deleted = await deleteLabelById(labelId, uid) + if (!deleted) { return { errorCodes: [DeleteLabelErrorCode.NotFound], } @@ -281,7 +279,7 @@ export const setLabelsForHighlightResolver = authorized< } } - // save labels in the library item + // save labels in the highlight await saveLabelsInHighlight(labelsSet, input.highlightId, uid, pubsub) analytics.track({ diff --git a/packages/api/src/services/labels.ts b/packages/api/src/services/labels.ts index 03f9eec7b..d4d1aff16 100644 --- a/packages/api/src/services/labels.ts +++ b/packages/api/src/services/labels.ts @@ -5,8 +5,9 @@ import { Label } from '../entity/label' import { createPubSubClient, EntityType, PubsubClient } from '../pubsub' import { authTrx } from '../repository' import { CreateLabelInput, labelRepository } from '../repository/label' -import { enqueueUpdateLabelsInLibraryItem } from '../utils/createTask' +import { bulkEnqueueUpdateLabels } from '../utils/createTask' import { logger } from '../utils/logger' +import { findLibraryItemIdsByLabelId } from './library_item' type AddLabelsToLibraryItemEvent = { pageId: string @@ -124,8 +125,8 @@ export const saveLabelsInLibraryItem = async ( } // update labels in library item - const job = await enqueueUpdateLabelsInLibraryItem({ libraryItemId, userId }) - logger.info('update labels in library item job created', job) + const jobs = await bulkEnqueueUpdateLabels([{ libraryItemId, userId }]) + logger.info('update labels jobs enqueued', jobs) } export const addLabelsToLibraryItem = async ( @@ -151,6 +152,10 @@ export const addLabelsToLibraryItem = async ( undefined, userId ) + + // update labels in library item + const jobs = await bulkEnqueueUpdateLabels([{ libraryItemId, userId }]) + logger.info('update labels jobs enqueued', jobs) } export const saveLabelsInHighlight = async ( @@ -224,12 +229,33 @@ export const deleteLabels = async ( ) } +export const deleteLabelById = async (labelId: string, userId: string) => { + const libraryItemIds = await findLibraryItemIdsByLabelId(labelId, userId) + + const deleteResult = await authTrx(async (tx) => { + return tx.withRepository(labelRepository).deleteById(labelId) + }) + + if (!deleteResult.affected) { + return false + } + + const data = libraryItemIds.map((libraryItemId) => ({ + libraryItemId, + userId, + })) + const jobs = await bulkEnqueueUpdateLabels(data) + logger.info('update labels jobs enqueued', jobs) + + return true +} + export const updateLabel = async ( id: string, label: QueryDeepPartialEntity