delete/archive implemented

This commit is contained in:
dimitar committed 2026-02-03 23:14:36 +01:00
1 parent 89b8687431
commit 9ca05f5ea1
13 files changed
+680 -163

No files matched your search

+91 -44
View File
@@ -5,7 +5,13 @@ import { lastValueFrom } from 'rxjs';
import { ArticlesService } from './articles.service';
import { LiveBlogService } from './live-blog.service';
import { CreateArticleDto, CreateLiveBlogDto } from './articles.dto';
import { ArticleStatus, LiveBlogStatus, ImagePosition, ImageSize, VideoPosition } from './entities';
import {
ArticleStatus,
LiveBlogStatus,
ImagePosition,
ImageSize,
VideoPosition,
} from './entities';
interface StrapiArticle {
id: number;
@@ -88,18 +94,18 @@ export class StrapiService {
private extractImageUrl(strapiArticle: StrapiArticle): string | undefined {
// Try to get image from img field first (single image)
let imageUrl: string | undefined;
if (strapiArticle.img?.url) {
imageUrl = strapiArticle.img.url;
} else if (strapiArticle.media?.[0]?.url) {
// Try to get first image from media field (multiple images)
imageUrl = strapiArticle.media[0].url;
}
if (!imageUrl) {
return undefined;
}
// If URL is relative, prepend Strapi base URL
if (imageUrl.startsWith('/')) {
// Convert Docker service URL to localhost for frontend access
@@ -107,25 +113,27 @@ export class StrapiService {
const frontendStrapiUrl = this.strapiUrl.replace('cms:', 'localhost:');
return `${frontendStrapiUrl}${imageUrl}`;
}
return imageUrl;
}
private extractLiveBlogImageUrl(strapiLiveBlog: StrapiLiveBlog): string | undefined {
private extractLiveBlogImageUrl(
strapiLiveBlog: StrapiLiveBlog,
): string | undefined {
// Try to get image from img field first (single image)
let imageUrl: string | undefined;
if (strapiLiveBlog.img?.url) {
imageUrl = strapiLiveBlog.img.url;
} else if (strapiLiveBlog.media?.[0]?.url) {
// Try to get first image from media field (multiple images)
imageUrl = strapiLiveBlog.media[0].url;
}
if (!imageUrl) {
return undefined;
}
// If URL is relative, prepend Strapi base URL
if (imageUrl.startsWith('/')) {
// Convert Docker service URL to localhost for frontend access
@@ -133,7 +141,7 @@ export class StrapiService {
const frontendStrapiUrl = this.strapiUrl.replace('cms:', 'localhost:');
return `${frontendStrapiUrl}${imageUrl}`;
}
return imageUrl;
}
@@ -141,7 +149,7 @@ export class StrapiService {
try {
this.logger.log('Starting articles sync from Strapi...');
const response = await lastValueFrom(
const response = await lastValueFrom(
this.httpService.get<StrapiResponse<StrapiArticle[]>>(
`${this.strapiUrl}/api/articles?populate=*`,
{
@@ -155,7 +163,7 @@ export class StrapiService {
for (const strapiArticle of strapiArticles) {
const imageUrl = this.extractImageUrl(strapiArticle);
const articleData: Partial<CreateArticleDto> = {
title: strapiArticle.title,
excerpt: strapiArticle.description,
@@ -166,10 +174,12 @@ export class StrapiService {
: ArticleStatus.DRAFT,
tags: [],
featuredImage: imageUrl,
imagePosition: (strapiArticle.imagePosition || 'top') as ImagePosition,
imagePosition: (strapiArticle.imagePosition ||
'top') as ImagePosition,
imageSize: (strapiArticle.imageSize || 'medium') as ImageSize,
videoUrl: strapiArticle.videoUrl || '',
videoPosition: (strapiArticle.videoPosition || 'inline') as VideoPosition,
videoPosition: (strapiArticle.videoPosition ||
'inline') as VideoPosition,
videoCaption: strapiArticle.videoCaption || '',
};
@@ -191,12 +201,19 @@ export class StrapiService {
async syncSingleArticle(
strapiId: string,
event?: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish',
event?:
| 'entry.create'
| 'entry.update'
| 'entry.delete'
| 'entry.publish'
| 'entry.unpublish',
): Promise<void> {
try {
this.logger.log(`Syncing single article from Strapi: ${strapiId}, event: ${event}`);
this.logger.log(
`Syncing single article from Strapi: ${strapiId}, event: ${event}`,
);
const response = await lastValueFrom(
const response = await lastValueFrom(
this.httpService.get<StrapiResponse<StrapiArticle>>(
`${this.strapiUrl}/api/articles/${strapiId}?populate=*`,
{
@@ -206,7 +223,7 @@ export class StrapiService {
);
const strapiArticle = response.data.data;
// Determine status based on publishedAt and event type
let status: ArticleStatus;
if (event === 'entry.unpublish') {
@@ -221,7 +238,7 @@ export class StrapiService {
}
const imageUrl = this.extractImageUrl(strapiArticle);
const articleData: Partial<CreateArticleDto> = {
title: strapiArticle.title,
excerpt: strapiArticle.description,
@@ -233,7 +250,8 @@ export class StrapiService {
imagePosition: (strapiArticle.imagePosition || 'top') as ImagePosition,
imageSize: (strapiArticle.imageSize || 'medium') as ImageSize,
videoUrl: strapiArticle.videoUrl || '',
videoPosition: (strapiArticle.videoPosition || 'inline') as VideoPosition,
videoPosition: (strapiArticle.videoPosition ||
'inline') as VideoPosition,
videoCaption: strapiArticle.videoCaption || '',
};
@@ -241,20 +259,26 @@ export class StrapiService {
strapiArticle.documentId,
articleData,
);
this.logger.log(`Successfully synced article: ${strapiArticle.title} with status: ${status}`);
this.logger.log(
`Successfully synced article: ${strapiArticle.title} with status: ${status}`,
);
} catch (error: any) {
// If we get a 404 and it's an unpublish event, we can still mark it as draft
if (event === 'entry.unpublish' && error.response?.status === 404) {
this.logger.log(`Article ${strapiId} not found in Strapi, marking as draft based on unpublish event`);
this.logger.log(
`Article ${strapiId} not found in Strapi, marking as draft based on unpublish event`,
);
// Try to update the article status to draft directly
try {
const articleData: Partial<CreateArticleDto> = {
status: ArticleStatus.DRAFT,
};
await this.articlesService.syncFromStrapi(strapiId, articleData);
this.logger.log(`Marked article ${strapiId} as draft based on unpublish event`);
this.logger.log(
`Marked article ${strapiId} as draft based on unpublish event`,
);
} catch (syncError) {
this.logger.error(
`Failed to mark article ${strapiId} as draft:`,
@@ -276,7 +300,7 @@ export class StrapiService {
try {
this.logger.log('Starting live blogs sync from Strapi...');
const response = await lastValueFrom(
const response = await lastValueFrom(
this.httpService.get<StrapiResponse<StrapiLiveBlog[]>>(
`${this.strapiUrl}/api/live-blogs?populate=*`,
{
@@ -290,17 +314,19 @@ export class StrapiService {
for (const strapiLiveBlog of strapiLiveBlogs) {
const imageUrl = this.extractLiveBlogImageUrl(strapiLiveBlog);
const liveBlogData: Partial<CreateLiveBlogDto> = {
title: strapiLiveBlog.title,
description: strapiLiveBlog.description,
slug: strapiLiveBlog.slug,
status: this.mapStrapiStatusToLiveBlogStatus(strapiLiveBlog.status),
featuredImage: imageUrl,
imagePosition: (strapiLiveBlog.imagePosition || 'top') as ImagePosition,
imagePosition: (strapiLiveBlog.imagePosition ||
'top') as ImagePosition,
imageSize: (strapiLiveBlog.imageSize || 'medium') as ImageSize,
videoUrl: strapiLiveBlog.videoUrl || '',
videoPosition: (strapiLiveBlog.videoPosition || 'inline') as VideoPosition,
videoPosition: (strapiLiveBlog.videoPosition ||
'inline') as VideoPosition,
videoCaption: strapiLiveBlog.videoCaption || '',
};
@@ -322,12 +348,19 @@ export class StrapiService {
async syncSingleLiveBlog(
strapiId: string,
event?: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish',
event?:
| 'entry.create'
| 'entry.update'
| 'entry.delete'
| 'entry.publish'
| 'entry.unpublish',
): Promise<void> {
try {
this.logger.log(`Syncing single live blog from Strapi: ${strapiId}, event: ${event}`);
this.logger.log(
`Syncing single live blog from Strapi: ${strapiId}, event: ${event}`,
);
const response = await lastValueFrom(
const response = await lastValueFrom(
this.httpService.get<StrapiResponse<StrapiLiveBlog>>(
`${this.strapiUrl}/api/live-blogs/${strapiId}?populate=*`,
{
@@ -337,18 +370,18 @@ export class StrapiService {
);
const strapiLiveBlog = response.data.data;
// For live blogs, we use the status from Strapi directly
// but we might want to handle unpublish events differently
let status = this.mapStrapiStatusToLiveBlogStatus(strapiLiveBlog.status);
// If it's an unpublish event, set to draft
if (event === 'entry.unpublish') {
status = LiveBlogStatus.DRAFT;
}
const imageUrl = this.extractLiveBlogImageUrl(strapiLiveBlog);
const liveBlogData: Partial<CreateLiveBlogDto> = {
title: strapiLiveBlog.title,
description: strapiLiveBlog.description,
@@ -358,7 +391,8 @@ export class StrapiService {
imagePosition: (strapiLiveBlog.imagePosition || 'top') as ImagePosition,
imageSize: (strapiLiveBlog.imageSize || 'medium') as ImageSize,
videoUrl: strapiLiveBlog.videoUrl || '',
videoPosition: (strapiLiveBlog.videoPosition || 'inline') as VideoPosition,
videoPosition: (strapiLiveBlog.videoPosition ||
'inline') as VideoPosition,
videoCaption: strapiLiveBlog.videoCaption || '',
};
@@ -366,20 +400,26 @@ export class StrapiService {
strapiLiveBlog.documentId,
liveBlogData,
);
this.logger.log(`Successfully synced live blog: ${strapiLiveBlog.title} with status: ${status}`);
this.logger.log(
`Successfully synced live blog: ${strapiLiveBlog.title} with status: ${status}`,
);
} catch (error: any) {
// If we get a 404 and it's an unpublish event, we can still mark it as draft
if (event === 'entry.unpublish' && error.response?.status === 404) {
this.logger.log(`Live blog ${strapiId} not found in Strapi, marking as draft based on unpublish event`);
this.logger.log(
`Live blog ${strapiId} not found in Strapi, marking as draft based on unpublish event`,
);
// Try to update the live blog status to draft directly
try {
const liveBlogData: Partial<CreateLiveBlogDto> = {
status: LiveBlogStatus.DRAFT,
};
await this.liveBlogService.syncFromStrapi(strapiId, liveBlogData);
this.logger.log(`Marked live blog ${strapiId} as draft based on unpublish event`);
this.logger.log(
`Marked live blog ${strapiId} as draft based on unpublish event`,
);
} catch (syncError) {
this.logger.error(
`Failed to mark live blog ${strapiId} as draft:`,
@@ -413,7 +453,12 @@ export class StrapiService {
}
async handleWebhook(
event: 'entry.create' | 'entry.update' | 'entry.delete' | 'entry.publish' | 'entry.unpublish',
event:
| 'entry.create'
| 'entry.update'
| 'entry.delete'
| 'entry.publish'
| 'entry.unpublish',
data: { documentId: string; model?: string },
): Promise<void> {
this.logger.log(
@@ -421,8 +466,10 @@ export class StrapiService {
);
if (event === 'entry.delete') {
this.logger.log(`Handling delete for document: ${data.documentId}, model: ${data.model}`);
this.logger.log(
`Handling delete for document: ${data.documentId}, model: ${data.model}`,
);
if (data.model === 'article') {
await this.articlesService.removeByStrapiId(data.documentId);
} else if (data.model === 'live-blog') {