feat: better post valdiation + better error messages for validation

This commit is contained in:
Nevo David 2025-07-04 13:01:52 +07:00
parent a80f0397f2
commit 0f0bebeec9
4 changed files with 74 additions and 11 deletions

View File

@ -139,11 +139,12 @@ export class PostsController {
@Post('/')
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
createPost(
async createPost(
@GetOrgFromRequest() org: Organization,
@Body() body: CreatePostDto
@Body() rawBody: any
) {
console.log(JSON.stringify(body, null, 2));
console.log(JSON.stringify(rawBody, null, 2));
const body = await this._postsService.mapTypeToPost(rawBody, org.id);
return this._postsService.createPost(org.id, body);
}

View File

@ -61,7 +61,6 @@ export class PublicIntegrationsController {
@Query() query: GetPostsDto
) {
const posts = await this._postsService.getPosts(org.id, query);
return {
posts,
// comments,
@ -70,10 +69,12 @@ export class PublicIntegrationsController {
@Post('/posts')
@CheckPolicies([AuthorizationActions.Create, Sections.POSTS_PER_MONTH])
createPost(
async createPost(
@GetOrgFromRequest() org: Organization,
@Body() body: CreatePostDto
@Body() rawBody: any
) {
const body = await this._postsService.mapTypeToPost(rawBody, org.id);
console.log(JSON.stringify(body, null, 2));
return this._postsService.createPost(org.id, body);
}

View File

@ -240,7 +240,7 @@ export const ManageModal: FC<AddEditModalProps> = (props) => {
posts: checkAllValid.map((p: any) => ({
integration: p.integration,
group,
settings: { ...(p.settings || {}), __type: p.integration.identifier },
settings: { ...(p.settings || {}) },
value: p.values.map((a: any) => ({
...a,
image: a.media || [],

View File

@ -1,4 +1,9 @@
import { Injectable } from '@nestjs/common';
import {
BadRequestException,
ForbiddenException,
Injectable,
ValidationPipe,
} from '@nestjs/common';
import { PostsRepository } from '@gitroom/nestjs-libraries/database/prisma/posts/posts.repository';
import { CreatePostDto } from '@gitroom/nestjs-libraries/dtos/posts/create.post.dto';
import dayjs from 'dayjs';
@ -29,6 +34,8 @@ import sharp from 'sharp';
import { UploadFactory } from '@gitroom/nestjs-libraries/upload/upload.factory';
import { Readable } from 'stream';
import { OpenaiService } from '@gitroom/nestjs-libraries/openai/openai.service';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
dayjs.extend(utc);
type PostWithConditionals = Post & {
@ -50,7 +57,7 @@ export class PostsService {
private _mediaService: MediaService,
private _shortLinkService: ShortLinkService,
private _webhookService: WebhooksService,
private openaiService: OpenaiService,
private openaiService: OpenaiService
) {}
async getStatistics(orgId: string, id: string) {
@ -65,6 +72,54 @@ export class PostsService {
};
}
async mapTypeToPost(
body: CreatePostDto,
organization: string
): Promise<CreatePostDto> {
if (!body?.posts?.every((p) => p?.integration?.id)) {
throw new BadRequestException('All posts must have an integration id');
}
const mappedValues = {
...body,
posts: await Promise.all(
body.posts.map(async (post) => {
const integration = await this._integrationService.getIntegrationById(
organization,
post.integration.id
);
if (!integration) {
throw new BadRequestException(
`Integration with id ${post.integration.id} not found`
);
}
return {
...post,
settings: {
...(post.settings || ({} as any)),
__type: integration.providerIdentifier,
},
};
})
),
};
const validationPipe = new ValidationPipe({
skipMissingProperties: false,
transform: true,
transformOptions: {
enableImplicitConversion: true,
},
});
return await validationPipe.transform(mappedValues, {
type: 'body',
metatype: CreatePostDto,
});
}
async getPostsRecursively(
id: string,
includeIntegration = false,
@ -572,7 +627,10 @@ export class PostsService {
}
}
private async postArticle(integration: Integration, posts: Post[]): Promise<any> {
private async postArticle(
integration: Integration,
posts: Post[]
): Promise<any> {
const getIntegration = this._integrationManager.getArticlesIntegration(
integration.providerIdentifier
);
@ -929,7 +987,10 @@ export class PostsService {
}
async findFreeDateTime(orgId: string, integrationId?: string) {
const findTimes = await this._integrationService.findFreeDateTime(orgId, integrationId);
const findTimes = await this._integrationService.findFreeDateTime(
orgId,
integrationId
);
return this.findFreeDateTimeRecursive(
orgId,
findTimes,