508 lines
11 KiB
TypeScript
508 lines
11 KiB
TypeScript
import { PrismaRepository } from '@gitroom/nestjs-libraries/database/prisma/prisma.service';
|
|
import { Injectable } from '@nestjs/common';
|
|
import { Post as PostBody } from '@gitroom/nestjs-libraries/dtos/posts/create.post.dto';
|
|
import { APPROVED_SUBMIT_FOR_ORDER, Post, State } from '@prisma/client';
|
|
import { GetPostsDto } from '@gitroom/nestjs-libraries/dtos/posts/get.posts.dto';
|
|
import dayjs from 'dayjs';
|
|
import isoWeek from 'dayjs/plugin/isoWeek';
|
|
import weekOfYear from 'dayjs/plugin/weekOfYear';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
dayjs.extend(isoWeek);
|
|
dayjs.extend(weekOfYear);
|
|
|
|
@Injectable()
|
|
export class PostsRepository {
|
|
constructor(
|
|
private _post: PrismaRepository<'post'>,
|
|
private _popularPosts: PrismaRepository<'popularPosts'>,
|
|
private _comments: PrismaRepository<'comments'>
|
|
) {}
|
|
|
|
getOldPosts(orgId: string, date: string) {
|
|
return this._post.model.post.findMany({
|
|
where: {
|
|
organizationId: orgId,
|
|
publishDate: {
|
|
lte: dayjs(date).toDate(),
|
|
},
|
|
deletedAt: null,
|
|
parentPostId: null,
|
|
},
|
|
orderBy: {
|
|
publishDate: 'desc',
|
|
},
|
|
select: {
|
|
id: true,
|
|
content: true,
|
|
publishDate: true,
|
|
releaseURL: true,
|
|
state: true,
|
|
integration: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
providerIdentifier: true,
|
|
picture: true,
|
|
type: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
getPostUrls(orgId: string, ids: string[]) {
|
|
return this._post.model.post.findMany({
|
|
where: {
|
|
organizationId: orgId,
|
|
id: {
|
|
in: ids,
|
|
},
|
|
},
|
|
select: {
|
|
id: true,
|
|
releaseURL: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
getPosts(orgId: string, query: GetPostsDto) {
|
|
const dateYear = dayjs().year(query.year);
|
|
const date =
|
|
query.display === 'day'
|
|
? dateYear.isoWeek(query.week).day(query.day)
|
|
: query.display === 'week'
|
|
? dateYear.isoWeek(query.week)
|
|
: dateYear.month(query.month - 1);
|
|
|
|
const startDate = (
|
|
query.display === 'day'
|
|
? date.startOf('day')
|
|
: query.display === 'week'
|
|
? date.startOf('isoWeek')
|
|
: date.startOf('month')
|
|
)
|
|
.subtract(2, 'hours')
|
|
.toDate();
|
|
const endDate = (
|
|
query.display === 'day'
|
|
? date.endOf('day')
|
|
: query.display === 'week'
|
|
? date.endOf('isoWeek')
|
|
: date.endOf('month')
|
|
)
|
|
.add(2, 'hours')
|
|
.toDate();
|
|
|
|
return this._post.model.post.findMany({
|
|
where: {
|
|
OR: [
|
|
{
|
|
organizationId: orgId,
|
|
},
|
|
{
|
|
submittedForOrganizationId: orgId,
|
|
},
|
|
],
|
|
publishDate: {
|
|
gte: startDate,
|
|
lte: endDate,
|
|
},
|
|
deletedAt: null,
|
|
parentPostId: null,
|
|
...query.customer ? {
|
|
integration: {
|
|
customerId: query.customer,
|
|
}
|
|
}: {},
|
|
},
|
|
select: {
|
|
id: true,
|
|
content: true,
|
|
publishDate: true,
|
|
releaseURL: true,
|
|
submittedForOrganizationId: true,
|
|
submittedForOrderId: true,
|
|
state: true,
|
|
integration: {
|
|
select: {
|
|
id: true,
|
|
providerIdentifier: true,
|
|
name: true,
|
|
picture: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
async deletePost(orgId: string, group: string) {
|
|
await this._post.model.post.updateMany({
|
|
where: {
|
|
organizationId: orgId,
|
|
group,
|
|
},
|
|
data: {
|
|
deletedAt: new Date(),
|
|
},
|
|
});
|
|
|
|
return this._post.model.post.findFirst({
|
|
where: {
|
|
organizationId: orgId,
|
|
group,
|
|
parentPostId: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
getPost(
|
|
id: string,
|
|
includeIntegration = false,
|
|
orgId?: string,
|
|
isFirst?: boolean
|
|
) {
|
|
return this._post.model.post.findUnique({
|
|
where: {
|
|
id,
|
|
...(orgId ? { organizationId: orgId } : {}),
|
|
deletedAt: null,
|
|
},
|
|
include: {
|
|
...(includeIntegration
|
|
? {
|
|
integration: true,
|
|
}
|
|
: {}),
|
|
childrenPost: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
updatePost(id: string, postId: string, releaseURL: string) {
|
|
return this._post.model.post.update({
|
|
where: {
|
|
id,
|
|
},
|
|
data: {
|
|
state: 'PUBLISHED',
|
|
releaseURL,
|
|
releaseId: postId,
|
|
},
|
|
});
|
|
}
|
|
|
|
changeState(id: string, state: State, err?: string) {
|
|
return this._post.model.post.update({
|
|
where: {
|
|
id,
|
|
},
|
|
data: {
|
|
state,
|
|
error: typeof err === 'string' ? err : JSON.stringify(err),
|
|
},
|
|
});
|
|
}
|
|
|
|
async changeDate(orgId: string, id: string, date: string) {
|
|
return this._post.model.post.update({
|
|
where: {
|
|
organizationId: orgId,
|
|
id,
|
|
},
|
|
data: {
|
|
publishDate: dayjs(date).toDate(),
|
|
},
|
|
});
|
|
}
|
|
|
|
countPostsFromDay(orgId: string, date: Date) {
|
|
return this._post.model.post.count({
|
|
where: {
|
|
organizationId: orgId,
|
|
publishDate: {
|
|
gte: date,
|
|
},
|
|
OR: [
|
|
{
|
|
deletedAt: null,
|
|
state: {
|
|
in: ['QUEUE'],
|
|
},
|
|
},
|
|
{
|
|
state: 'PUBLISHED',
|
|
},
|
|
],
|
|
},
|
|
});
|
|
}
|
|
|
|
async createOrUpdatePost(
|
|
state: 'draft' | 'schedule' | 'now',
|
|
orgId: string,
|
|
date: string,
|
|
body: PostBody
|
|
) {
|
|
const posts: Post[] = [];
|
|
const uuid = uuidv4();
|
|
|
|
for (const value of body.value) {
|
|
const updateData = (type: 'create' | 'update') => ({
|
|
publishDate: dayjs(date).toDate(),
|
|
integration: {
|
|
connect: {
|
|
id: body.integration.id,
|
|
organizationId: orgId,
|
|
},
|
|
},
|
|
...(posts?.[posts.length - 1]?.id
|
|
? {
|
|
parentPost: {
|
|
connect: {
|
|
id: posts[posts.length - 1]?.id,
|
|
},
|
|
},
|
|
}
|
|
: type === 'update'
|
|
? {
|
|
parentPost: {
|
|
disconnect: true,
|
|
},
|
|
}
|
|
: {}),
|
|
content: value.content,
|
|
group: uuid,
|
|
approvedSubmitForOrder: APPROVED_SUBMIT_FOR_ORDER.NO,
|
|
state: state === 'draft' ? ('DRAFT' as const) : ('QUEUE' as const),
|
|
image: JSON.stringify(value.image),
|
|
settings: JSON.stringify(body.settings),
|
|
organization: {
|
|
connect: {
|
|
id: orgId,
|
|
},
|
|
},
|
|
});
|
|
|
|
posts.push(
|
|
await this._post.model.post.upsert({
|
|
where: {
|
|
id: value.id || uuidv4(),
|
|
},
|
|
create: { ...updateData('create') },
|
|
update: {
|
|
...updateData('update'),
|
|
lastMessage: {
|
|
disconnect: true,
|
|
},
|
|
submittedForOrder: {
|
|
disconnect: true,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
const previousPost = body.group
|
|
? (
|
|
await this._post.model.post.findFirst({
|
|
where: {
|
|
group: body.group,
|
|
deletedAt: null,
|
|
parentPostId: null,
|
|
},
|
|
select: {
|
|
id: true,
|
|
},
|
|
})
|
|
)?.id!
|
|
: undefined;
|
|
|
|
if (body.group) {
|
|
await this._post.model.post.updateMany({
|
|
where: {
|
|
group: body.group,
|
|
deletedAt: null,
|
|
},
|
|
data: {
|
|
parentPostId: null,
|
|
deletedAt: new Date(),
|
|
},
|
|
});
|
|
}
|
|
|
|
return { previousPost, posts };
|
|
}
|
|
|
|
async submit(id: string, order: string, buyerOrganizationId: string) {
|
|
return this._post.model.post.update({
|
|
where: {
|
|
id,
|
|
},
|
|
data: {
|
|
submittedForOrderId: order,
|
|
approvedSubmitForOrder: 'WAITING_CONFIRMATION',
|
|
submittedForOrganizationId: buyerOrganizationId,
|
|
},
|
|
select: {
|
|
id: true,
|
|
description: true,
|
|
submittedForOrder: {
|
|
select: {
|
|
messageGroupId: true,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
updateMessage(id: string, messageId: string) {
|
|
return this._post.model.post.update({
|
|
where: {
|
|
id,
|
|
},
|
|
data: {
|
|
lastMessageId: messageId,
|
|
},
|
|
});
|
|
}
|
|
|
|
getPostById(id: string, org?: string) {
|
|
return this._post.model.post.findUnique({
|
|
where: {
|
|
id,
|
|
...(org ? { organizationId: org } : {}),
|
|
},
|
|
include: {
|
|
integration: true,
|
|
submittedForOrder: {
|
|
include: {
|
|
posts: {
|
|
where: {
|
|
state: 'PUBLISHED',
|
|
},
|
|
},
|
|
ordersItems: true,
|
|
seller: {
|
|
select: {
|
|
id: true,
|
|
account: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
findAllExistingCategories() {
|
|
return this._popularPosts.model.popularPosts.findMany({
|
|
select: {
|
|
category: true,
|
|
},
|
|
distinct: ['category'],
|
|
});
|
|
}
|
|
|
|
findAllExistingTopicsOfCategory(category: string) {
|
|
return this._popularPosts.model.popularPosts.findMany({
|
|
where: {
|
|
category,
|
|
},
|
|
select: {
|
|
topic: true,
|
|
},
|
|
distinct: ['topic'],
|
|
});
|
|
}
|
|
|
|
findPopularPosts(category: string, topic?: string) {
|
|
return this._popularPosts.model.popularPosts.findMany({
|
|
where: {
|
|
category,
|
|
...(topic ? { topic } : {}),
|
|
},
|
|
select: {
|
|
content: true,
|
|
hook: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
createPopularPosts(post: {
|
|
category: string;
|
|
topic: string;
|
|
content: string;
|
|
hook: string;
|
|
}) {
|
|
return this._popularPosts.model.popularPosts.create({
|
|
data: {
|
|
category: 'category',
|
|
topic: 'topic',
|
|
content: 'content',
|
|
hook: 'hook',
|
|
},
|
|
});
|
|
}
|
|
|
|
async getPostsCountsByDates(
|
|
orgId: string,
|
|
times: number[],
|
|
date: dayjs.Dayjs
|
|
) {
|
|
const dates = await this._post.model.post.findMany({
|
|
where: {
|
|
deletedAt: null,
|
|
organizationId: orgId,
|
|
publishDate: {
|
|
in: times.map((time) => {
|
|
return date.clone().add(time, 'minutes').toDate();
|
|
}),
|
|
},
|
|
},
|
|
});
|
|
|
|
return times.filter(
|
|
(time) =>
|
|
date.clone().add(time, 'minutes').isAfter(dayjs.utc()) &&
|
|
!dates.find((dateFind) => {
|
|
return (
|
|
dayjs
|
|
.utc(dateFind.publishDate)
|
|
.diff(date.clone().startOf('day'), 'minutes') == time
|
|
);
|
|
})
|
|
);
|
|
}
|
|
|
|
async getComments(postId: string) {
|
|
return this._comments.model.comments.findMany({
|
|
where: {
|
|
postId,
|
|
},
|
|
orderBy: {
|
|
createdAt: 'asc',
|
|
},
|
|
});
|
|
}
|
|
|
|
createComment(
|
|
orgId: string,
|
|
userId: string,
|
|
postId: string,
|
|
content: string
|
|
) {
|
|
return this._comments.model.comments.create({
|
|
data: {
|
|
organizationId: orgId,
|
|
userId,
|
|
postId,
|
|
content,
|
|
},
|
|
});
|
|
}
|
|
}
|