@drodil/backstage-plugin-qeta-backend 3.48.0 → 3.48.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/database/stores/AnswersStore.cjs.js +4 -5
- package/dist/database/stores/AnswersStore.cjs.js.map +1 -1
- package/dist/database/stores/PostsStore.cjs.js +13 -4
- package/dist/database/stores/PostsStore.cjs.js.map +1 -1
- package/dist/database/stores/UsersStore.cjs.js +29 -31
- package/dist/database/stores/UsersStore.cjs.js.map +1 -1
- package/dist/service/PermissionManager.cjs.js +44 -46
- package/dist/service/PermissionManager.cjs.js.map +1 -1
- package/dist/service/routes/answers.cjs.js +92 -72
- package/dist/service/routes/answers.cjs.js.map +1 -1
- package/dist/service/routes/collections.cjs.js +69 -44
- package/dist/service/routes/collections.cjs.js.map +1 -1
- package/dist/service/routes/helpers.cjs.js +20 -10
- package/dist/service/routes/helpers.cjs.js.map +1 -1
- package/dist/service/routes/posts.cjs.js +60 -34
- package/dist/service/routes/posts.cjs.js.map +1 -1
- package/dist/service/routes/routeUtil.cjs.js +1 -1
- package/dist/service/routes/routeUtil.cjs.js.map +1 -1
- package/dist/service/util.cjs.js +246 -149
- package/dist/service/util.cjs.js.map +1 -1
- package/package.json +7 -7
|
@@ -193,11 +193,10 @@ class AnswersStore extends BaseStore.BaseStore {
|
|
|
193
193
|
answerIds,
|
|
194
194
|
options?.commentsFilter
|
|
195
195
|
) : void 0,
|
|
196
|
-
includePost && this.postsStore ?
|
|
197
|
-
[...new Set(rows.map((r) => r.postId))]
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
) : void 0,
|
|
196
|
+
includePost && this.postsStore ? this.postsStore.getPosts(user_ref, {
|
|
197
|
+
ids: [...new Set(rows.map((r) => r.postId))],
|
|
198
|
+
limit: rows.length
|
|
199
|
+
}).then((p) => p.posts) : void 0,
|
|
201
200
|
this.attachmentsStore.getAttachments(answerIds, "answerId"),
|
|
202
201
|
includeExperts ? this.db("tag_experts").leftJoin("tags", "tag_experts.tagId", "tags.id").leftJoin("post_tags", "post_tags.tagId", "tags.id").leftJoin("answers", "answers.postId", "post_tags.postId").whereIn("answers.id", answerIds).select("answers.id as answerId", "tag_experts.entityRef") : void 0
|
|
203
202
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnswersStore.cjs.js","sources":["../../../src/database/stores/AnswersStore.ts"],"sourcesContent":["import {\n Answer,\n AnswersQuery,\n AnswerCommentStatus,\n Comment as QetaComment,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { AnswerOptions, Answers, MaybeAnswer, MaybePost } from '../QetaStore';\nimport { Knex } from 'knex';\nimport { CommentsStore } from './CommentsStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { QetaFilters } from '../../service/util';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport { BaseStore } from './BaseStore';\n\nexport interface RawAnswerEntity {\n id: number;\n postId: number;\n author: string;\n content: string;\n correct: boolean;\n score: number | string;\n created: Date;\n updated: Date;\n updatedBy: string;\n anonymous: boolean;\n status: string;\n}\n\nexport interface RawAnswerVoteEntity {\n answerId: number;\n author: string;\n score: number;\n timestamp: Date;\n}\n\nexport class AnswersStore extends BaseStore {\n constructor(\n protected readonly db: Knex,\n private readonly commentsStore: CommentsStore,\n private readonly postsStore: {\n getPost(\n user_ref: string,\n id: number,\n recordView?: boolean,\n ): Promise<MaybePost>;\n },\n private readonly attachmentsStore: AttachmentsStore,\n ) {\n super(db);\n }\n\n async getAnswers(\n user_ref: string,\n options: AnswersQuery,\n filters?: PermissionCriteria<QetaFilters>,\n opts?: AnswerOptions,\n ): Promise<Answers> {\n const query = this.getAnswerBaseQuery();\n\n if (options.author) {\n query.where('answers.author', '=', options.author);\n }\n\n if (filters) {\n this.parseFilter(filters, query, this.db, 'answer');\n }\n\n if (options.searchQuery) {\n this.applySearchQuery(query, ['answers.content'], options.searchQuery);\n }\n\n if (options.questionId) {\n query.where('answers.postId', '=', options.questionId);\n }\n\n if (options.noVotes) {\n query.whereNull('answer_votes.answerId');\n }\n\n const totalQuery = query.clone();\n\n if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n this.db(totalQuery.as('totalQuery')).count('* as CNT').first(),\n ]);\n\n const rows = results[0] as RawAnswerEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n answers: await this.mapAnswerEntities(rows, user_ref, opts),\n total,\n };\n }\n\n async getAnswer(\n answerId: number,\n user_ref: string,\n options?: AnswerOptions,\n ): Promise<MaybeAnswer> {\n const query = this.getAnswerBaseQuery().where('answers.id', '=', answerId);\n if (options?.filter) {\n this.parseFilter(options.filter, query, this.db, 'answer');\n }\n\n const rows = await query.select();\n if (rows.length === 0) {\n return null;\n }\n return (\n await this.mapAnswerEntities(\n [rows[0] as unknown as RawAnswerEntity],\n user_ref,\n options,\n )\n )[0];\n }\n\n async getPostAnswers(\n postId: number | number[],\n user_ref: string,\n options?: AnswerOptions,\n ): Promise<Answer[]> {\n const { includeStatusFilter = true } = options ?? {};\n const query = this.getAnswerBaseQuery()\n .orderBy('answers.correct', 'desc')\n .orderBy('answers.created');\n\n if (Array.isArray(postId)) {\n query.whereIn('postId', postId);\n } else {\n query.where('postId', '=', postId);\n }\n\n if (includeStatusFilter) {\n query.where('answers.status', '=', 'active');\n }\n\n if (options?.filter) {\n this.parseFilter(options.filter, query, this.db, 'answer');\n }\n\n const rows = await query.select();\n return this.mapAnswerEntities(rows, user_ref, options);\n }\n\n async answerPost(\n user_ref: string,\n questionId: number,\n answer: string,\n created: Date,\n images?: number[],\n anonymous?: boolean,\n options?: AnswerOptions,\n ): Promise<MaybeAnswer> {\n const answers = await this.db\n .insert(\n {\n postId: questionId,\n author: user_ref,\n content: answer,\n created,\n correct: false,\n anonymous: anonymous ?? false,\n },\n ['id'],\n )\n .into('answers')\n .returning('id');\n\n await this.db('posts').where('id', questionId).increment('answersCount', 1);\n\n if (images && images.length > 0) {\n await this.updateAttachments('answerId', answer, images, answers[0].id);\n }\n\n return this.getAnswer(answers[0].id, user_ref, options);\n }\n\n async updateAnswer(\n user_ref: string,\n questionId: number,\n answerId: number,\n answer: string,\n author?: string,\n images?: number[],\n options?: AnswerOptions,\n ): Promise<MaybeAnswer> {\n const query = this.db('answers')\n .where('id', '=', answerId)\n .where('postId', '=', questionId);\n\n await query.update({\n content: answer,\n updatedBy: user_ref,\n updated: new Date(),\n author: author,\n });\n\n if (images) {\n await this.updateAttachments('answerId', answer, images, answerId);\n }\n\n return this.getAnswer(answerId, user_ref, options);\n }\n\n async deleteAnswer(id: number, permanently?: boolean): Promise<boolean> {\n const answer = await this.db('answers')\n .select('postId')\n .where('id', id)\n .first();\n\n if (permanently) {\n const rows = await this.db('answers').where('id', '=', id).delete();\n if (answer && rows > 0) {\n await this.db('posts')\n .where('id', answer.postId)\n .decrement('answersCount', 1);\n }\n return rows > 0;\n }\n const rows = await this.db('answers').where('id', '=', id).update({\n status: 'deleted',\n });\n if (answer && rows > 0) {\n await this.db('posts')\n .where('id', answer.postId)\n .decrement('answersCount', 1);\n }\n return rows > 0;\n }\n\n async voteAnswer(\n user_ref: string,\n answerId: number,\n score: number,\n ): Promise<boolean> {\n await this.db('answer_votes')\n .where('author', '=', user_ref)\n .where('answerId', '=', answerId)\n .delete();\n\n await this.db\n .insert({\n author: user_ref,\n answerId,\n score,\n timestamp: new Date(),\n })\n .into('answer_votes');\n\n await this.db('answers')\n .where('id', '=', answerId)\n .update({\n score: this.db('answer_votes')\n .where('answerId', '=', answerId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n return true;\n }\n\n async deleteAnswerVote(user_ref: string, answerId: number): Promise<boolean> {\n const rows = await this.db('answer_votes')\n .where('author', '=', user_ref)\n .where('answerId', '=', answerId)\n .delete();\n\n if (rows > 0) {\n await this.db('answers')\n .where('id', '=', answerId)\n .update({\n score: this.db('answer_votes')\n .where('answerId', '=', answerId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n }\n return rows > 0;\n }\n\n async markAnswerCorrect(postId: number, answerId: number): Promise<boolean> {\n return this.markAnswer(postId, answerId, true);\n }\n\n async markAnswerIncorrect(\n postId: number,\n answerId: number,\n ): Promise<boolean> {\n return this.markAnswer(postId, answerId, false);\n }\n\n private async markAnswer(\n postId: number,\n answerId: number,\n correct: boolean,\n ): Promise<boolean> {\n if (correct) {\n const exists = await this.db('answers')\n .select('id')\n .where('correct', '=', true)\n .where('postId', '=', postId);\n if (exists && exists.length > 0) {\n return false;\n }\n }\n\n const ret = await this.db('answers')\n .where('answers.id', '=', answerId)\n .where('postId', '=', postId)\n .update({ correct }, ['id']);\n\n if (ret !== undefined && ret?.length > 0) {\n if (correct) {\n await this.db('posts')\n .where('id', '=', postId)\n .increment('correctAnswers', 1);\n } else {\n await this.db('posts')\n .where('id', '=', postId)\n .decrement('correctAnswers', 1);\n }\n }\n\n return ret !== undefined && ret?.length > 0;\n }\n\n private getAnswerBaseQuery() {\n return this.db<RawAnswerEntity>('answers').select('*');\n }\n\n private async mapAnswerEntities(\n rows: RawAnswerEntity[],\n user_ref: string,\n options?: AnswerOptions,\n ): Promise<Answer[]> {\n if (rows.length === 0) {\n return [];\n }\n const answerIds = rows.map(r => r.id);\n const {\n includeVotes = true,\n includeComments = true,\n includePost = true,\n includeExperts = true,\n } = options ?? {};\n const [votes, comments, posts, attachments, experts] = await Promise.all([\n includeVotes\n ? this.db<RawAnswerVoteEntity>('answer_votes')\n .whereIn('answerId', answerIds)\n .select()\n : undefined,\n includeComments\n ? (this.commentsStore.getAnswerComments(\n answerIds as any,\n options?.commentsFilter,\n ) as unknown as Promise<(QetaComment & { answerId: number })[]>)\n : undefined,\n includePost && this.postsStore\n ? Promise.all(\n [...new Set(rows.map((r: RawAnswerEntity) => r.postId))].map(\n (id: number) => this.postsStore.getPost(user_ref, id, false),\n ),\n )\n : undefined,\n this.attachmentsStore.getAttachments(answerIds, 'answerId'),\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('tags', 'tag_experts.tagId', 'tags.id')\n .leftJoin('post_tags', 'post_tags.tagId', 'tags.id')\n .leftJoin('answers', 'answers.postId', 'post_tags.postId')\n .whereIn('answers.id', answerIds)\n .select('answers.id as answerId', 'tag_experts.entityRef')\n : undefined,\n ]);\n\n const votesMap = new Map<number, RawAnswerVoteEntity[]>();\n votes?.forEach((v: RawAnswerVoteEntity) => {\n const ps = votesMap.get(v.answerId) || [];\n ps.push(v);\n votesMap.set(v.answerId, ps);\n });\n\n const commentsMap = new Map<number, QetaComment[]>();\n comments?.forEach(c => {\n const ps = commentsMap.get(c.answerId) || [];\n ps.push(c);\n commentsMap.set(c.answerId, ps);\n });\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.answerId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.answerId, ps);\n });\n\n return rows.map(val => {\n const answerVotes = votesMap.get(val.id) || [];\n return {\n id: val.id,\n postId: val.postId,\n own: val.author === user_ref,\n author:\n val.anonymous && val.author !== user_ref ? 'anonymous' : val.author,\n content: val.content,\n correct: val.correct,\n created: val.created,\n updated: val.updated,\n updatedBy: val.updatedBy,\n status: val.status as AnswerCommentStatus,\n score: this.mapToInteger(val.score),\n votes: answerVotes.map((v: RawAnswerVoteEntity) => ({\n author: v.author,\n score: v.score,\n timestamp: v.timestamp,\n })),\n comments: commentsMap.get(val.id),\n anonymous: val.anonymous,\n post: posts?.find(p => p?.id === val.postId) ?? undefined,\n images: attachmentsMap.get(val.id) || [],\n experts: expertsMap.get(val.id),\n };\n });\n }\n}\n"],"names":["BaseStore","rows"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnswersStore.cjs.js","sources":["../../../src/database/stores/AnswersStore.ts"],"sourcesContent":["import {\n Answer,\n AnswersQuery,\n AnswerCommentStatus,\n Comment as QetaComment,\n PostsQuery,\n} from '@drodil/backstage-plugin-qeta-common';\nimport {\n AnswerOptions,\n Answers,\n MaybeAnswer,\n MaybePost,\n Posts,\n} from '../QetaStore';\nimport { Knex } from 'knex';\nimport { CommentsStore } from './CommentsStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { QetaFilters } from '../../service/util';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport { BaseStore } from './BaseStore';\n\nexport interface RawAnswerEntity {\n id: number;\n postId: number;\n author: string;\n content: string;\n correct: boolean;\n score: number | string;\n created: Date;\n updated: Date;\n updatedBy: string;\n anonymous: boolean;\n status: string;\n}\n\nexport interface RawAnswerVoteEntity {\n answerId: number;\n author: string;\n score: number;\n timestamp: Date;\n}\n\nexport class AnswersStore extends BaseStore {\n constructor(\n protected readonly db: Knex,\n private readonly commentsStore: CommentsStore,\n private readonly postsStore: {\n getPost(\n user_ref: string,\n id: number,\n recordView?: boolean,\n ): Promise<MaybePost>;\n getPosts(user_ref: string, options: PostsQuery): Promise<Posts>;\n },\n private readonly attachmentsStore: AttachmentsStore,\n ) {\n super(db);\n }\n\n async getAnswers(\n user_ref: string,\n options: AnswersQuery,\n filters?: PermissionCriteria<QetaFilters>,\n opts?: AnswerOptions,\n ): Promise<Answers> {\n const query = this.getAnswerBaseQuery();\n\n if (options.author) {\n query.where('answers.author', '=', options.author);\n }\n\n if (filters) {\n this.parseFilter(filters, query, this.db, 'answer');\n }\n\n if (options.searchQuery) {\n this.applySearchQuery(query, ['answers.content'], options.searchQuery);\n }\n\n if (options.questionId) {\n query.where('answers.postId', '=', options.questionId);\n }\n\n if (options.noVotes) {\n query.whereNull('answer_votes.answerId');\n }\n\n const totalQuery = query.clone();\n\n if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n this.db(totalQuery.as('totalQuery')).count('* as CNT').first(),\n ]);\n\n const rows = results[0] as RawAnswerEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n answers: await this.mapAnswerEntities(rows, user_ref, opts),\n total,\n };\n }\n\n async getAnswer(\n answerId: number,\n user_ref: string,\n options?: AnswerOptions,\n ): Promise<MaybeAnswer> {\n const query = this.getAnswerBaseQuery().where('answers.id', '=', answerId);\n if (options?.filter) {\n this.parseFilter(options.filter, query, this.db, 'answer');\n }\n\n const rows = await query.select();\n if (rows.length === 0) {\n return null;\n }\n return (\n await this.mapAnswerEntities(\n [rows[0] as unknown as RawAnswerEntity],\n user_ref,\n options,\n )\n )[0];\n }\n\n async getPostAnswers(\n postId: number | number[],\n user_ref: string,\n options?: AnswerOptions,\n ): Promise<Answer[]> {\n const { includeStatusFilter = true } = options ?? {};\n const query = this.getAnswerBaseQuery()\n .orderBy('answers.correct', 'desc')\n .orderBy('answers.created');\n\n if (Array.isArray(postId)) {\n query.whereIn('postId', postId);\n } else {\n query.where('postId', '=', postId);\n }\n\n if (includeStatusFilter) {\n query.where('answers.status', '=', 'active');\n }\n\n if (options?.filter) {\n this.parseFilter(options.filter, query, this.db, 'answer');\n }\n\n const rows = await query.select();\n return this.mapAnswerEntities(rows, user_ref, options);\n }\n\n async answerPost(\n user_ref: string,\n questionId: number,\n answer: string,\n created: Date,\n images?: number[],\n anonymous?: boolean,\n options?: AnswerOptions,\n ): Promise<MaybeAnswer> {\n const answers = await this.db\n .insert(\n {\n postId: questionId,\n author: user_ref,\n content: answer,\n created,\n correct: false,\n anonymous: anonymous ?? false,\n },\n ['id'],\n )\n .into('answers')\n .returning('id');\n\n await this.db('posts').where('id', questionId).increment('answersCount', 1);\n\n if (images && images.length > 0) {\n await this.updateAttachments('answerId', answer, images, answers[0].id);\n }\n\n return this.getAnswer(answers[0].id, user_ref, options);\n }\n\n async updateAnswer(\n user_ref: string,\n questionId: number,\n answerId: number,\n answer: string,\n author?: string,\n images?: number[],\n options?: AnswerOptions,\n ): Promise<MaybeAnswer> {\n const query = this.db('answers')\n .where('id', '=', answerId)\n .where('postId', '=', questionId);\n\n await query.update({\n content: answer,\n updatedBy: user_ref,\n updated: new Date(),\n author: author,\n });\n\n if (images) {\n await this.updateAttachments('answerId', answer, images, answerId);\n }\n\n return this.getAnswer(answerId, user_ref, options);\n }\n\n async deleteAnswer(id: number, permanently?: boolean): Promise<boolean> {\n const answer = await this.db('answers')\n .select('postId')\n .where('id', id)\n .first();\n\n if (permanently) {\n const rows = await this.db('answers').where('id', '=', id).delete();\n if (answer && rows > 0) {\n await this.db('posts')\n .where('id', answer.postId)\n .decrement('answersCount', 1);\n }\n return rows > 0;\n }\n const rows = await this.db('answers').where('id', '=', id).update({\n status: 'deleted',\n });\n if (answer && rows > 0) {\n await this.db('posts')\n .where('id', answer.postId)\n .decrement('answersCount', 1);\n }\n return rows > 0;\n }\n\n async voteAnswer(\n user_ref: string,\n answerId: number,\n score: number,\n ): Promise<boolean> {\n await this.db('answer_votes')\n .where('author', '=', user_ref)\n .where('answerId', '=', answerId)\n .delete();\n\n await this.db\n .insert({\n author: user_ref,\n answerId,\n score,\n timestamp: new Date(),\n })\n .into('answer_votes');\n\n await this.db('answers')\n .where('id', '=', answerId)\n .update({\n score: this.db('answer_votes')\n .where('answerId', '=', answerId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n return true;\n }\n\n async deleteAnswerVote(user_ref: string, answerId: number): Promise<boolean> {\n const rows = await this.db('answer_votes')\n .where('author', '=', user_ref)\n .where('answerId', '=', answerId)\n .delete();\n\n if (rows > 0) {\n await this.db('answers')\n .where('id', '=', answerId)\n .update({\n score: this.db('answer_votes')\n .where('answerId', '=', answerId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n }\n return rows > 0;\n }\n\n async markAnswerCorrect(postId: number, answerId: number): Promise<boolean> {\n return this.markAnswer(postId, answerId, true);\n }\n\n async markAnswerIncorrect(\n postId: number,\n answerId: number,\n ): Promise<boolean> {\n return this.markAnswer(postId, answerId, false);\n }\n\n private async markAnswer(\n postId: number,\n answerId: number,\n correct: boolean,\n ): Promise<boolean> {\n if (correct) {\n const exists = await this.db('answers')\n .select('id')\n .where('correct', '=', true)\n .where('postId', '=', postId);\n if (exists && exists.length > 0) {\n return false;\n }\n }\n\n const ret = await this.db('answers')\n .where('answers.id', '=', answerId)\n .where('postId', '=', postId)\n .update({ correct }, ['id']);\n\n if (ret !== undefined && ret?.length > 0) {\n if (correct) {\n await this.db('posts')\n .where('id', '=', postId)\n .increment('correctAnswers', 1);\n } else {\n await this.db('posts')\n .where('id', '=', postId)\n .decrement('correctAnswers', 1);\n }\n }\n\n return ret !== undefined && ret?.length > 0;\n }\n\n private getAnswerBaseQuery() {\n return this.db<RawAnswerEntity>('answers').select('*');\n }\n\n private async mapAnswerEntities(\n rows: RawAnswerEntity[],\n user_ref: string,\n options?: AnswerOptions,\n ): Promise<Answer[]> {\n if (rows.length === 0) {\n return [];\n }\n const answerIds = rows.map(r => r.id);\n const {\n includeVotes = true,\n includeComments = true,\n includePost = true,\n includeExperts = true,\n } = options ?? {};\n const [votes, comments, posts, attachments, experts] = await Promise.all([\n includeVotes\n ? this.db<RawAnswerVoteEntity>('answer_votes')\n .whereIn('answerId', answerIds)\n .select()\n : undefined,\n includeComments\n ? (this.commentsStore.getAnswerComments(\n answerIds as any,\n options?.commentsFilter,\n ) as unknown as Promise<(QetaComment & { answerId: number })[]>)\n : undefined,\n includePost && this.postsStore\n ? this.postsStore\n .getPosts(user_ref, {\n ids: [...new Set(rows.map((r: RawAnswerEntity) => r.postId))],\n limit: rows.length,\n })\n .then(p => p.posts)\n : undefined,\n this.attachmentsStore.getAttachments(answerIds, 'answerId'),\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('tags', 'tag_experts.tagId', 'tags.id')\n .leftJoin('post_tags', 'post_tags.tagId', 'tags.id')\n .leftJoin('answers', 'answers.postId', 'post_tags.postId')\n .whereIn('answers.id', answerIds)\n .select('answers.id as answerId', 'tag_experts.entityRef')\n : undefined,\n ]);\n\n const votesMap = new Map<number, RawAnswerVoteEntity[]>();\n votes?.forEach((v: RawAnswerVoteEntity) => {\n const ps = votesMap.get(v.answerId) || [];\n ps.push(v);\n votesMap.set(v.answerId, ps);\n });\n\n const commentsMap = new Map<number, QetaComment[]>();\n comments?.forEach(c => {\n const ps = commentsMap.get(c.answerId) || [];\n ps.push(c);\n commentsMap.set(c.answerId, ps);\n });\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.answerId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.answerId, ps);\n });\n\n return rows.map(val => {\n const answerVotes = votesMap.get(val.id) || [];\n return {\n id: val.id,\n postId: val.postId,\n own: val.author === user_ref,\n author:\n val.anonymous && val.author !== user_ref ? 'anonymous' : val.author,\n content: val.content,\n correct: val.correct,\n created: val.created,\n updated: val.updated,\n updatedBy: val.updatedBy,\n status: val.status as AnswerCommentStatus,\n score: this.mapToInteger(val.score),\n votes: answerVotes.map((v: RawAnswerVoteEntity) => ({\n author: v.author,\n score: v.score,\n timestamp: v.timestamp,\n })),\n comments: commentsMap.get(val.id),\n anonymous: val.anonymous,\n post: posts?.find(p => p?.id === val.postId) ?? undefined,\n images: attachmentsMap.get(val.id) || [],\n experts: expertsMap.get(val.id),\n };\n });\n }\n}\n"],"names":["BaseStore","rows"],"mappings":"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"}
|
|
@@ -533,11 +533,20 @@ class PostsStore extends BaseStore.BaseStore {
|
|
|
533
533
|
});
|
|
534
534
|
}
|
|
535
535
|
getPostsBaseQuery(user, opts) {
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
536
|
+
const q = this.db("posts").leftJoin("user_favorite", function joinUserFavorite() {
|
|
537
|
+
this.on("posts.id", "=", "user_favorite.postId").andOnVal(
|
|
538
|
+
"user_favorite.user",
|
|
539
|
+
"=",
|
|
540
|
+
user
|
|
541
|
+
);
|
|
542
|
+
}).select(
|
|
543
|
+
"posts.*",
|
|
544
|
+
this.db.raw(
|
|
545
|
+
`CASE WHEN user_favorite.${this.db.client.config.client === "pg" ? '"postId"' : "postId"} IS NOT NULL THEN 1 ELSE 0 END as favorite`
|
|
546
|
+
)
|
|
547
|
+
);
|
|
539
548
|
if (opts?.favorite) {
|
|
540
|
-
q.
|
|
549
|
+
q.whereNotNull("user_favorite.postId");
|
|
541
550
|
}
|
|
542
551
|
return q;
|
|
543
552
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostsStore.cjs.js","sources":["../../../src/database/stores/PostsStore.ts"],"sourcesContent":["import {\n AIResponse,\n Answer,\n Comment as QetaComment,\n filterTags,\n Post,\n PostsQuery,\n PostStatus,\n PostType,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { MaybePost, PostOptions, Posts } from '../QetaStore';\nimport { QetaFilters } from '../../service/util';\nimport { Knex } from 'knex';\nimport { AnswersStore } from './AnswersStore';\nimport { CommentsStore } from './CommentsStore';\nimport { TagsStore } from './TagsStore';\nimport { EntitiesStore } from './EntitiesStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport { TAGS } from '../../tagDb';\nimport { BaseStore } from './BaseStore';\nimport { TagDatabase } from '@drodil/backstage-plugin-qeta-node';\n\nexport interface RawPostEntity {\n id: number;\n author: string;\n title: string;\n content: string;\n status: string;\n created: Date | string;\n updated: Date | string;\n updatedBy: string;\n score: number | string;\n views: number | string;\n answersCount: number | string;\n correctAnswers: number | string;\n commentsCount: number | string;\n favorite: number | string;\n trend: number | string;\n anonymous: boolean;\n type: 'question' | 'article' | 'link';\n headerImage: string;\n url: string | null;\n published: Date | string | null;\n}\n\nexport interface RawPostVoteEntity {\n postId: number;\n author: string;\n score: number;\n timestamp: Date;\n}\n\nexport interface RawPostAIAnswer {\n id: number;\n answer: string;\n created: Date;\n}\n\nexport class PostsStore extends BaseStore {\n private answersStore?: AnswersStore;\n\n constructor(\n protected readonly db: Knex,\n private readonly commentsStore: CommentsStore,\n private readonly tagsStore: TagsStore,\n private readonly entitiesStore: EntitiesStore,\n private readonly attachmentsStore: AttachmentsStore,\n private readonly tagDatabase?: TagDatabase,\n ) {\n super(db);\n }\n\n setAnswersStore(answersStore: AnswersStore) {\n this.answersStore = answersStore;\n }\n\n async getAIAnswer(postId: number): Promise<AIResponse | null> {\n const row = await this.db('ai_answers').where('postId', postId).first();\n if (!row) {\n return null;\n }\n return {\n answer: row.answer,\n created: row.created,\n };\n }\n\n async saveAIAnswer(postId: number, response: AIResponse): Promise<void> {\n await this.db\n .insert({\n postId,\n answer: response.answer,\n created: response.created,\n })\n .into('ai_answers')\n .onConflict('postId')\n .merge();\n }\n\n async deleteAIAnswer(postId: number): Promise<boolean> {\n const rows = await this.db('ai_answers').where('postId', postId).delete();\n return rows > 0;\n }\n\n async getPosts(\n user_ref: string,\n options: PostsQuery,\n filters?: PermissionCriteria<QetaFilters>,\n opts?: PostOptions,\n ): Promise<Posts> {\n const { includeTotal = true, includeDraftFilter = true } = opts ?? {};\n const query = this.getPostsBaseQuery(user_ref, options);\n if (options.type) {\n query.where('posts.type', options.type);\n }\n\n if (options.fromDate && options.toDate) {\n query.whereBetween('posts.created', [\n `${options.fromDate} 00:00:00.000+00`,\n `${options.toDate} 23:59:59.999+00`,\n ]);\n } else if (options.fromDate) {\n query.where('posts.created', '>=', `${options.fromDate} 00:00:00.000+00`);\n } else if (options.toDate) {\n query.where('posts.created', '<=', `${options.toDate} 23:59:59.999+00`);\n }\n\n if (options.author) {\n if (Array.isArray(options.author)) {\n query.whereIn('posts.author', options.author);\n } else {\n query.where('posts.author', '=', options.author);\n }\n }\n\n if (options.excludeAuthors) {\n query.whereNotIn('posts.author', options.excludeAuthors);\n }\n\n if (options.status) {\n if (options.status === 'draft') {\n query.where('posts.author', '=', user_ref);\n }\n query.where('posts.status', '=', options.status);\n } else if (includeDraftFilter) {\n query.where(q => {\n q.where('posts.status', 'active').orWhere(q2 => {\n q2.where('posts.status', 'draft').where(\n 'posts.author',\n '=',\n user_ref,\n );\n });\n });\n }\n\n if (filters) {\n this.parseFilter(filters, query, this.db);\n }\n\n if (options.searchQuery) {\n this.applySearchQuery(\n query,\n ['posts.title', 'posts.content'],\n options.searchQuery,\n );\n }\n\n if (options.tags) {\n const tags = filterTags(options.tags);\n if (options.tagsRelation === 'or') {\n query.innerJoin('post_tags', 'posts.id', 'post_tags.postId');\n query.innerJoin('tags', 'post_tags.tagId', 'tags.id');\n query.whereIn('tags.tag', tags);\n } else {\n tags?.forEach((t: string, i: number) => {\n query.innerJoin(`post_tags AS qt${i}`, 'posts.id', `qt${i}.postId`);\n query.innerJoin(`tags AS t${i}`, `qt${i}.tagId`, `t${i}.id`);\n query.where(`t${i}.tag`, '=', t);\n });\n }\n }\n\n if (options.entities) {\n const entityValues = Array.isArray(options.entities)\n ? options.entities\n : [options.entities];\n if (options.entitiesRelation === 'or') {\n query\n .innerJoin('post_entities', 'posts.id', 'post_entities.postId')\n .innerJoin('entities', 'post_entities.entityId', 'entities.id')\n .whereIn('entities.entity_ref', entityValues);\n } else {\n entityValues.forEach((t: string, i: number) => {\n query.innerJoin(\n `post_entities AS pe${i}`,\n 'posts.id',\n `pe${i}.postId`,\n );\n query.innerJoin(`entities AS e${i}`, `pe${i}.entityId`, `e${i}.id`);\n query.where(`e${i}.entity_ref`, '=', t);\n });\n }\n }\n\n if (options.collectionId) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.where('collection_posts.collectionId', options.collectionId);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (opts?.collectionIds) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.whereIn('collection_posts.collectionId', opts.collectionIds);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (options.orderBy === 'rank') {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.select('collection_posts.rank');\n }\n if (options.orderBy === 'rank') {\n query.groupBy('posts.id', 'collection_posts.rank');\n }\n\n if (options.noAnswers) {\n query.where('answersCount', 0);\n }\n\n if (options.hasAnswers) {\n query.where('answersCount', '>', 0);\n }\n\n if (options.noCorrectAnswer) {\n query.where('correctAnswers', 0);\n }\n\n if (options.noVotes) {\n query.where('score', 0);\n }\n\n if (options.favorite) {\n query.where('user_favorite.user', '=', user_ref);\n query.whereNotNull('user_favorite.postId');\n }\n\n if (options.includeTrend || options.orderBy === 'trend') {\n query.select(\n this.db.raw(\n `(\n posts.score * 200 + \n posts.\"answersCount\" * 100 +\n posts.\"favoritesCount\" * 50 +\n posts.views * 10 +\n posts.\"commentsCount\" * 30\n ) / \n POWER(\n EXTRACT(EPOCH FROM (now() - posts.created)) / 172800 + 1,\n 1.5\n ) as trend`,\n ),\n );\n }\n\n if (options.ids) {\n query.whereIn('posts.id', options.ids);\n }\n\n const totalQuery = query.clone();\n\n if (options.random) {\n query.orderByRaw('RANDOM()');\n } else if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n } else {\n query.orderBy('created', 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n includeTotal\n ? this.db(totalQuery.as('totalQuery')).count('* as CNT').first()\n : undefined,\n ]);\n const rows = results[0] as RawPostEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n posts: await this.mapPostEntities(rows, user_ref, {\n ...opts,\n includeAnswers: options.includeAnswers ?? opts?.includeAnswers,\n includeVotes: options.includeVotes ?? opts?.includeVotes,\n includeEntities: options.includeEntities ?? opts?.includeEntities,\n includeAttachments:\n options.includeAttachments ?? opts?.includeAttachments,\n includeExperts: options.includeExperts ?? opts?.includeExperts,\n }),\n total,\n };\n }\n\n async getPost(\n user_ref: string,\n id: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const rows = await this.getPostsBaseQuery(user_ref).where(\n 'posts.id',\n '=',\n id,\n );\n\n if (!rows || rows.length === 0) {\n return null;\n }\n const post = rows[0] as unknown as RawPostEntity;\n\n if ((recordView === undefined || recordView) && post.status === 'active') {\n this.recordPostView(id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async getPostByAnswerId(\n user_ref: string,\n answerId: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const rows = await this.getPostsBaseQuery(user_ref)\n .join('answers', 'posts.id', 'answers.postId')\n .where('answers.id', '=', answerId)\n .select('posts.*');\n if (!rows || rows.length === 0) {\n return null;\n }\n if (recordView === undefined || recordView) {\n this.recordPostView(rows[0].id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async createPost(options: {\n user_ref: string;\n title: string;\n content: string;\n created: Date;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n anonymous?: boolean;\n type?: PostType;\n headerImage?: string;\n url?: string;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<Post> {\n const {\n user_ref,\n title,\n content,\n author,\n created,\n tags,\n entities,\n images,\n anonymous,\n type = 'question',\n headerImage,\n url,\n opts,\n status = 'active',\n } = options;\n const posts = await this.db\n .insert(\n {\n author: author ?? user_ref,\n title,\n content,\n created,\n anonymous: anonymous ?? false,\n type: type ?? 'question',\n headerImage,\n url,\n status,\n published: status === 'active' ? created : null,\n },\n ['id'],\n )\n .into('posts')\n .returning([\n 'id',\n 'author',\n 'title',\n 'content',\n 'created',\n 'anonymous',\n 'type',\n 'status',\n 'url',\n ]);\n\n await Promise.all([\n this.addTags(posts[0].id, tags),\n this.addEntities(posts[0].id, entities),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n posts[0].id,\n headerImage,\n );\n\n return (await this.mapPostEntities([posts[0]], user_ref, opts))[0];\n }\n\n async updatePost(options: {\n id: number;\n user_ref: string;\n title?: string;\n content?: string;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n headerImage?: string;\n url?: string;\n setUpdatedBy?: boolean;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<MaybePost> {\n const {\n id,\n user_ref,\n title,\n content,\n author,\n tags,\n entities,\n images,\n headerImage,\n url,\n setUpdatedBy = true,\n opts,\n status = 'active',\n } = options;\n\n // Check if this is a transition from draft to active\n const currentPost = await this.db('posts')\n .select('status', 'published')\n .where('id', '=', id)\n .first();\n\n const shouldSetPublished =\n currentPost &&\n currentPost.status === 'draft' &&\n status === 'active' &&\n !currentPost.published;\n\n const query = this.db('posts').where('posts.id', '=', id);\n const rows = await query.update({\n title,\n content,\n headerImage,\n author,\n url,\n updatedBy: setUpdatedBy ? user_ref : undefined,\n updated: setUpdatedBy ? new Date() : undefined,\n status,\n published: shouldSetPublished ? new Date() : undefined,\n });\n\n if (!rows) {\n return null;\n }\n\n await Promise.all([\n this.addTags(id, tags, true),\n this.addEntities(id, entities, true),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n id,\n headerImage,\n );\n\n return await this.getPost(user_ref, id, false, opts);\n }\n\n async deletePost(id: number, permanently?: boolean): Promise<boolean> {\n if (permanently) {\n const rows = await this.db('posts').where('id', '=', id).delete();\n return rows > 0;\n }\n const rows = await this.db('posts').where('id', '=', id).update({\n status: 'deleted',\n });\n return rows > 0;\n }\n\n async votePost(\n user_ref: string,\n postId: number,\n score: number,\n ): Promise<boolean> {\n await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n await this.db\n .insert({\n author: user_ref,\n postId,\n score,\n timestamp: new Date(),\n })\n .into('post_votes');\n\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n return true;\n }\n\n async getPostVote(\n user_ref: string,\n postId: number,\n ): Promise<RawPostVoteEntity | undefined> {\n return await this.db<RawPostVoteEntity>('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .first();\n }\n\n async deletePostVote(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n if (rows > 0) {\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n }\n return rows > 0;\n }\n\n async favoritePost(user_ref: string, postId: number): Promise<boolean> {\n await this.db\n .insert({\n user: user_ref,\n postId,\n })\n .into('user_favorite');\n await this.db('posts').where('id', postId).increment('favoritesCount', 1);\n return true;\n }\n\n async unfavoritePost(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('user_favorite')\n .where('user', user_ref)\n .where('postId', postId)\n .delete();\n if (rows > 0) {\n await this.db('posts').where('id', postId).decrement('favoritesCount', 1);\n }\n return true;\n }\n\n async getUsersWhoFavoritedPost(postId: number): Promise<string[]> {\n const users = await this.db('user_favorite')\n .where('postId', postId)\n .select('user');\n return users.map(user => user.user);\n }\n\n private async mapPostEntities(\n rows: RawPostEntity[],\n user_ref: string,\n options?: PostOptions,\n ): Promise<Post[]> {\n if (rows.length === 0) {\n return [];\n }\n\n const postIds = rows.map(r => r.id);\n const {\n includeTags = true,\n includeAnswers = true,\n includeVotes = true,\n includeEntities = true,\n includeComments = true,\n includeAttachments = true,\n includeExperts = true,\n includeCollections = true,\n } = options ?? {};\n\n const [\n tags,\n votes,\n entities,\n comments,\n attachments,\n experts,\n answers,\n collections,\n ] = await Promise.all([\n includeTags\n ? this.tagsStore.getRelatedTags(\n postIds,\n 'post_tags',\n 'postId',\n options?.tagsFilter,\n )\n : undefined,\n includeVotes\n ? this.db<RawPostVoteEntity>('post_votes')\n .whereIn('postId', postIds)\n .select()\n : undefined,\n includeEntities\n ? this.entitiesStore.getRelatedEntities(\n postIds,\n 'post_entities',\n 'postId',\n )\n : undefined,\n includeComments\n ? this.commentsStore.getPostComments(postIds, options?.commentsFilter)\n : undefined,\n includeAttachments\n ? this.attachmentsStore.getAttachments(postIds, 'postId')\n : undefined,\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('post_tags', 'tag_experts.tagId', 'post_tags.tagId')\n .whereIn('post_tags.postId', postIds)\n .select('post_tags.postId', 'tag_experts.entityRef')\n : undefined,\n includeAnswers && this.answersStore\n ? this.answersStore.getPostAnswers(postIds, user_ref, {\n ...options,\n includePost: false,\n filter: options?.answersFilter,\n })\n : undefined,\n includeCollections\n ? this.db('collection_posts')\n .whereIn('postId', postIds)\n .select('postId', 'collectionId')\n : undefined,\n ]);\n\n const tagsMap = tags ?? new Map<number, string[]>();\n\n const votesMap = new Map<number, RawPostVoteEntity[]>();\n votes?.forEach((v: RawPostVoteEntity) => {\n const ps = votesMap.get(v.postId) || [];\n ps.push(v);\n votesMap.set(v.postId, ps);\n });\n\n const entitiesMap = entities ?? new Map<number, string[]>();\n\n const commentsMap = new Map<number, QetaComment[]>();\n (comments as unknown as (QetaComment & { postId: number })[])?.forEach(\n c => {\n const ps = commentsMap.get(c.postId) || [];\n ps.push(c);\n commentsMap.set(c.postId, ps);\n },\n );\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.postId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.postId, ps);\n });\n\n const answersMap = new Map<number, Answer[]>();\n answers?.forEach((a: Answer) => {\n const ps = answersMap.get(a.postId) || [];\n ps.push(a);\n answersMap.set(a.postId, ps);\n });\n\n const collectionsMap = new Map<number, number[]>();\n (collections as any)?.forEach((c: any) => {\n const cs = collectionsMap.get(c.postId) || [];\n cs.push(c.collectionId);\n collectionsMap.set(c.postId, cs);\n });\n\n return rows.map(val => {\n const postVotes = votesMap.get(val.id) || [];\n return {\n id: val.id,\n author:\n val.anonymous && val.author !== user_ref ? 'anonymous' : val.author,\n own: val.author === user_ref,\n title: val.title,\n content: val.content,\n created: val.created as Date,\n updated: val.updated as Date,\n updatedBy: val.updatedBy,\n status: val.status as PostStatus,\n score: this.mapToInteger(val.score),\n views: this.mapToInteger(val.views),\n answersCount: this.mapToInteger(val.answersCount),\n correctAnswer: this.mapToBoolean(val.correctAnswers),\n commentsCount: this.mapToInteger(val.commentsCount),\n favorite: this.mapToInteger(val.favorite) > 0,\n tags: tagsMap.get(val.id),\n answers: answersMap.get(val.id),\n votes: postVotes.map(v => ({\n author: v.author,\n score: v.score,\n timestamp: v.timestamp,\n })),\n entities: entitiesMap.get(val.id),\n trend: this.mapToInteger(val.trend),\n comments: commentsMap.get(val.id),\n ownVote: postVotes.find(v => v.author === user_ref)?.score,\n anonymous: val.anonymous,\n type: val.type,\n headerImage: val.headerImage,\n url: val.url ?? undefined,\n images: attachmentsMap.get(val.id),\n experts: expertsMap.get(val.id),\n published: val.published ? (val.published as Date) : undefined,\n collectionIds: collectionsMap.get(val.id),\n };\n });\n }\n\n private getPostsBaseQuery(user: string, opts?: PostsQuery) {\n const postRef = this.db.ref('posts.id');\n\n const favorite = this.db('user_favorite')\n .where('user_favorite.user', '=', user)\n .where('user_favorite.postId', postRef)\n .count('*')\n .as('favorite');\n\n const q = this.db<RawPostEntity>('posts').select('posts.*', favorite);\n if (opts?.favorite) {\n q.leftJoin('user_favorite', 'user_favorite.postId', 'posts.id');\n }\n return q;\n }\n\n private async recordPostView(\n postId: number,\n user_ref: string,\n ): Promise<void> {\n await this.db\n .insert({\n author: user_ref,\n postId,\n timestamp: new Date(),\n })\n .into('post_views');\n\n await this.db('posts').where('id', postId).increment('views', 1);\n }\n\n private async addTags(\n id: number,\n tagsInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_tags',\n columnName: string = 'postId',\n ) {\n const tags = filterTags(tagsInput);\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n if (!tags || tags.length === 0) {\n return;\n }\n const existingTags = await this.db('tags')\n .whereIn('tag', tags)\n .returning('id')\n .select();\n const newTags = tags.filter(t => !existingTags.some(e => e.tag === t));\n const allTags: Record<string, string> = {\n ...TAGS,\n ...(await this.tagDatabase?.getTags()),\n };\n\n const tagIds = (\n await Promise.all(\n [...new Set(newTags)].map(async tag => {\n const trimmed = tag.trim();\n const description = trimmed in allTags ? allTags[trimmed] : undefined;\n\n return this.db\n .insert({ tag: trimmed, description })\n .into('tags')\n .returning('id')\n .onConflict('tag')\n .ignore();\n }),\n )\n )\n .flat()\n .map(tag => tag.id)\n .concat(existingTags.map(t => t.id));\n\n await Promise.all(\n tagIds.map(async tagId => {\n await this.db\n .insert({ [columnName]: id, tagId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n\n private async addEntities(\n id: number,\n entitiesInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_entities',\n columnName: string = 'postId',\n ) {\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n const regex = /\\w+:\\w+\\/\\w+/;\n const entities =\n entitiesInput\n ?.filter(t => regex.test(t))\n .map(t => t.toLowerCase())\n .filter(t => t.length > 0) ?? [];\n\n if (!entities || entities.length === 0) {\n return;\n }\n\n const existingEntities = await this.db('entities')\n .whereIn('entity_ref', entities)\n .returning('id')\n .select();\n const newEntities = entities.filter(\n t => !existingEntities.some(e => e.entity_ref === t),\n );\n\n const entityIds = (\n await Promise.all(\n [...new Set(newEntities)].map(async entityRef =>\n this.db\n .insert({ entity_ref: entityRef })\n .into('entities')\n .returning('id')\n .onConflict('entity_ref')\n .ignore(),\n ),\n )\n )\n .flat()\n .map(entity => entity.id)\n .concat(existingEntities.map(c => c.id));\n\n await Promise.all(\n entityIds.map(async entityId => {\n await this.db\n .insert({ [columnName]: id, entityId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n}\n"],"names":["BaseStore","filterTags","rows","TAGS"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PostsStore.cjs.js","sources":["../../../src/database/stores/PostsStore.ts"],"sourcesContent":["import {\n AIResponse,\n Answer,\n Comment as QetaComment,\n filterTags,\n Post,\n PostsQuery,\n PostStatus,\n PostType,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { MaybePost, PostOptions, Posts } from '../QetaStore';\nimport { QetaFilters } from '../../service/util';\nimport { Knex } from 'knex';\nimport { AnswersStore } from './AnswersStore';\nimport { CommentsStore } from './CommentsStore';\nimport { TagsStore } from './TagsStore';\nimport { EntitiesStore } from './EntitiesStore';\nimport { AttachmentsStore } from './AttachmentsStore';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport { TAGS } from '../../tagDb';\nimport { BaseStore } from './BaseStore';\nimport { TagDatabase } from '@drodil/backstage-plugin-qeta-node';\n\nexport interface RawPostEntity {\n id: number;\n author: string;\n title: string;\n content: string;\n status: string;\n created: Date | string;\n updated: Date | string;\n updatedBy: string;\n score: number | string;\n views: number | string;\n answersCount: number | string;\n correctAnswers: number | string;\n commentsCount: number | string;\n favorite: number | string;\n trend: number | string;\n anonymous: boolean;\n type: 'question' | 'article' | 'link';\n headerImage: string;\n url: string | null;\n published: Date | string | null;\n}\n\nexport interface RawPostVoteEntity {\n postId: number;\n author: string;\n score: number;\n timestamp: Date;\n}\n\nexport interface RawPostAIAnswer {\n id: number;\n answer: string;\n created: Date;\n}\n\nexport class PostsStore extends BaseStore {\n private answersStore?: AnswersStore;\n\n constructor(\n protected readonly db: Knex,\n private readonly commentsStore: CommentsStore,\n private readonly tagsStore: TagsStore,\n private readonly entitiesStore: EntitiesStore,\n private readonly attachmentsStore: AttachmentsStore,\n private readonly tagDatabase?: TagDatabase,\n ) {\n super(db);\n }\n\n setAnswersStore(answersStore: AnswersStore) {\n this.answersStore = answersStore;\n }\n\n async getAIAnswer(postId: number): Promise<AIResponse | null> {\n const row = await this.db('ai_answers').where('postId', postId).first();\n if (!row) {\n return null;\n }\n return {\n answer: row.answer,\n created: row.created,\n };\n }\n\n async saveAIAnswer(postId: number, response: AIResponse): Promise<void> {\n await this.db\n .insert({\n postId,\n answer: response.answer,\n created: response.created,\n })\n .into('ai_answers')\n .onConflict('postId')\n .merge();\n }\n\n async deleteAIAnswer(postId: number): Promise<boolean> {\n const rows = await this.db('ai_answers').where('postId', postId).delete();\n return rows > 0;\n }\n\n async getPosts(\n user_ref: string,\n options: PostsQuery,\n filters?: PermissionCriteria<QetaFilters>,\n opts?: PostOptions,\n ): Promise<Posts> {\n const { includeTotal = true, includeDraftFilter = true } = opts ?? {};\n const query = this.getPostsBaseQuery(user_ref, options);\n if (options.type) {\n query.where('posts.type', options.type);\n }\n\n if (options.fromDate && options.toDate) {\n query.whereBetween('posts.created', [\n `${options.fromDate} 00:00:00.000+00`,\n `${options.toDate} 23:59:59.999+00`,\n ]);\n } else if (options.fromDate) {\n query.where('posts.created', '>=', `${options.fromDate} 00:00:00.000+00`);\n } else if (options.toDate) {\n query.where('posts.created', '<=', `${options.toDate} 23:59:59.999+00`);\n }\n\n if (options.author) {\n if (Array.isArray(options.author)) {\n query.whereIn('posts.author', options.author);\n } else {\n query.where('posts.author', '=', options.author);\n }\n }\n\n if (options.excludeAuthors) {\n query.whereNotIn('posts.author', options.excludeAuthors);\n }\n\n if (options.status) {\n if (options.status === 'draft') {\n query.where('posts.author', '=', user_ref);\n }\n query.where('posts.status', '=', options.status);\n } else if (includeDraftFilter) {\n query.where(q => {\n q.where('posts.status', 'active').orWhere(q2 => {\n q2.where('posts.status', 'draft').where(\n 'posts.author',\n '=',\n user_ref,\n );\n });\n });\n }\n\n if (filters) {\n this.parseFilter(filters, query, this.db);\n }\n\n if (options.searchQuery) {\n this.applySearchQuery(\n query,\n ['posts.title', 'posts.content'],\n options.searchQuery,\n );\n }\n\n if (options.tags) {\n const tags = filterTags(options.tags);\n if (options.tagsRelation === 'or') {\n query.innerJoin('post_tags', 'posts.id', 'post_tags.postId');\n query.innerJoin('tags', 'post_tags.tagId', 'tags.id');\n query.whereIn('tags.tag', tags);\n } else {\n tags?.forEach((t: string, i: number) => {\n query.innerJoin(`post_tags AS qt${i}`, 'posts.id', `qt${i}.postId`);\n query.innerJoin(`tags AS t${i}`, `qt${i}.tagId`, `t${i}.id`);\n query.where(`t${i}.tag`, '=', t);\n });\n }\n }\n\n if (options.entities) {\n const entityValues = Array.isArray(options.entities)\n ? options.entities\n : [options.entities];\n if (options.entitiesRelation === 'or') {\n query\n .innerJoin('post_entities', 'posts.id', 'post_entities.postId')\n .innerJoin('entities', 'post_entities.entityId', 'entities.id')\n .whereIn('entities.entity_ref', entityValues);\n } else {\n entityValues.forEach((t: string, i: number) => {\n query.innerJoin(\n `post_entities AS pe${i}`,\n 'posts.id',\n `pe${i}.postId`,\n );\n query.innerJoin(`entities AS e${i}`, `pe${i}.entityId`, `e${i}.id`);\n query.where(`e${i}.entity_ref`, '=', t);\n });\n }\n }\n\n if (options.collectionId) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.where('collection_posts.collectionId', options.collectionId);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (opts?.collectionIds) {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.whereIn('collection_posts.collectionId', opts.collectionIds);\n if (options.orderBy === 'rank') {\n query.select('collection_posts.rank');\n }\n } else if (options.orderBy === 'rank') {\n query.innerJoin(\n 'collection_posts',\n 'posts.id',\n 'collection_posts.postId',\n );\n query.select('collection_posts.rank');\n }\n if (options.orderBy === 'rank') {\n query.groupBy('posts.id', 'collection_posts.rank');\n }\n\n if (options.noAnswers) {\n query.where('answersCount', 0);\n }\n\n if (options.hasAnswers) {\n query.where('answersCount', '>', 0);\n }\n\n if (options.noCorrectAnswer) {\n query.where('correctAnswers', 0);\n }\n\n if (options.noVotes) {\n query.where('score', 0);\n }\n\n if (options.favorite) {\n query.where('user_favorite.user', '=', user_ref);\n query.whereNotNull('user_favorite.postId');\n }\n\n if (options.includeTrend || options.orderBy === 'trend') {\n query.select(\n this.db.raw(\n `(\n posts.score * 200 + \n posts.\"answersCount\" * 100 +\n posts.\"favoritesCount\" * 50 +\n posts.views * 10 +\n posts.\"commentsCount\" * 30\n ) / \n POWER(\n EXTRACT(EPOCH FROM (now() - posts.created)) / 172800 + 1,\n 1.5\n ) as trend`,\n ),\n );\n }\n\n if (options.ids) {\n query.whereIn('posts.id', options.ids);\n }\n\n const totalQuery = query.clone();\n\n if (options.random) {\n query.orderByRaw('RANDOM()');\n } else if (options.orderBy) {\n query.orderBy(options.orderBy, options.order ? options.order : 'desc');\n } else {\n query.orderBy('created', 'desc');\n }\n\n if (options.limit) {\n query.limit(options.limit);\n }\n\n if (options.offset) {\n query.offset(options.offset);\n }\n\n const results = await Promise.all([\n query,\n includeTotal\n ? this.db(totalQuery.as('totalQuery')).count('* as CNT').first()\n : undefined,\n ]);\n const rows = results[0] as RawPostEntity[];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n posts: await this.mapPostEntities(rows, user_ref, {\n ...opts,\n includeAnswers: options.includeAnswers ?? opts?.includeAnswers,\n includeVotes: options.includeVotes ?? opts?.includeVotes,\n includeEntities: options.includeEntities ?? opts?.includeEntities,\n includeAttachments:\n options.includeAttachments ?? opts?.includeAttachments,\n includeExperts: options.includeExperts ?? opts?.includeExperts,\n }),\n total,\n };\n }\n\n async getPost(\n user_ref: string,\n id: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const rows = await this.getPostsBaseQuery(user_ref).where(\n 'posts.id',\n '=',\n id,\n );\n\n if (!rows || rows.length === 0) {\n return null;\n }\n const post = rows[0] as unknown as RawPostEntity;\n\n if ((recordView === undefined || recordView) && post.status === 'active') {\n this.recordPostView(id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async getPostByAnswerId(\n user_ref: string,\n answerId: number,\n recordView?: boolean,\n options?: PostOptions,\n ): Promise<MaybePost> {\n const rows = await this.getPostsBaseQuery(user_ref)\n .join('answers', 'posts.id', 'answers.postId')\n .where('answers.id', '=', answerId)\n .select('posts.*');\n if (!rows || rows.length === 0) {\n return null;\n }\n if (recordView === undefined || recordView) {\n this.recordPostView(rows[0].id, user_ref);\n }\n const posts = await this.mapPostEntities(\n [rows[0] as unknown as RawPostEntity],\n user_ref,\n options,\n );\n return posts[0];\n }\n\n async createPost(options: {\n user_ref: string;\n title: string;\n content: string;\n created: Date;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n anonymous?: boolean;\n type?: PostType;\n headerImage?: string;\n url?: string;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<Post> {\n const {\n user_ref,\n title,\n content,\n author,\n created,\n tags,\n entities,\n images,\n anonymous,\n type = 'question',\n headerImage,\n url,\n opts,\n status = 'active',\n } = options;\n const posts = await this.db\n .insert(\n {\n author: author ?? user_ref,\n title,\n content,\n created,\n anonymous: anonymous ?? false,\n type: type ?? 'question',\n headerImage,\n url,\n status,\n published: status === 'active' ? created : null,\n },\n ['id'],\n )\n .into('posts')\n .returning([\n 'id',\n 'author',\n 'title',\n 'content',\n 'created',\n 'anonymous',\n 'type',\n 'status',\n 'url',\n ]);\n\n await Promise.all([\n this.addTags(posts[0].id, tags),\n this.addEntities(posts[0].id, entities),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n posts[0].id,\n headerImage,\n );\n\n return (await this.mapPostEntities([posts[0]], user_ref, opts))[0];\n }\n\n async updatePost(options: {\n id: number;\n user_ref: string;\n title?: string;\n content?: string;\n author?: string;\n tags?: string[];\n entities?: string[];\n images?: number[];\n headerImage?: string;\n url?: string;\n setUpdatedBy?: boolean;\n status?: PostStatus;\n opts?: PostOptions;\n }): Promise<MaybePost> {\n const {\n id,\n user_ref,\n title,\n content,\n author,\n tags,\n entities,\n images,\n headerImage,\n url,\n setUpdatedBy = true,\n opts,\n status = 'active',\n } = options;\n\n // Check if this is a transition from draft to active\n const currentPost = await this.db('posts')\n .select('status', 'published')\n .where('id', '=', id)\n .first();\n\n const shouldSetPublished =\n currentPost &&\n currentPost.status === 'draft' &&\n status === 'active' &&\n !currentPost.published;\n\n const query = this.db('posts').where('posts.id', '=', id);\n const rows = await query.update({\n title,\n content,\n headerImage,\n author,\n url,\n updatedBy: setUpdatedBy ? user_ref : undefined,\n updated: setUpdatedBy ? new Date() : undefined,\n status,\n published: shouldSetPublished ? new Date() : undefined,\n });\n\n if (!rows) {\n return null;\n }\n\n await Promise.all([\n this.addTags(id, tags, true),\n this.addEntities(id, entities, true),\n ]);\n\n await this.updateAttachments(\n 'postId',\n content ?? '',\n images ?? [],\n id,\n headerImage,\n );\n\n return await this.getPost(user_ref, id, false, opts);\n }\n\n async deletePost(id: number, permanently?: boolean): Promise<boolean> {\n if (permanently) {\n const rows = await this.db('posts').where('id', '=', id).delete();\n return rows > 0;\n }\n const rows = await this.db('posts').where('id', '=', id).update({\n status: 'deleted',\n });\n return rows > 0;\n }\n\n async votePost(\n user_ref: string,\n postId: number,\n score: number,\n ): Promise<boolean> {\n await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n await this.db\n .insert({\n author: user_ref,\n postId,\n score,\n timestamp: new Date(),\n })\n .into('post_votes');\n\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n return true;\n }\n\n async getPostVote(\n user_ref: string,\n postId: number,\n ): Promise<RawPostVoteEntity | undefined> {\n return await this.db<RawPostVoteEntity>('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .first();\n }\n\n async deletePostVote(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('post_votes')\n .where('author', '=', user_ref)\n .where('postId', '=', postId)\n .delete();\n\n if (rows > 0) {\n await this.db('posts')\n .where('id', '=', postId)\n .update({\n score: this.db('post_votes')\n .where('postId', '=', postId)\n .select(this.db.raw('COALESCE(SUM(score), 0)')),\n });\n }\n return rows > 0;\n }\n\n async favoritePost(user_ref: string, postId: number): Promise<boolean> {\n await this.db\n .insert({\n user: user_ref,\n postId,\n })\n .into('user_favorite');\n await this.db('posts').where('id', postId).increment('favoritesCount', 1);\n return true;\n }\n\n async unfavoritePost(user_ref: string, postId: number): Promise<boolean> {\n const rows = await this.db('user_favorite')\n .where('user', user_ref)\n .where('postId', postId)\n .delete();\n if (rows > 0) {\n await this.db('posts').where('id', postId).decrement('favoritesCount', 1);\n }\n return true;\n }\n\n async getUsersWhoFavoritedPost(postId: number): Promise<string[]> {\n const users = await this.db('user_favorite')\n .where('postId', postId)\n .select('user');\n return users.map(user => user.user);\n }\n\n private async mapPostEntities(\n rows: RawPostEntity[],\n user_ref: string,\n options?: PostOptions,\n ): Promise<Post[]> {\n if (rows.length === 0) {\n return [];\n }\n\n const postIds = rows.map(r => r.id);\n const {\n includeTags = true,\n includeAnswers = true,\n includeVotes = true,\n includeEntities = true,\n includeComments = true,\n includeAttachments = true,\n includeExperts = true,\n includeCollections = true,\n } = options ?? {};\n\n const [\n tags,\n votes,\n entities,\n comments,\n attachments,\n experts,\n answers,\n collections,\n ] = await Promise.all([\n includeTags\n ? this.tagsStore.getRelatedTags(\n postIds,\n 'post_tags',\n 'postId',\n options?.tagsFilter,\n )\n : undefined,\n includeVotes\n ? this.db<RawPostVoteEntity>('post_votes')\n .whereIn('postId', postIds)\n .select()\n : undefined,\n includeEntities\n ? this.entitiesStore.getRelatedEntities(\n postIds,\n 'post_entities',\n 'postId',\n )\n : undefined,\n includeComments\n ? this.commentsStore.getPostComments(postIds, options?.commentsFilter)\n : undefined,\n includeAttachments\n ? this.attachmentsStore.getAttachments(postIds, 'postId')\n : undefined,\n includeExperts\n ? this.db('tag_experts')\n .leftJoin('post_tags', 'tag_experts.tagId', 'post_tags.tagId')\n .whereIn('post_tags.postId', postIds)\n .select('post_tags.postId', 'tag_experts.entityRef')\n : undefined,\n includeAnswers && this.answersStore\n ? this.answersStore.getPostAnswers(postIds, user_ref, {\n ...options,\n includePost: false,\n filter: options?.answersFilter,\n })\n : undefined,\n includeCollections\n ? this.db('collection_posts')\n .whereIn('postId', postIds)\n .select('postId', 'collectionId')\n : undefined,\n ]);\n\n const tagsMap = tags ?? new Map<number, string[]>();\n\n const votesMap = new Map<number, RawPostVoteEntity[]>();\n votes?.forEach((v: RawPostVoteEntity) => {\n const ps = votesMap.get(v.postId) || [];\n ps.push(v);\n votesMap.set(v.postId, ps);\n });\n\n const entitiesMap = entities ?? new Map<number, string[]>();\n\n const commentsMap = new Map<number, QetaComment[]>();\n (comments as unknown as (QetaComment & { postId: number })[])?.forEach(\n c => {\n const ps = commentsMap.get(c.postId) || [];\n ps.push(c);\n commentsMap.set(c.postId, ps);\n },\n );\n\n const attachmentsMap = attachments ?? new Map<number, number[]>();\n\n const expertsMap = new Map<number, string[]>();\n experts?.forEach((e: any) => {\n const ps = expertsMap.get(e.postId) || [];\n ps.push(e.entityRef);\n expertsMap.set(e.postId, ps);\n });\n\n const answersMap = new Map<number, Answer[]>();\n answers?.forEach((a: Answer) => {\n const ps = answersMap.get(a.postId) || [];\n ps.push(a);\n answersMap.set(a.postId, ps);\n });\n\n const collectionsMap = new Map<number, number[]>();\n (collections as any)?.forEach((c: any) => {\n const cs = collectionsMap.get(c.postId) || [];\n cs.push(c.collectionId);\n collectionsMap.set(c.postId, cs);\n });\n\n return rows.map(val => {\n const postVotes = votesMap.get(val.id) || [];\n return {\n id: val.id,\n author:\n val.anonymous && val.author !== user_ref ? 'anonymous' : val.author,\n own: val.author === user_ref,\n title: val.title,\n content: val.content,\n created: val.created as Date,\n updated: val.updated as Date,\n updatedBy: val.updatedBy,\n status: val.status as PostStatus,\n score: this.mapToInteger(val.score),\n views: this.mapToInteger(val.views),\n answersCount: this.mapToInteger(val.answersCount),\n correctAnswer: this.mapToBoolean(val.correctAnswers),\n commentsCount: this.mapToInteger(val.commentsCount),\n favorite: this.mapToInteger(val.favorite) > 0,\n tags: tagsMap.get(val.id),\n answers: answersMap.get(val.id),\n votes: postVotes.map(v => ({\n author: v.author,\n score: v.score,\n timestamp: v.timestamp,\n })),\n entities: entitiesMap.get(val.id),\n trend: this.mapToInteger(val.trend),\n comments: commentsMap.get(val.id),\n ownVote: postVotes.find(v => v.author === user_ref)?.score,\n anonymous: val.anonymous,\n type: val.type,\n headerImage: val.headerImage,\n url: val.url ?? undefined,\n images: attachmentsMap.get(val.id),\n experts: expertsMap.get(val.id),\n published: val.published ? (val.published as Date) : undefined,\n collectionIds: collectionsMap.get(val.id),\n };\n });\n }\n\n private getPostsBaseQuery(user: string, opts?: PostsQuery) {\n const q = this.db<RawPostEntity>('posts')\n .leftJoin('user_favorite', function joinUserFavorite() {\n this.on('posts.id', '=', 'user_favorite.postId').andOnVal(\n 'user_favorite.user',\n '=',\n user,\n );\n })\n .select(\n 'posts.*',\n this.db.raw(\n `CASE WHEN user_favorite.${\n this.db.client.config.client === 'pg' ? '\"postId\"' : 'postId'\n } IS NOT NULL THEN 1 ELSE 0 END as favorite`,\n ),\n );\n\n if (opts?.favorite) {\n q.whereNotNull('user_favorite.postId');\n }\n\n return q;\n }\n\n private async recordPostView(\n postId: number,\n user_ref: string,\n ): Promise<void> {\n await this.db\n .insert({\n author: user_ref,\n postId,\n timestamp: new Date(),\n })\n .into('post_views');\n\n await this.db('posts').where('id', postId).increment('views', 1);\n }\n\n private async addTags(\n id: number,\n tagsInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_tags',\n columnName: string = 'postId',\n ) {\n const tags = filterTags(tagsInput);\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n if (!tags || tags.length === 0) {\n return;\n }\n const existingTags = await this.db('tags')\n .whereIn('tag', tags)\n .returning('id')\n .select();\n const newTags = tags.filter(t => !existingTags.some(e => e.tag === t));\n const allTags: Record<string, string> = {\n ...TAGS,\n ...(await this.tagDatabase?.getTags()),\n };\n\n const tagIds = (\n await Promise.all(\n [...new Set(newTags)].map(async tag => {\n const trimmed = tag.trim();\n const description = trimmed in allTags ? allTags[trimmed] : undefined;\n\n return this.db\n .insert({ tag: trimmed, description })\n .into('tags')\n .returning('id')\n .onConflict('tag')\n .ignore();\n }),\n )\n )\n .flat()\n .map(tag => tag.id)\n .concat(existingTags.map(t => t.id));\n\n await Promise.all(\n tagIds.map(async tagId => {\n await this.db\n .insert({ [columnName]: id, tagId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n\n private async addEntities(\n id: number,\n entitiesInput?: string[],\n removeOld?: boolean,\n tableName: string = 'post_entities',\n columnName: string = 'postId',\n ) {\n if (removeOld) {\n await this.db(tableName).where(columnName, '=', id).delete();\n }\n\n const regex = /\\w+:\\w+\\/\\w+/;\n const entities =\n entitiesInput\n ?.filter(t => regex.test(t))\n .map(t => t.toLowerCase())\n .filter(t => t.length > 0) ?? [];\n\n if (!entities || entities.length === 0) {\n return;\n }\n\n const existingEntities = await this.db('entities')\n .whereIn('entity_ref', entities)\n .returning('id')\n .select();\n const newEntities = entities.filter(\n t => !existingEntities.some(e => e.entity_ref === t),\n );\n\n const entityIds = (\n await Promise.all(\n [...new Set(newEntities)].map(async entityRef =>\n this.db\n .insert({ entity_ref: entityRef })\n .into('entities')\n .returning('id')\n .onConflict('entity_ref')\n .ignore(),\n ),\n )\n )\n .flat()\n .map(entity => entity.id)\n .concat(existingEntities.map(c => c.id));\n\n await Promise.all(\n entityIds.map(async entityId => {\n await this.db\n .insert({ [columnName]: id, entityId })\n .into(tableName)\n .onConflict()\n .ignore();\n }),\n );\n }\n}\n"],"names":["BaseStore","filterTags","rows","TAGS"],"mappings":"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"}
|
|
@@ -103,39 +103,37 @@ class UsersStore extends BaseStore.BaseStore {
|
|
|
103
103
|
if (this.db.client.config.client !== "pg") {
|
|
104
104
|
return this.db("posts").select([
|
|
105
105
|
"author",
|
|
106
|
-
this.db.raw(
|
|
107
|
-
this.db.raw(
|
|
108
|
-
this.db.raw(
|
|
109
|
-
this.db.raw(
|
|
110
|
-
this.db.raw(
|
|
111
|
-
this.db.raw("0 as
|
|
112
|
-
this.db.raw(
|
|
113
|
-
this.db.raw(
|
|
114
|
-
this.db.raw(
|
|
115
|
-
this.db.raw("0 as totalFollowers")
|
|
106
|
+
this.db.raw('0 as "totalViews"'),
|
|
107
|
+
this.db.raw('0 as "totalQuestions"'),
|
|
108
|
+
this.db.raw('0 as "totalArticles"'),
|
|
109
|
+
this.db.raw('0 as "totalLinks"'),
|
|
110
|
+
this.db.raw('0 as "totalAnswers"'),
|
|
111
|
+
this.db.raw("0 as comments"),
|
|
112
|
+
this.db.raw('0 as "answerVotes"'),
|
|
113
|
+
this.db.raw('0 as "postVotes"'),
|
|
114
|
+
this.db.raw('0 as "totalFollowers"')
|
|
116
115
|
]).distinct();
|
|
117
116
|
}
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
followers
|
|
117
|
+
const views = this.db("post_views").select("author").count("* as totalViews").groupBy("author").as("v");
|
|
118
|
+
const questions = this.db("posts").select("author").where("type", "question").count("* as totalQuestions").groupBy("author").as("q");
|
|
119
|
+
const articles = this.db("posts").select("author").where("type", "article").count("* as totalArticles").groupBy("author").as("ar");
|
|
120
|
+
const links = this.db("posts").select("author").where("type", "link").count("* as totalLinks").groupBy("author").as("l");
|
|
121
|
+
const answers = this.db("answers").select("author").count("* as totalAnswers").groupBy("author").as("a");
|
|
122
|
+
const comments = this.db("comments").select("author").count("* as comments").groupBy("author").as("c");
|
|
123
|
+
const aVotes = this.db("answer_votes").select("author").count("* as answerVotes").groupBy("author").as("av");
|
|
124
|
+
const pVotes = this.db("post_votes").select("author").count("* as postVotes").groupBy("author").as("pv");
|
|
125
|
+
const followers = this.db("user_users").select("followedUserRef as author").count("* as totalFollowers").groupBy("followedUserRef").as("f");
|
|
126
|
+
return this.db("unique_authors").leftJoin(views, "unique_authors.author", "v.author").leftJoin(questions, "unique_authors.author", "q.author").leftJoin(articles, "unique_authors.author", "ar.author").leftJoin(links, "unique_authors.author", "l.author").leftJoin(answers, "unique_authors.author", "a.author").leftJoin(comments, "unique_authors.author", "c.author").leftJoin(aVotes, "unique_authors.author", "av.author").leftJoin(pVotes, "unique_authors.author", "pv.author").leftJoin(followers, "unique_authors.author", "f.author").select(
|
|
127
|
+
"unique_authors.author",
|
|
128
|
+
this.db.raw('COALESCE(v."totalViews", 0) as "totalViews"'),
|
|
129
|
+
this.db.raw('COALESCE(q."totalQuestions", 0) as "totalQuestions"'),
|
|
130
|
+
this.db.raw('COALESCE(ar."totalArticles", 0) as "totalArticles"'),
|
|
131
|
+
this.db.raw('COALESCE(l."totalLinks", 0) as "totalLinks"'),
|
|
132
|
+
this.db.raw('COALESCE(a."totalAnswers", 0) as "totalAnswers"'),
|
|
133
|
+
this.db.raw("COALESCE(c.comments, 0) as comments"),
|
|
134
|
+
this.db.raw('COALESCE(av."answerVotes", 0) as "answerVotes"'),
|
|
135
|
+
this.db.raw('COALESCE(pv."postVotes", 0) as "postVotes"'),
|
|
136
|
+
this.db.raw('COALESCE(f."totalFollowers", 0) as "totalFollowers"')
|
|
139
137
|
);
|
|
140
138
|
}
|
|
141
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UsersStore.cjs.js","sources":["../../../src/database/stores/UsersStore.ts"],"sourcesContent":["import { UserResponse, UsersResponse } from '../QetaStore';\nimport {\n UsersQuery,\n UserUsersResponse,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { Knex } from 'knex';\nimport { BaseStore } from './BaseStore';\n\nexport interface RawUserImpact {\n userRef: string;\n impact: number;\n date: Date;\n}\n\nexport class UsersStore extends BaseStore {\n constructor(protected readonly db: Knex) {\n super(db);\n }\n\n async getUsers(\n options?: { entityRefs?: string[] } & UsersQuery,\n ): Promise<UsersResponse> {\n const query = this.getUserBaseQuery();\n if (options?.entityRefs) {\n query.whereIn('unique_authors.author', options.entityRefs);\n }\n\n const totalQuery = query.clone();\n\n if (options?.orderBy) {\n query.orderBy(options?.orderBy, options?.order || 'desc');\n }\n\n if (options?.limit) {\n query.limit(options.limit);\n }\n\n if (options?.offset) {\n query.offset(options.offset);\n }\n\n if (options?.searchQuery) {\n if (this.db.client.config.client === 'pg') {\n query.whereRaw('author % ?', [options.searchQuery]);\n } else {\n query.whereRaw('LOWER(author) LIKE LOWER(?)', [\n `%${options.searchQuery}%`,\n ]);\n }\n }\n\n const results = await Promise.all([\n query,\n this.db(totalQuery.as('totalQuery')).count('* as CNT').first(),\n ]);\n\n const rows = results[0];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n users: rows.map((val: any) => {\n return {\n userRef: val.author,\n totalViews: this.mapToInteger(val.totalViews),\n totalQuestions: this.mapToInteger(val.totalQuestions),\n totalAnswers: this.mapToInteger(val.totalAnswers),\n totalComments: this.mapToInteger(val.comments),\n totalVotes:\n this.mapToInteger(val.answerVotes) +\n this.mapToInteger(val.postVotes),\n totalArticles: this.mapToInteger(val.totalArticles),\n totalFollowers: this.mapToInteger(val.totalFollowers),\n totalLinks: this.mapToInteger(val.totalLinks),\n };\n }),\n total,\n };\n }\n\n async getUsersCount(): Promise<number> {\n const res = await this.db('unique_authors').count('* as CNT').first();\n return this.mapToInteger(res?.CNT);\n }\n\n async getUser(user_ref: string): Promise<UserResponse | null> {\n const query = this.getUserBaseQuery();\n const rows = await query.where('author', user_ref);\n if (rows.length === 0) {\n return null;\n }\n const val = rows[0] as any;\n return {\n userRef: val.author,\n totalViews: this.mapToInteger(val.totalViews),\n totalQuestions: this.mapToInteger(val.totalQuestions),\n totalAnswers: this.mapToInteger(val.totalAnswers),\n totalComments: this.mapToInteger(val.comments),\n totalVotes:\n this.mapToInteger(val.answerVotes) + this.mapToInteger(val.postVotes),\n totalArticles: this.mapToInteger(val.totalArticles),\n totalFollowers: this.mapToInteger(val.totalFollowers),\n totalLinks: this.mapToInteger(val.totalLinks),\n };\n }\n\n async followUser(\n user_ref: string,\n followedUserRef: string,\n ): Promise<boolean> {\n await this.db\n .insert({\n userRef: user_ref,\n followedUserRef,\n })\n .into('user_users');\n return true;\n }\n\n async unfollowUser(\n user_ref: string,\n followedUserRef: string,\n ): Promise<boolean> {\n await this.db('user_users')\n .where('userRef', user_ref)\n .where('followedUserRef', followedUserRef)\n .delete();\n return true;\n }\n\n async getFollowedUsers(user_ref: string): Promise<UserUsersResponse> {\n const entities = await this.db('user_users')\n .where('userRef', user_ref)\n .select('followedUserRef');\n\n return {\n followedUserRefs: entities.map(e => e.followedUserRef),\n count: entities.length,\n };\n }\n\n async getFollowingUsers(user_ref: string): Promise<string[]> {\n const users = await this.db('user_users')\n .where('followedUserRef', user_ref)\n .select('userRef');\n return users.map(user => user.userRef);\n }\n\n private getUserBaseQuery() {\n if (this.db.client.config.client !== 'pg') {\n // Subqueries do not work in sqlite so we just return all stats as empty, at least for now\n return this.db('posts')\n .select([\n 'author',\n this.db.raw('0 as totalViews'),\n this.db.raw('0 as totalQuestions'),\n this.db.raw('0 as totalArticles'),\n this.db.raw('0 as totalLinks'),\n this.db.raw('0 as totalAnswers'),\n this.db.raw('0 as answerComments'),\n this.db.raw('0 as postComments'),\n this.db.raw('0 as answerVotes'),\n this.db.raw('0 as postVotes'),\n this.db.raw('0 as totalFollowers'),\n ])\n .distinct();\n }\n\n const authorRef = this.db.ref('unique_authors.author');\n\n const views = this.db('post_views')\n .where('post_views.author', authorRef)\n .count('*')\n .as('totalViews');\n\n const questions = this.db('posts')\n .where('posts.author', authorRef)\n .where('posts.type', 'question')\n .count('*')\n .as('totalQuestions');\n\n const articles = this.db('posts')\n .where('posts.author', authorRef)\n .where('posts.type', 'article')\n .count('*')\n .as('totalArticles');\n\n const links = this.db('posts')\n .where('posts.author', authorRef)\n .where('posts.type', 'link')\n .count('*')\n .as('totalLinks');\n\n const answers = this.db('answers')\n .where('answers.author', authorRef)\n .count('*')\n .as('totalAnswers');\n\n const comments = this.db('comments')\n .where('comments.author', authorRef)\n .count('*')\n .as('comments');\n const aVotes = this.db('answer_votes')\n .where('answer_votes.author', authorRef)\n .count('*')\n .as('answerVotes');\n\n const pVotes = this.db('post_votes')\n .where('post_votes.author', authorRef)\n .count('*')\n .as('postVotes');\n\n const followers = this.db('user_users')\n .where('user_users.followedUserRef', authorRef)\n .count('*')\n .as('totalFollowers');\n\n return this.db('unique_authors').select(\n 'author',\n views,\n questions,\n answers,\n articles,\n links,\n comments,\n pVotes,\n aVotes,\n followers,\n );\n }\n}\n"],"names":["BaseStore"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UsersStore.cjs.js","sources":["../../../src/database/stores/UsersStore.ts"],"sourcesContent":["import { UserResponse, UsersResponse } from '../QetaStore';\nimport {\n UsersQuery,\n UserUsersResponse,\n} from '@drodil/backstage-plugin-qeta-common';\nimport { Knex } from 'knex';\nimport { BaseStore } from './BaseStore';\n\nexport interface RawUserImpact {\n userRef: string;\n impact: number;\n date: Date;\n}\n\nexport class UsersStore extends BaseStore {\n constructor(protected readonly db: Knex) {\n super(db);\n }\n\n async getUsers(\n options?: { entityRefs?: string[] } & UsersQuery,\n ): Promise<UsersResponse> {\n const query = this.getUserBaseQuery();\n if (options?.entityRefs) {\n query.whereIn('unique_authors.author', options.entityRefs);\n }\n\n const totalQuery = query.clone();\n\n if (options?.orderBy) {\n query.orderBy(options?.orderBy, options?.order || 'desc');\n }\n\n if (options?.limit) {\n query.limit(options.limit);\n }\n\n if (options?.offset) {\n query.offset(options.offset);\n }\n\n if (options?.searchQuery) {\n if (this.db.client.config.client === 'pg') {\n query.whereRaw('author % ?', [options.searchQuery]);\n } else {\n query.whereRaw('LOWER(author) LIKE LOWER(?)', [\n `%${options.searchQuery}%`,\n ]);\n }\n }\n\n const results = await Promise.all([\n query,\n this.db(totalQuery.as('totalQuery')).count('* as CNT').first(),\n ]);\n\n const rows = results[0];\n const total = this.mapToInteger((results[1] as any)?.CNT);\n\n return {\n users: rows.map((val: any) => {\n return {\n userRef: val.author,\n totalViews: this.mapToInteger(val.totalViews),\n totalQuestions: this.mapToInteger(val.totalQuestions),\n totalAnswers: this.mapToInteger(val.totalAnswers),\n totalComments: this.mapToInteger(val.comments),\n totalVotes:\n this.mapToInteger(val.answerVotes) +\n this.mapToInteger(val.postVotes),\n totalArticles: this.mapToInteger(val.totalArticles),\n totalFollowers: this.mapToInteger(val.totalFollowers),\n totalLinks: this.mapToInteger(val.totalLinks),\n };\n }),\n total,\n };\n }\n\n async getUsersCount(): Promise<number> {\n const res = await this.db('unique_authors').count('* as CNT').first();\n return this.mapToInteger(res?.CNT);\n }\n\n async getUser(user_ref: string): Promise<UserResponse | null> {\n const query = this.getUserBaseQuery();\n const rows = await query.where('author', user_ref);\n if (rows.length === 0) {\n return null;\n }\n const val = rows[0] as any;\n return {\n userRef: val.author,\n totalViews: this.mapToInteger(val.totalViews),\n totalQuestions: this.mapToInteger(val.totalQuestions),\n totalAnswers: this.mapToInteger(val.totalAnswers),\n totalComments: this.mapToInteger(val.comments),\n totalVotes:\n this.mapToInteger(val.answerVotes) + this.mapToInteger(val.postVotes),\n totalArticles: this.mapToInteger(val.totalArticles),\n totalFollowers: this.mapToInteger(val.totalFollowers),\n totalLinks: this.mapToInteger(val.totalLinks),\n };\n }\n\n async followUser(\n user_ref: string,\n followedUserRef: string,\n ): Promise<boolean> {\n await this.db\n .insert({\n userRef: user_ref,\n followedUserRef,\n })\n .into('user_users');\n return true;\n }\n\n async unfollowUser(\n user_ref: string,\n followedUserRef: string,\n ): Promise<boolean> {\n await this.db('user_users')\n .where('userRef', user_ref)\n .where('followedUserRef', followedUserRef)\n .delete();\n return true;\n }\n\n async getFollowedUsers(user_ref: string): Promise<UserUsersResponse> {\n const entities = await this.db('user_users')\n .where('userRef', user_ref)\n .select('followedUserRef');\n\n return {\n followedUserRefs: entities.map(e => e.followedUserRef),\n count: entities.length,\n };\n }\n\n async getFollowingUsers(user_ref: string): Promise<string[]> {\n const users = await this.db('user_users')\n .where('followedUserRef', user_ref)\n .select('userRef');\n return users.map(user => user.userRef);\n }\n\n private getUserBaseQuery() {\n if (this.db.client.config.client !== 'pg') {\n // Subqueries do not work in sqlite so we just return all stats as empty, at least for now\n return this.db('posts')\n .select([\n 'author',\n this.db.raw('0 as \"totalViews\"'),\n this.db.raw('0 as \"totalQuestions\"'),\n this.db.raw('0 as \"totalArticles\"'),\n this.db.raw('0 as \"totalLinks\"'),\n this.db.raw('0 as \"totalAnswers\"'),\n this.db.raw('0 as comments'),\n this.db.raw('0 as \"answerVotes\"'),\n this.db.raw('0 as \"postVotes\"'),\n this.db.raw('0 as \"totalFollowers\"'),\n ])\n .distinct();\n }\n\n const views = this.db('post_views')\n .select('author')\n .count('* as totalViews')\n .groupBy('author')\n .as('v');\n\n const questions = this.db('posts')\n .select('author')\n .where('type', 'question')\n .count('* as totalQuestions')\n .groupBy('author')\n .as('q');\n\n const articles = this.db('posts')\n .select('author')\n .where('type', 'article')\n .count('* as totalArticles')\n .groupBy('author')\n .as('ar');\n\n const links = this.db('posts')\n .select('author')\n .where('type', 'link')\n .count('* as totalLinks')\n .groupBy('author')\n .as('l');\n\n const answers = this.db('answers')\n .select('author')\n .count('* as totalAnswers')\n .groupBy('author')\n .as('a');\n\n const comments = this.db('comments')\n .select('author')\n .count('* as comments')\n .groupBy('author')\n .as('c');\n\n const aVotes = this.db('answer_votes')\n .select('author')\n .count('* as answerVotes')\n .groupBy('author')\n .as('av');\n\n const pVotes = this.db('post_votes')\n .select('author')\n .count('* as postVotes')\n .groupBy('author')\n .as('pv');\n\n const followers = this.db('user_users')\n .select('followedUserRef as author')\n .count('* as totalFollowers')\n .groupBy('followedUserRef')\n .as('f');\n\n return this.db('unique_authors')\n .leftJoin(views, 'unique_authors.author', 'v.author')\n .leftJoin(questions, 'unique_authors.author', 'q.author')\n .leftJoin(articles, 'unique_authors.author', 'ar.author')\n .leftJoin(links, 'unique_authors.author', 'l.author')\n .leftJoin(answers, 'unique_authors.author', 'a.author')\n .leftJoin(comments, 'unique_authors.author', 'c.author')\n .leftJoin(aVotes, 'unique_authors.author', 'av.author')\n .leftJoin(pVotes, 'unique_authors.author', 'pv.author')\n .leftJoin(followers, 'unique_authors.author', 'f.author')\n .select(\n 'unique_authors.author',\n this.db.raw('COALESCE(v.\"totalViews\", 0) as \"totalViews\"'),\n this.db.raw('COALESCE(q.\"totalQuestions\", 0) as \"totalQuestions\"'),\n this.db.raw('COALESCE(ar.\"totalArticles\", 0) as \"totalArticles\"'),\n this.db.raw('COALESCE(l.\"totalLinks\", 0) as \"totalLinks\"'),\n this.db.raw('COALESCE(a.\"totalAnswers\", 0) as \"totalAnswers\"'),\n this.db.raw('COALESCE(c.comments, 0) as comments'),\n this.db.raw('COALESCE(av.\"answerVotes\", 0) as \"answerVotes\"'),\n this.db.raw('COALESCE(pv.\"postVotes\", 0) as \"postVotes\"'),\n this.db.raw('COALESCE(f.\"totalFollowers\", 0) as \"totalFollowers\"'),\n );\n }\n}\n"],"names":["BaseStore"],"mappings":"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"}
|