diff --git a/src/backend/services/article-cleanup-service.ts b/src/backend/services/article-cleanup-service.ts index 4c0d2f5..02beca7 100644 --- a/src/backend/services/article-cleanup-service.ts +++ b/src/backend/services/article-cleanup-service.ts @@ -2,6 +2,7 @@ import { and, lt, neq } from "sqlkit"; import { persistenceRepository } from "../persistence/persistence-repositories"; import { handleActionException } from "./RepositoryException"; +import { deleteArticleById } from "./search.service"; /** * Delete articles that have passed their scheduled deletion time @@ -10,6 +11,17 @@ export async function deleteExpiredArticles() { try { const currentTime = new Date(); + const articlesToDelete = await persistenceRepository.article.find({ + where: and( + neq("delete_scheduled_at", null), + lt("delete_scheduled_at", currentTime) + ), + }); + + for (const article of articlesToDelete) { + deleteArticleById(article.id); + } + const deleteResult = await persistenceRepository.article.delete({ where: and( neq("delete_scheduled_at", null), diff --git a/src/backend/services/article.actions.ts b/src/backend/services/article.actions.ts index 6129ae6..50d32a0 100644 --- a/src/backend/services/article.actions.ts +++ b/src/backend/services/article.actions.ts @@ -5,18 +5,19 @@ import { removeMarkdownSyntax, removeNullOrUndefinedFromObject, } from "@/lib/utils"; +import { addDays } from "date-fns"; import * as sk from "sqlkit"; import { and, desc, eq, like, neq, or } from "sqlkit"; import { z } from "zod"; +import { ActionResponse } from "../models/action-contracts"; import { Article, User } from "../models/domain-models"; import { DatabaseTableName } from "../persistence/persistence-contracts"; import { persistenceRepository } from "../persistence/persistence-repositories"; -import { handleActionException, ActionException } from "./RepositoryException"; +import { ActionException, handleActionException } from "./RepositoryException"; import { ArticleRepositoryInput } from "./inputs/article.input"; +import { deleteArticleById, syncArticleById } from "./search.service"; import { authID } from "./session.actions"; import { syncTagsWithArticles } from "./tag.action"; -import { addDays } from "date-fns"; -import { ActionResponse } from "../models/action-contracts"; export async function createMyArticle( _input: z.infer @@ -166,8 +167,6 @@ export async function updateMyArticle( excerpt: input.excerpt, body: input.body, cover_image: input.cover_image, - is_published: input.is_published, - published_at: input.is_published ? new Date() : null, metadata: input.metadata, }), }); @@ -536,6 +535,12 @@ export async function setArticlePublished( published_at: is_published ? new Date() : null, }, }); + if (articles?.rows?.[0] && is_published) { + syncArticleById(article_id); + } + if (articles?.rows?.[0] && !is_published) { + deleteArticleById(article_id); + } return articles?.rows?.[0]; } catch (error) { handleActionException(error); diff --git a/src/backend/services/search.service.ts b/src/backend/services/search.service.ts index c3f84c0..d821325 100644 --- a/src/backend/services/search.service.ts +++ b/src/backend/services/search.service.ts @@ -1,7 +1,6 @@ -import { env } from "@/env"; +import { meilisearchClient } from "@/lib/meilisearch.admin.client"; import { and, eq, neq } from "sqlkit"; import { persistenceRepository } from "../persistence/persistence-repositories"; -import { meilisearchClient } from "@/lib/meilisearch.admin.client"; const index = meilisearchClient.index("articles"); meilisearchClient @@ -15,6 +14,10 @@ meilisearchClient console.error("Error creating index 'articles':", error); }); +/** + * Sync all articles to the search index + * @returns The number of articles synced + */ export const syncAllArticles = async () => { try { const articles = await persistenceRepository.article.find({ @@ -49,6 +52,11 @@ export const syncAllArticles = async () => { } }; +/** + * Sync an article by its ID + * @param articleId - The ID of the article to sync + * @returns The article that was synced + */ export const syncArticleById = async (articleId: string) => { try { const [article] = await persistenceRepository.article.find({ @@ -95,6 +103,7 @@ export const syncArticleById = async (articleId: string) => { export const deleteArticleById = async (articleId: string) => { try { const response = await index.deleteDocument(articleId); + console.log(`Article ${articleId} deleted successfully`); return { message: `Article ${articleId} deleted successfully`, response, diff --git a/src/components/Editor/ArticleEditor.tsx b/src/components/Editor/ArticleEditor.tsx index 4e217f4..be9ca24 100644 --- a/src/components/Editor/ArticleEditor.tsx +++ b/src/components/Editor/ArticleEditor.tsx @@ -175,10 +175,20 @@ const ArticleEditor: React.FC = ({ article, uuid }) => { }, onConfirm: () => { if (uuid) { - updateMyArticleMutation.mutate({ - article_id: uuid, - is_published: !article?.is_published, - }); + updateMyArticleMutation.mutate( + { + article_id: uuid, + is_published: !article?.is_published, + }, + { + onSuccess: () => { + articleActions.setArticlePublished( + uuid, + !article?.is_published + ); + }, + } + ); } }, });