sync working as intended
This commit is contained in:
parent
9ca05f5ea1
commit
7378d37b36
@ -63,10 +63,7 @@ export class ArticlesController {
|
||||
}
|
||||
|
||||
@Patch(':id/publish')
|
||||
publish(
|
||||
@Param('id') id: string,
|
||||
@Query('status') status?: ArticleStatus,
|
||||
) {
|
||||
publish(@Param('id') id: string, @Query('status') status?: ArticleStatus) {
|
||||
return this.articlesService.publish(id, status || ArticleStatus.PUBLISHED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { Module, forwardRef } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ArticlesService } from './articles.service';
|
||||
import { ArticlesController } from './articles.controller';
|
||||
import { Article, Author, Category } from './entities';
|
||||
import { StrapiModule } from './strapi.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Article, Author, Category])],
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([Article, Author, Category]),
|
||||
forwardRef(() => StrapiModule),
|
||||
],
|
||||
controllers: [ArticlesController],
|
||||
providers: [ArticlesService],
|
||||
exports: [ArticlesService],
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
import { Injectable, NotFoundException, Logger } from '@nestjs/common';
|
||||
import {
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
Logger,
|
||||
Inject,
|
||||
forwardRef,
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Article, ArticleStatus } from './entities';
|
||||
import { StrapiService } from './strapi.service';
|
||||
import {
|
||||
CreateArticleDto,
|
||||
UpdateArticleDto,
|
||||
@ -15,6 +22,8 @@ export class ArticlesService {
|
||||
constructor(
|
||||
@InjectRepository(Article)
|
||||
private readonly articleRepository: Repository<Article>,
|
||||
@Inject(forwardRef(() => StrapiService))
|
||||
private readonly strapiService: StrapiService,
|
||||
) {}
|
||||
|
||||
async create(dto: CreateArticleDto): Promise<Article> {
|
||||
@ -102,44 +111,173 @@ export class ArticlesService {
|
||||
|
||||
async update(id: string, dto: UpdateArticleDto): Promise<Article> {
|
||||
const article = await this.findOne(id);
|
||||
const oldStatus = article.status;
|
||||
Object.assign(article, dto);
|
||||
return await this.articleRepository.save(article);
|
||||
const savedArticle = await this.articleRepository.save(article);
|
||||
|
||||
// Update Strapi if status changed and article has strapiId
|
||||
if (
|
||||
dto.status !== undefined &&
|
||||
dto.status !== oldStatus &&
|
||||
article.strapiId
|
||||
) {
|
||||
try {
|
||||
await this.strapiService.updateArticleStatusInStrapi(
|
||||
article.strapiId,
|
||||
dto.status,
|
||||
);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - backend status is updated
|
||||
this.logger.error(
|
||||
`Failed to update Strapi status for article ${id}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return savedArticle;
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
const article = await this.findOne(id);
|
||||
|
||||
// Delete from Strapi if article has strapiId
|
||||
if (article.strapiId) {
|
||||
try {
|
||||
await this.strapiService.deleteArticleFromStrapi(article.strapiId);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - we still want to delete from backend
|
||||
this.logger.error(`Failed to delete article ${id} from Strapi:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
await this.articleRepository.remove(article);
|
||||
}
|
||||
|
||||
async archive(id: string): Promise<Article> {
|
||||
const article = await this.findOne(id);
|
||||
article.status = ArticleStatus.ARCHIVED;
|
||||
return await this.articleRepository.save(article);
|
||||
const savedArticle = await this.articleRepository.save(article);
|
||||
|
||||
// Update Strapi if article has strapiId
|
||||
if (article.strapiId) {
|
||||
try {
|
||||
await this.strapiService.updateArticleStatusInStrapi(
|
||||
article.strapiId,
|
||||
ArticleStatus.ARCHIVED,
|
||||
);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - backend status is updated
|
||||
this.logger.error(
|
||||
`Failed to update Strapi status for article ${id}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return savedArticle;
|
||||
}
|
||||
|
||||
async publish(id: string, status: ArticleStatus = ArticleStatus.PUBLISHED): Promise<Article> {
|
||||
async publish(
|
||||
id: string,
|
||||
status: ArticleStatus = ArticleStatus.PUBLISHED,
|
||||
): Promise<Article> {
|
||||
const article = await this.findOne(id);
|
||||
article.status = status;
|
||||
return await this.articleRepository.save(article);
|
||||
const savedArticle = await this.articleRepository.save(article);
|
||||
|
||||
// Update Strapi if article has strapiId
|
||||
if (article.strapiId) {
|
||||
try {
|
||||
await this.strapiService.updateArticleStatusInStrapi(
|
||||
article.strapiId,
|
||||
status,
|
||||
);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - backend status is updated
|
||||
this.logger.error(
|
||||
`Failed to update Strapi status for article ${id}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return savedArticle;
|
||||
}
|
||||
|
||||
async syncFromStrapi(
|
||||
strapiId: string,
|
||||
data: Partial<CreateArticleDto>,
|
||||
): Promise<Article> {
|
||||
let article = await this.articleRepository.findOne({ where: { strapiId } });
|
||||
|
||||
if (!article) {
|
||||
article = this.articleRepository.create({
|
||||
strapiId,
|
||||
...data,
|
||||
status: data.status || ArticleStatus.DRAFT,
|
||||
// Use upsert to handle race conditions and ensure uniqueness
|
||||
try {
|
||||
// First try to find existing article by strapiId
|
||||
const article = await this.articleRepository.findOne({
|
||||
where: { strapiId },
|
||||
});
|
||||
} else {
|
||||
Object.assign(article, data);
|
||||
}
|
||||
|
||||
return await this.articleRepository.save(article);
|
||||
if (article) {
|
||||
// Update existing article
|
||||
const currentStatus = article.status;
|
||||
Object.assign(article, data);
|
||||
|
||||
// Preserve archived status if article is already archived in our system
|
||||
// unless Strapi explicitly sends a different status
|
||||
if (
|
||||
currentStatus === ArticleStatus.ARCHIVED &&
|
||||
data.status !== ArticleStatus.ARCHIVED
|
||||
) {
|
||||
article.status = ArticleStatus.ARCHIVED;
|
||||
}
|
||||
|
||||
return await this.articleRepository.save(article);
|
||||
} else {
|
||||
// Create new article
|
||||
const newArticle = this.articleRepository.create({
|
||||
strapiId,
|
||||
...data,
|
||||
status: data.status || ArticleStatus.DRAFT,
|
||||
});
|
||||
|
||||
return await this.articleRepository.save(newArticle);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
// If we get a unique constraint violation, try to find and update again
|
||||
// This handles race conditions where two syncs happen simultaneously
|
||||
const dbError = error as { code?: string; constraint?: string };
|
||||
if (
|
||||
dbError.code === '23505' &&
|
||||
dbError.constraint?.includes('strapiId')
|
||||
) {
|
||||
this.logger.warn(
|
||||
`Race condition detected for strapiId ${strapiId}, retrying...`,
|
||||
);
|
||||
|
||||
// Wait a bit and retry
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const existingArticle = await this.articleRepository.findOne({
|
||||
where: { strapiId },
|
||||
});
|
||||
|
||||
if (existingArticle) {
|
||||
const currentStatus = existingArticle.status;
|
||||
Object.assign(existingArticle, data);
|
||||
|
||||
if (
|
||||
currentStatus === ArticleStatus.ARCHIVED &&
|
||||
data.status !== ArticleStatus.ARCHIVED
|
||||
) {
|
||||
existingArticle.status = ArticleStatus.ARCHIVED;
|
||||
}
|
||||
|
||||
return await this.articleRepository.save(existingArticle);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-throw other errors
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async removeByStrapiId(strapiId: string): Promise<void> {
|
||||
|
||||
@ -174,7 +174,7 @@ export class Article {
|
||||
@Column({ default: 0 })
|
||||
views: number;
|
||||
|
||||
@Column({ nullable: true })
|
||||
@Column({ nullable: true, unique: true })
|
||||
strapiId: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
@ -221,7 +221,7 @@ export class LiveBlog {
|
||||
@Column({ default: false })
|
||||
isPinned: boolean;
|
||||
|
||||
@Column({ nullable: true })
|
||||
@Column({ nullable: true, unique: true })
|
||||
strapiId: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
|
||||
@ -129,10 +129,7 @@ export class LiveBlogController {
|
||||
}
|
||||
|
||||
@Patch(':id/publish')
|
||||
publish(
|
||||
@Param('id') id: string,
|
||||
@Query('status') status?: LiveBlogStatus,
|
||||
) {
|
||||
publish(@Param('id') id: string, @Query('status') status?: LiveBlogStatus) {
|
||||
return this.liveBlogService.publish(id, status || LiveBlogStatus.DRAFT);
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { Module, forwardRef } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
import { LiveBlogService } from './live-blog.service';
|
||||
import { LiveBlogController } from './live-blog.controller';
|
||||
import { LiveBlog, LiveBlogUpdate, Author, Category } from './entities';
|
||||
import { StrapiModule } from './strapi.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([LiveBlog, LiveBlogUpdate, Author, Category]),
|
||||
EventEmitterModule.forRoot(),
|
||||
forwardRef(() => StrapiModule),
|
||||
],
|
||||
controllers: [LiveBlogController],
|
||||
providers: [LiveBlogService],
|
||||
|
||||
@ -3,12 +3,15 @@ import {
|
||||
NotFoundException,
|
||||
Logger,
|
||||
OnModuleInit,
|
||||
Inject,
|
||||
forwardRef,
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository, In } from 'typeorm';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { Response } from 'express';
|
||||
import { LiveBlog, LiveBlogUpdate, LiveBlogStatus } from './entities';
|
||||
import { StrapiService } from './strapi.service';
|
||||
import {
|
||||
CreateLiveBlogDto,
|
||||
UpdateLiveBlogDto,
|
||||
@ -50,6 +53,8 @@ export class LiveBlogService implements OnModuleInit {
|
||||
@InjectRepository(LiveBlogUpdate)
|
||||
private readonly liveBlogUpdateRepository: Repository<LiveBlogUpdate>,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
@Inject(forwardRef(() => StrapiService))
|
||||
private readonly strapiService: StrapiService,
|
||||
) {}
|
||||
|
||||
onModuleInit() {
|
||||
@ -248,6 +253,22 @@ export class LiveBlogService implements OnModuleInit {
|
||||
blogId: id,
|
||||
status: dto.status,
|
||||
});
|
||||
|
||||
// Update Strapi if live blog has strapiId
|
||||
if (liveBlog.strapiId) {
|
||||
try {
|
||||
await this.strapiService.updateLiveBlogStatusInStrapi(
|
||||
liveBlog.strapiId,
|
||||
dto.status,
|
||||
);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - backend status is updated
|
||||
this.logger.error(
|
||||
`Failed to update Strapi status for live blog ${id}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updatedBlog;
|
||||
@ -255,19 +276,72 @@ export class LiveBlogService implements OnModuleInit {
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
const liveBlog = await this.findOne(id);
|
||||
|
||||
// Delete from Strapi if live blog has strapiId
|
||||
if (liveBlog.strapiId) {
|
||||
try {
|
||||
await this.strapiService.deleteLiveBlogFromStrapi(liveBlog.strapiId);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - we still want to delete from backend
|
||||
this.logger.error(
|
||||
`Failed to delete live blog ${id} from Strapi:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await this.liveBlogRepository.remove(liveBlog);
|
||||
}
|
||||
|
||||
async archive(id: string): Promise<LiveBlog> {
|
||||
const liveBlog = await this.findOne(id);
|
||||
liveBlog.status = LiveBlogStatus.ARCHIVED;
|
||||
return await this.liveBlogRepository.save(liveBlog);
|
||||
const savedLiveBlog = await this.liveBlogRepository.save(liveBlog);
|
||||
|
||||
// Update Strapi if live blog has strapiId
|
||||
if (liveBlog.strapiId) {
|
||||
try {
|
||||
await this.strapiService.updateLiveBlogStatusInStrapi(
|
||||
liveBlog.strapiId,
|
||||
LiveBlogStatus.ARCHIVED,
|
||||
);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - backend status is updated
|
||||
this.logger.error(
|
||||
`Failed to update Strapi status for live blog ${id}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return savedLiveBlog;
|
||||
}
|
||||
|
||||
async publish(id: string, status: LiveBlogStatus = LiveBlogStatus.DRAFT): Promise<LiveBlog> {
|
||||
async publish(
|
||||
id: string,
|
||||
status: LiveBlogStatus = LiveBlogStatus.DRAFT,
|
||||
): Promise<LiveBlog> {
|
||||
const liveBlog = await this.findOne(id);
|
||||
liveBlog.status = status;
|
||||
return await this.liveBlogRepository.save(liveBlog);
|
||||
const savedLiveBlog = await this.liveBlogRepository.save(liveBlog);
|
||||
|
||||
// Update Strapi if live blog has strapiId
|
||||
if (liveBlog.strapiId) {
|
||||
try {
|
||||
await this.strapiService.updateLiveBlogStatusInStrapi(
|
||||
liveBlog.strapiId,
|
||||
status,
|
||||
);
|
||||
} catch (error) {
|
||||
// Log error but don't fail - backend status is updated
|
||||
this.logger.error(
|
||||
`Failed to update Strapi status for live blog ${id}:`,
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return savedLiveBlog;
|
||||
}
|
||||
|
||||
// Live Blog Update CRUD operations
|
||||
@ -433,21 +507,75 @@ export class LiveBlogService implements OnModuleInit {
|
||||
strapiId: string,
|
||||
data: Partial<CreateLiveBlogDto>,
|
||||
): Promise<LiveBlog> {
|
||||
let liveBlog = await this.liveBlogRepository.findOne({
|
||||
where: { strapiId },
|
||||
});
|
||||
|
||||
if (!liveBlog) {
|
||||
liveBlog = this.liveBlogRepository.create({
|
||||
strapiId,
|
||||
...data,
|
||||
status: data.status || LiveBlogStatus.DRAFT,
|
||||
// Use upsert to handle race conditions and ensure uniqueness
|
||||
try {
|
||||
// First try to find existing live blog by strapiId
|
||||
const liveBlog = await this.liveBlogRepository.findOne({
|
||||
where: { strapiId },
|
||||
});
|
||||
} else {
|
||||
Object.assign(liveBlog, data);
|
||||
}
|
||||
|
||||
return await this.liveBlogRepository.save(liveBlog);
|
||||
if (liveBlog) {
|
||||
// Update existing live blog
|
||||
const currentStatus = liveBlog.status;
|
||||
Object.assign(liveBlog, data);
|
||||
|
||||
// Preserve archived status if live blog is already archived in our system
|
||||
// unless Strapi explicitly sends a different status
|
||||
if (
|
||||
currentStatus === LiveBlogStatus.ARCHIVED &&
|
||||
data.status !== LiveBlogStatus.ARCHIVED
|
||||
) {
|
||||
liveBlog.status = LiveBlogStatus.ARCHIVED;
|
||||
}
|
||||
|
||||
return await this.liveBlogRepository.save(liveBlog);
|
||||
} else {
|
||||
// Create new live blog
|
||||
const newLiveBlog = this.liveBlogRepository.create({
|
||||
strapiId,
|
||||
...data,
|
||||
status: data.status || LiveBlogStatus.DRAFT,
|
||||
});
|
||||
|
||||
return await this.liveBlogRepository.save(newLiveBlog);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
// If we get a unique constraint violation, try to find and update again
|
||||
// This handles race conditions where two syncs happen simultaneously
|
||||
const dbError = error as { code?: string; constraint?: string };
|
||||
if (
|
||||
dbError.code === '23505' &&
|
||||
dbError.constraint?.includes('strapiId')
|
||||
) {
|
||||
this.logger.warn(
|
||||
`Race condition detected for strapiId ${strapiId}, retrying...`,
|
||||
);
|
||||
|
||||
// Wait a bit and retry
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
const existingLiveBlog = await this.liveBlogRepository.findOne({
|
||||
where: { strapiId },
|
||||
});
|
||||
|
||||
if (existingLiveBlog) {
|
||||
const currentStatus = existingLiveBlog.status;
|
||||
Object.assign(existingLiveBlog, data);
|
||||
|
||||
if (
|
||||
currentStatus === LiveBlogStatus.ARCHIVED &&
|
||||
data.status !== LiveBlogStatus.ARCHIVED
|
||||
) {
|
||||
existingLiveBlog.status = LiveBlogStatus.ARCHIVED;
|
||||
}
|
||||
|
||||
return await this.liveBlogRepository.save(existingLiveBlog);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-throw other errors
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async removeByStrapiId(strapiId: string): Promise<void> {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { Module, forwardRef } from '@nestjs/common';
|
||||
import { HttpModule } from '@nestjs/axios';
|
||||
import { StrapiService } from './strapi.service';
|
||||
import { StrapiController } from './strapi.controller';
|
||||
@ -6,7 +6,11 @@ import { ArticlesModule } from './articles.module';
|
||||
import { LiveBlogModule } from './live-blog.module';
|
||||
|
||||
@Module({
|
||||
imports: [HttpModule, ArticlesModule, LiveBlogModule],
|
||||
imports: [
|
||||
HttpModule,
|
||||
forwardRef(() => ArticlesModule),
|
||||
forwardRef(() => LiveBlogModule),
|
||||
],
|
||||
controllers: [StrapiController],
|
||||
providers: [StrapiService],
|
||||
exports: [StrapiService],
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { Injectable, Logger, Inject, forwardRef } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { HttpService } from '@nestjs/axios';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
@ -13,6 +13,21 @@ import {
|
||||
VideoPosition,
|
||||
} from './entities';
|
||||
|
||||
interface StrapiImage {
|
||||
url: string;
|
||||
alternativeText?: string;
|
||||
caption?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
formats?: Record<string, StrapiImageFormat>;
|
||||
}
|
||||
|
||||
interface StrapiImageFormat {
|
||||
url: string;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
interface StrapiArticle {
|
||||
id: number;
|
||||
documentId: string;
|
||||
@ -23,8 +38,8 @@ interface StrapiArticle {
|
||||
publishedAt: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
img?: any;
|
||||
media?: any[];
|
||||
img?: StrapiImage;
|
||||
media?: StrapiImage[];
|
||||
imagePosition?: string;
|
||||
imageSize?: string;
|
||||
videoUrl?: string;
|
||||
@ -42,8 +57,8 @@ interface StrapiLiveBlog {
|
||||
publishedAt: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
img?: any;
|
||||
media?: any[];
|
||||
img?: StrapiImage;
|
||||
media?: StrapiImage[];
|
||||
imagePosition?: string;
|
||||
imageSize?: string;
|
||||
videoUrl?: string;
|
||||
@ -72,7 +87,9 @@ export class StrapiService {
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
private readonly httpService: HttpService,
|
||||
@Inject(forwardRef(() => ArticlesService))
|
||||
private readonly articlesService: ArticlesService,
|
||||
@Inject(forwardRef(() => LiveBlogService))
|
||||
private readonly liveBlogService: LiveBlogService,
|
||||
) {
|
||||
this.strapiUrl =
|
||||
@ -262,9 +279,10 @@ export class StrapiService {
|
||||
this.logger.log(
|
||||
`Successfully synced article: ${strapiArticle.title} with status: ${status}`,
|
||||
);
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
// 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) {
|
||||
const axiosError = error as { response?: { status: number } };
|
||||
if (event === 'entry.unpublish' && axiosError.response?.status === 404) {
|
||||
this.logger.log(
|
||||
`Article ${strapiId} not found in Strapi, marking as draft based on unpublish event`,
|
||||
);
|
||||
@ -403,9 +421,10 @@ export class StrapiService {
|
||||
this.logger.log(
|
||||
`Successfully synced live blog: ${strapiLiveBlog.title} with status: ${status}`,
|
||||
);
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
// 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) {
|
||||
const axiosError = error as { response?: { status: number } };
|
||||
if (event === 'entry.unpublish' && axiosError.response?.status === 404) {
|
||||
this.logger.log(
|
||||
`Live blog ${strapiId} not found in Strapi, marking as draft based on unpublish event`,
|
||||
);
|
||||
@ -489,4 +508,162 @@ export class StrapiService {
|
||||
this.logger.warn(`Unknown model type in webhook: ${data.model}`);
|
||||
}
|
||||
}
|
||||
|
||||
async updateArticleStatusInStrapi(
|
||||
strapiId: string,
|
||||
status: ArticleStatus,
|
||||
): Promise<void> {
|
||||
try {
|
||||
this.logger.log(
|
||||
`Updating article ${strapiId} status in Strapi to: ${status}`,
|
||||
);
|
||||
|
||||
// Map our status to Strapi status
|
||||
let strapiStatus: string;
|
||||
switch (status) {
|
||||
case ArticleStatus.DRAFT:
|
||||
strapiStatus = 'draft';
|
||||
break;
|
||||
case ArticleStatus.PUBLISHED:
|
||||
strapiStatus = 'published';
|
||||
break;
|
||||
case ArticleStatus.ARCHIVED:
|
||||
strapiStatus = 'archived';
|
||||
break;
|
||||
default:
|
||||
strapiStatus = 'draft';
|
||||
}
|
||||
|
||||
// For archived status, we need to unpublish first if it's published
|
||||
if (status === ArticleStatus.ARCHIVED) {
|
||||
await lastValueFrom(
|
||||
this.httpService.patch(
|
||||
`${this.strapiUrl}/api/articles/${strapiId}/unpublish`,
|
||||
{},
|
||||
{ headers: this.getHeaders() },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Update the status
|
||||
await lastValueFrom(
|
||||
this.httpService.patch(
|
||||
`${this.strapiUrl}/api/articles/${strapiId}`,
|
||||
{ data: { status: strapiStatus } },
|
||||
{ headers: this.getHeaders() },
|
||||
),
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
`Successfully updated article ${strapiId} status in Strapi to: ${status}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to update article ${strapiId} status in Strapi:`,
|
||||
error,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async updateLiveBlogStatusInStrapi(
|
||||
strapiId: string,
|
||||
status: LiveBlogStatus,
|
||||
): Promise<void> {
|
||||
try {
|
||||
this.logger.log(
|
||||
`Updating live blog ${strapiId} status in Strapi to: ${status}`,
|
||||
);
|
||||
|
||||
// Map our status to Strapi status
|
||||
let strapiStatus: string;
|
||||
switch (status) {
|
||||
case LiveBlogStatus.DRAFT:
|
||||
strapiStatus = 'draft';
|
||||
break;
|
||||
case LiveBlogStatus.LIVE:
|
||||
strapiStatus = 'live';
|
||||
break;
|
||||
case LiveBlogStatus.ENDED:
|
||||
strapiStatus = 'ended';
|
||||
break;
|
||||
case LiveBlogStatus.ARCHIVED:
|
||||
strapiStatus = 'archived';
|
||||
break;
|
||||
default:
|
||||
strapiStatus = 'draft';
|
||||
}
|
||||
|
||||
// For archived status, we need to unpublish first if it's published
|
||||
if (status === LiveBlogStatus.ARCHIVED) {
|
||||
await lastValueFrom(
|
||||
this.httpService.patch(
|
||||
`${this.strapiUrl}/api/live-blogs/${strapiId}/unpublish`,
|
||||
{},
|
||||
{ headers: this.getHeaders() },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Update the status
|
||||
await lastValueFrom(
|
||||
this.httpService.patch(
|
||||
`${this.strapiUrl}/api/live-blogs/${strapiId}`,
|
||||
{ data: { status: strapiStatus } },
|
||||
{ headers: this.getHeaders() },
|
||||
),
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
`Successfully updated live blog ${strapiId} status in Strapi to: ${status}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to update live blog ${strapiId} status in Strapi:`,
|
||||
error,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteArticleFromStrapi(strapiId: string): Promise<void> {
|
||||
try {
|
||||
this.logger.log(`Deleting article ${strapiId} from Strapi`);
|
||||
|
||||
await lastValueFrom(
|
||||
this.httpService.delete(`${this.strapiUrl}/api/articles/${strapiId}`, {
|
||||
headers: this.getHeaders(),
|
||||
}),
|
||||
);
|
||||
|
||||
this.logger.log(`Successfully deleted article ${strapiId} from Strapi`);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to delete article ${strapiId} from Strapi:`,
|
||||
error,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteLiveBlogFromStrapi(strapiId: string): Promise<void> {
|
||||
try {
|
||||
this.logger.log(`Deleting live blog ${strapiId} from Strapi`);
|
||||
|
||||
await lastValueFrom(
|
||||
this.httpService.delete(
|
||||
`${this.strapiUrl}/api/live-blogs/${strapiId}`,
|
||||
{ headers: this.getHeaders() },
|
||||
),
|
||||
);
|
||||
|
||||
this.logger.log(`Successfully deleted live blog ${strapiId} from Strapi`);
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Failed to delete live blog ${strapiId} from Strapi:`,
|
||||
error,
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user