From 97735d06332d78327567abd3ead2f179eefa9921 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 18 Dec 2023 16:08:36 +0800 Subject: [PATCH 1/2] make existing newsletters go to inbox folder --- packages/api/src/entity/newsletter_email.ts | 5 ++- packages/api/src/entity/subscription.ts | 4 ++- .../api/src/resolvers/function_resolvers.ts | 14 +++++++- .../api/src/resolvers/newsletters/index.ts | 34 +++++++++++-------- .../api/src/resolvers/subscriptions/index.ts | 9 +++-- .../api/src/services/save_newsletter_email.ts | 10 ++++-- packages/api/src/utils/createTask.ts | 1 + ....remove_default_folder_in_subscription.sql | 14 ++++++++ ....remove_default_folder_in_subscription.sql | 7 ++++ 9 files changed, 75 insertions(+), 23 deletions(-) create mode 100755 packages/db/migrations/0150.do.remove_default_folder_in_subscription.sql create mode 100755 packages/db/migrations/0150.undo.remove_default_folder_in_subscription.sql diff --git a/packages/api/src/entity/newsletter_email.ts b/packages/api/src/entity/newsletter_email.ts index 312cc6b14..901553dc7 100644 --- a/packages/api/src/entity/newsletter_email.ts +++ b/packages/api/src/entity/newsletter_email.ts @@ -11,6 +11,9 @@ import { import { User } from './user' import { Subscription } from './subscription' +export const DEFAULT_NEWSLETTER_FOLDER = 'following' +export const EXISTING_NEWSLETTER_FOLDER = 'inbox' + @Entity({ name: 'newsletter_emails' }) export class NewsletterEmail { @PrimaryGeneratedColumn('uuid') @@ -36,7 +39,7 @@ export class NewsletterEmail { subscriptions!: Subscription[] @Column('text') - folder!: string + folder?: string | null @Column('text') name?: string | null diff --git a/packages/api/src/entity/subscription.ts b/packages/api/src/entity/subscription.ts index 2b240e8e5..e1b8da23b 100644 --- a/packages/api/src/entity/subscription.ts +++ b/packages/api/src/entity/subscription.ts @@ -11,6 +11,8 @@ import { SubscriptionStatus, SubscriptionType } from '../generated/graphql' import { NewsletterEmail } from './newsletter_email' import { User } from './user' +export const DEFAULT_SUBSCRIPTION_FOLDER = 'following' + @Entity({ name: 'subscriptions' }) export class Subscription { @PrimaryGeneratedColumn('uuid') @@ -81,5 +83,5 @@ export class Subscription { fetchContent!: boolean @Column('text') - folder!: string + folder?: string | null } diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index 398ac284c..a75385689 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -4,7 +4,11 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { createHmac } from 'crypto' -import { Subscription } from '../entity/subscription' +import { NewsletterEmail } from '../entity/newsletter_email' +import { + DEFAULT_SUBSCRIPTION_FOLDER, + Subscription, +} from '../entity/subscription' import { env } from '../env' import { Article, @@ -438,6 +442,14 @@ export const functionResolvers = { subscription.icon && createImageProxyUrl(subscription.icon, 128, 128) ) }, + folder(subscription: { folder?: string | null }) { + return subscription.folder || DEFAULT_SUBSCRIPTION_FOLDER + }, + }, + NewsletterEmail: { + subscriptionCount(newsletterEmail: NewsletterEmail) { + return newsletterEmail.subscriptions?.length || 0 + }, }, ...resultResolveTypeResolver('Login'), ...resultResolveTypeResolver('LogOut'), diff --git a/packages/api/src/resolvers/newsletters/index.ts b/packages/api/src/resolvers/newsletters/index.ts index 8e1e4ec9a..6672b4ea4 100644 --- a/packages/api/src/resolvers/newsletters/index.ts +++ b/packages/api/src/resolvers/newsletters/index.ts @@ -20,11 +20,16 @@ import { getNewsletterEmails, } from '../../services/newsletters' import { unsubscribeAll } from '../../services/subscriptions' +import { Merge } from '../../util' import { analytics } from '../../utils/analytics' import { authorized } from '../../utils/helpers' -export const createNewsletterEmailResolver = authorized< +export type CreateNewsletterEmailSuccessPartial = Merge< CreateNewsletterEmailSuccess, + { newsletterEmail: NewsletterEmail } +> +export const createNewsletterEmailResolver = authorized< + CreateNewsletterEmailSuccessPartial, CreateNewsletterEmailError, MutationCreateNewsletterEmailArgs >(async (_parent, { input }, { claims, log }) => { @@ -47,10 +52,7 @@ export const createNewsletterEmailResolver = authorized< ) return { - newsletterEmail: { - ...newsletterEmail, - subscriptionCount: 0, - }, + newsletterEmail, } } catch (e) { log.error('createNewsletterEmailResolver', e) @@ -61,18 +63,19 @@ export const createNewsletterEmailResolver = authorized< } }) -export const newsletterEmailsResolver = authorized< +export type NewsletterEmailsSuccessPartial = Merge< NewsletterEmailsSuccess, + { newsletterEmails: NewsletterEmail[] } +> +export const newsletterEmailsResolver = authorized< + NewsletterEmailsSuccessPartial, NewsletterEmailsError >(async (_parent, _args, { uid, log }) => { try { const newsletterEmails = await getNewsletterEmails(uid) return { - newsletterEmails: newsletterEmails.map((newsletterEmail) => ({ - ...newsletterEmail, - subscriptionCount: newsletterEmail.subscriptions.length, - })), + newsletterEmails, } } catch (e) { log.error('newsletterEmailsResolver', e) @@ -83,8 +86,12 @@ export const newsletterEmailsResolver = authorized< } }) -export const deleteNewsletterEmailResolver = authorized< +export type DeleteNewsletterEmailSuccessPartial = Merge< DeleteNewsletterEmailSuccess, + { newsletterEmail: NewsletterEmail } +> +export const deleteNewsletterEmailResolver = authorized< + DeleteNewsletterEmailSuccessPartial, DeleteNewsletterEmailError, MutationDeleteNewsletterEmailArgs >(async (_parent, args, { uid, log }) => { @@ -117,10 +124,7 @@ export const deleteNewsletterEmailResolver = authorized< const deleted = await deleteNewsletterEmail(args.newsletterEmailId) if (deleted) { return { - newsletterEmail: { - ...newsletterEmail, - subscriptionCount: newsletterEmail.subscriptions.length, - }, + newsletterEmail, } } else { // when user tries to delete other's newsletters emails or email already deleted diff --git a/packages/api/src/resolvers/subscriptions/index.ts b/packages/api/src/resolvers/subscriptions/index.ts index 6489e80c7..120dedc95 100644 --- a/packages/api/src/resolvers/subscriptions/index.ts +++ b/packages/api/src/resolvers/subscriptions/index.ts @@ -1,7 +1,10 @@ import axios from 'axios' import { parseHTML } from 'linkedom' import { Brackets } from 'typeorm' -import { Subscription } from '../../entity/subscription' +import { + DEFAULT_SUBSCRIPTION_FOLDER, + Subscription, +} from '../../entity/subscription' import { env } from '../../env' import { FeedEdge, @@ -221,7 +224,7 @@ export const subscribeResolver = authorized< fetchedDates: [updatedSubscription.lastFetchedAt || null], checksums: [updatedSubscription.lastFetchedChecksum || null], fetchContents: [updatedSubscription.fetchContent], - folders: [updatedSubscription.folder], + folders: [updatedSubscription.folder || DEFAULT_SUBSCRIPTION_FOLDER], }) return { @@ -278,7 +281,7 @@ export const subscribeResolver = authorized< fetchedDates: [null], checksums: [null], fetchContents: [newSubscription.fetchContent], - folders: [newSubscription.folder], + folders: [newSubscription.folder || DEFAULT_SUBSCRIPTION_FOLDER], }) return { diff --git a/packages/api/src/services/save_newsletter_email.ts b/packages/api/src/services/save_newsletter_email.ts index 4b6ca70b0..8bbde8820 100644 --- a/packages/api/src/services/save_newsletter_email.ts +++ b/packages/api/src/services/save_newsletter_email.ts @@ -1,4 +1,7 @@ -import { NewsletterEmail } from '../entity/newsletter_email' +import { + EXISTING_NEWSLETTER_FOLDER, + NewsletterEmail, +} from '../entity/newsletter_email' import { Subscription } from '../entity/subscription' import { env } from '../env' import { analytics } from '../utils/analytics' @@ -49,7 +52,10 @@ export const saveNewsletter = async ( } // subscription's folder takes precedence over newsletter email's folder - const folder = existingSubscription?.folder || newsletterEmail.folder + const folder = + existingSubscription?.folder || + newsletterEmail.folder || + EXISTING_NEWSLETTER_FOLDER const input: SaveEmailInput = { userId: newsletterEmail.user.id, diff --git a/packages/api/src/utils/createTask.ts b/packages/api/src/utils/createTask.ts index bbf901e2e..7e332c967 100644 --- a/packages/api/src/utils/createTask.ts +++ b/packages/api/src/utils/createTask.ts @@ -8,6 +8,7 @@ import { nanoid } from 'nanoid' import { DeepPartial } from 'typeorm' import { ImportItemState } from '../entity/integration' import { Recommendation } from '../entity/recommendation' +import { DEFAULT_SUBSCRIPTION_FOLDER } from '../entity/subscription' import { env } from '../env' import { ArticleSavingRequestStatus, diff --git a/packages/db/migrations/0150.do.remove_default_folder_in_subscription.sql b/packages/db/migrations/0150.do.remove_default_folder_in_subscription.sql new file mode 100755 index 000000000..2c0032d37 --- /dev/null +++ b/packages/db/migrations/0150.do.remove_default_folder_in_subscription.sql @@ -0,0 +1,14 @@ +-- Type: DO +-- Name: remove_default_folder_in_subscription +-- Description: Remove default value of folder column in subscriptions and newsletter_emails tables + +BEGIN; + +-- Drop the column first because we can't remove the default value of an existing column +ALTER TABLE omnivore.subscriptions DROP COLUMN folder; +ALTER TABLE omnivore.newsletter_emails DROP COLUMN folder; + +ALTER TABLE omnivore.subscriptions ADD COLUMN folder TEXT; +ALTER TABLE omnivore.newsletter_emails ADD COLUMN folder TEXT; + +COMMIT; diff --git a/packages/db/migrations/0150.undo.remove_default_folder_in_subscription.sql b/packages/db/migrations/0150.undo.remove_default_folder_in_subscription.sql new file mode 100755 index 000000000..cb620fa2a --- /dev/null +++ b/packages/db/migrations/0150.undo.remove_default_folder_in_subscription.sql @@ -0,0 +1,7 @@ +-- Type: UNDO +-- Name: remove_default_folder_in_subscription +-- Description: Remove default value of folder column in subscriptions and newsletter_emails tables + +BEGIN; + +COMMIT; From 55ed5a0a80b618b29a0caa03ba7d80e3c469b1b3 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 18 Dec 2023 16:20:40 +0800 Subject: [PATCH 2/2] fix typo --- packages/api/src/resolvers/newsletters/index.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/api/src/resolvers/newsletters/index.ts b/packages/api/src/resolvers/newsletters/index.ts index 6672b4ea4..34b887dea 100644 --- a/packages/api/src/resolvers/newsletters/index.ts +++ b/packages/api/src/resolvers/newsletters/index.ts @@ -1,4 +1,7 @@ -import { NewsletterEmail } from '../../entity/newsletter_email' +import { + DEFAULT_NEWSLETTER_FOLDER, + NewsletterEmail, +} from '../../entity/newsletter_email' import { env } from '../../env' import { CreateNewsletterEmailError, @@ -46,7 +49,7 @@ export const createNewsletterEmailResolver = authorized< const newsletterEmail = await createNewsletterEmail( claims.uid, undefined, - input?.folder || 'following', + input?.folder || DEFAULT_NEWSLETTER_FOLDER, input?.name || undefined, input?.description || undefined )