Initial commit
This commit is contained in:
@@ -0,0 +1,754 @@
|
||||
const db = require('./db')
|
||||
const {
|
||||
searchEngineClient,
|
||||
deleteConsultancyEntriesFromIndex,
|
||||
CONSULTANCY_ENTRY_INDEX
|
||||
} = require('./search-engine')
|
||||
const { removeHtmlTags } = require('./helpers')
|
||||
|
||||
class ConsultancyEntry {
|
||||
constructor({
|
||||
id,
|
||||
id_external: idExternal,
|
||||
time_created: timeCreated,
|
||||
status,
|
||||
author_id: authorId,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial: domainPrimaryIdInitial,
|
||||
existing_solutions: existingSolutions,
|
||||
examples_of_use: examplesOfUse,
|
||||
time_published: timePublished,
|
||||
title,
|
||||
question,
|
||||
answer,
|
||||
path,
|
||||
answer_authors: answerAuthors,
|
||||
domain_primary_id: domainPrimaryId,
|
||||
first_name: firstName,
|
||||
last_name: lastName,
|
||||
is_moderator: isModerator,
|
||||
formatted_time_created: formattedTimeCreated,
|
||||
formatted_time_published: formattedTimePublished
|
||||
}) {
|
||||
this.id = id
|
||||
this.idExternal = idExternal
|
||||
this.timeCreated = timeCreated
|
||||
this.status = status
|
||||
this.authorId = authorId
|
||||
this.institution = institution
|
||||
this.description = description
|
||||
this.domainPrimaryIdInitial = domainPrimaryIdInitial
|
||||
this.existingSolutions = existingSolutions
|
||||
this.examplesOfUse = examplesOfUse
|
||||
this.timePublished = timePublished
|
||||
this.title = title
|
||||
this.question = question
|
||||
this.answer = answer
|
||||
this.path = path
|
||||
this.answerAuthors = answerAuthors
|
||||
this.domainPrimaryId = domainPrimaryId
|
||||
this.firstName = firstName
|
||||
this.lastName = lastName
|
||||
this.isModerator = isModerator
|
||||
this.formattedTimeCreated = formattedTimeCreated
|
||||
this.formattedTimePublished = formattedTimePublished
|
||||
}
|
||||
|
||||
// Fetch all consultancy entries from DB.
|
||||
static async fetchAll() {
|
||||
// TODO Luka: Miha, define specific fields instead of using *.
|
||||
const { rows: fetchedConsEntries } = await db.query(`
|
||||
SELECT *
|
||||
FROM consultancy_entry
|
||||
ORDER BY time_created DESC`)
|
||||
const deserializedConsEntries = fetchedConsEntries.map(
|
||||
consEntry => new this(consEntry)
|
||||
)
|
||||
return deserializedConsEntries
|
||||
}
|
||||
|
||||
// Fetch consultancy entry by ID
|
||||
// to_char(time_created,'HH24:MI:SS DD/MM/YYYY')
|
||||
static async fetchByIdWithFormattedTime(id) {
|
||||
const { rows: fetchedConsEntry } = await db.query(
|
||||
`
|
||||
SELECT
|
||||
|
||||
id,
|
||||
id_external,
|
||||
to_char(time_created,'DD. MM. YYYY') time_created,
|
||||
status,
|
||||
author_id,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial,
|
||||
existing_solutions,
|
||||
examples_of_use,
|
||||
to_char(time_published,'DD. MM. YYYY') time_published,
|
||||
title,
|
||||
question,
|
||||
answer,
|
||||
path,
|
||||
answer_authors,
|
||||
domain_primary_id
|
||||
|
||||
FROM consultancy_entry
|
||||
WHERE id=$1`,
|
||||
[id]
|
||||
)
|
||||
|
||||
return new this(fetchedConsEntry[0])
|
||||
}
|
||||
|
||||
static async fetchById(id) {
|
||||
const { rows: fetchedConsEntry } = await db.query(
|
||||
`
|
||||
SELECT
|
||||
|
||||
id,
|
||||
id_external,
|
||||
to_char(time_created, 'DD. MM. YYYY') time_created,
|
||||
status,
|
||||
author_id,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial,
|
||||
existing_solutions,
|
||||
examples_of_use,
|
||||
to_char(time_published,'DD. MM. YYYY') time_published,
|
||||
title,
|
||||
question,
|
||||
answer,
|
||||
path,
|
||||
answer_authors,
|
||||
domain_primary_id
|
||||
|
||||
FROM consultancy_entry
|
||||
WHERE id=$1`,
|
||||
[id]
|
||||
)
|
||||
|
||||
return new this(fetchedConsEntry[0])
|
||||
}
|
||||
|
||||
// Fetch dictionaries admin emails.
|
||||
static async fetchConsultancyAdminEmails() {
|
||||
const query = {
|
||||
text: `
|
||||
SELECT email FROM "user" WHERE id
|
||||
IN(SELECT user_id FROM user_role
|
||||
WHERE role_name = 'consultancy admin')`,
|
||||
rowMode: 'array'
|
||||
}
|
||||
|
||||
const { rows: users } = await db.query(query)
|
||||
const emails = users.flat()
|
||||
return emails
|
||||
}
|
||||
|
||||
static async fetchModeratorEmail(entryId) {
|
||||
const query = {
|
||||
text: `
|
||||
SELECT email FROM "user" WHERE id
|
||||
IN (SELECT user_id FROM consultancy_entry_consultant cec
|
||||
WHERE cec.entry_id=$1 AND cec.is_moderator=true)`,
|
||||
rowMode: 'array'
|
||||
}
|
||||
|
||||
const { rows: users } = await db.query(query, [entryId])
|
||||
const emails = users.flat()
|
||||
return emails
|
||||
}
|
||||
|
||||
// Fetch all consultancy entries filtered by status from DB.
|
||||
static async fetchAllByStatus(status) {
|
||||
// TODO Luka: Miha, define specific fields instead of using *.
|
||||
const sqlQuery = `
|
||||
SELECT *, to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created
|
||||
FROM consultancy_entry
|
||||
WHERE status=$1
|
||||
ORDER BY time_created DESC`
|
||||
|
||||
const values = [status]
|
||||
const { rows: fetchedConsEntries } = await db.query(sqlQuery, values)
|
||||
|
||||
const deserializedConsEntries = fetchedConsEntries.map(
|
||||
consEntry => new this(consEntry)
|
||||
)
|
||||
return deserializedConsEntries
|
||||
}
|
||||
|
||||
// Fetch all consultancy entries filtered by status from DB.
|
||||
static async fetchAllByStatusCount(status) {
|
||||
// TODO Luka: Miha, define specific fields instead of using *.
|
||||
const sqlQuery = `
|
||||
SELECT COUNT(id)
|
||||
FROM consultancy_entry
|
||||
WHERE status=$1`
|
||||
|
||||
const values = [status]
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
|
||||
return rows[0].count
|
||||
}
|
||||
|
||||
static async fetchWithStatusByIdCount(status, id) {
|
||||
const sqlQuery = `
|
||||
SELECT COUNT(DISTINCT(ce.id))
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.status=$1 and cec.user_id=$2`
|
||||
const values = [status, id]
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
|
||||
return rows[0].count
|
||||
}
|
||||
|
||||
static async fetchWithStatusById(status, id) {
|
||||
const sqlQuery = `
|
||||
SELECT ce.id,
|
||||
to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created,
|
||||
author_id,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial,
|
||||
to_char(time_published, 'FMDD. FMMM. YYYY') time_published,
|
||||
title,
|
||||
question,
|
||||
answer,
|
||||
path,
|
||||
answer_authors,
|
||||
domain_primary_id,
|
||||
first_name,
|
||||
last_name,
|
||||
cec.is_moderator
|
||||
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.status=$1 and cec.user_id=$2
|
||||
ORDER BY time_created DESC`
|
||||
|
||||
/* filter them in pug by displaying moderator, and showing authors
|
||||
of non moderator */
|
||||
/* AND cec.is_moderator='true';` */
|
||||
|
||||
const values = [status, id]
|
||||
const { rows: fetchedConsEntries } = await db.query(sqlQuery, values)
|
||||
|
||||
const deserializedConsEntries = fetchedConsEntries.map(
|
||||
consEntry => new this(consEntry)
|
||||
)
|
||||
return deserializedConsEntries
|
||||
}
|
||||
|
||||
static async fetchInProgressById(id) {
|
||||
return await this.fetchWithStatusById('in progress', id)
|
||||
}
|
||||
|
||||
static async fetchPublishedById(id) {
|
||||
return await this.fetchWithStatusById('published', id)
|
||||
}
|
||||
|
||||
// Fetch entry count.
|
||||
static async fetchAllByStatusWithAuthorDataCount(status) {
|
||||
const sqlQuery = `
|
||||
SELECT COUNT(DISTINCT(ce.id))
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.status=$1`
|
||||
|
||||
/* filter them in pug by displaying moderator, and showing authors
|
||||
of non moderator */
|
||||
/* AND cec.is_moderator='true';` */
|
||||
|
||||
const values = [status]
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
await db.query(sqlQuery, values)
|
||||
return rows[0].count
|
||||
}
|
||||
|
||||
// Fetch all consultancy entries filtered by status from DB.
|
||||
static async fetchAllByStatusWithAuthorData(status) {
|
||||
const sqlQuery = `
|
||||
SELECT ce.id,
|
||||
to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created,
|
||||
author_id,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial,
|
||||
to_char(time_published, 'FMDD. FMMM. YYYY') time_published,
|
||||
title,
|
||||
question,
|
||||
answer,
|
||||
path,
|
||||
answer_authors,
|
||||
domain_primary_id,
|
||||
first_name,
|
||||
last_name,
|
||||
cec.is_moderator
|
||||
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.status=$1
|
||||
ORDER BY time_created DESC`
|
||||
|
||||
/* filter them in pug by displaying moderator, and showing authors
|
||||
of non moderator */
|
||||
/* AND cec.is_moderator='true';` */
|
||||
|
||||
const values = [status]
|
||||
const { rows: fetchedConsEntries } = await db.query(sqlQuery, values)
|
||||
|
||||
const deserializedConsEntries = fetchedConsEntries.map(
|
||||
consEntry => new this(consEntry)
|
||||
)
|
||||
return deserializedConsEntries
|
||||
}
|
||||
|
||||
// Fetch all new consultancy entries from DB.
|
||||
static async fetchAllNew() {
|
||||
const newEntries = await this.fetchAllByStatus('new')
|
||||
return newEntries
|
||||
}
|
||||
|
||||
static async fetchAllRejected() {
|
||||
const newEntries = await this.fetchAllByStatusWithAuthorData('rejected')
|
||||
return newEntries
|
||||
}
|
||||
|
||||
static async fetchAllInProgress() {
|
||||
const newEntries = await this.fetchAllByStatusWithAuthorData('in progress')
|
||||
return newEntries
|
||||
}
|
||||
|
||||
static async fetchAllPrepared() {
|
||||
const newEntries = await this.fetchAllByStatusWithAuthorData('review')
|
||||
return newEntries
|
||||
}
|
||||
|
||||
static async fetchAllPublished() {
|
||||
const newEntries = await this.fetchAllByStatusWithAuthorData('published')
|
||||
return newEntries
|
||||
}
|
||||
|
||||
static async fetch5MostRecentPublished() {
|
||||
const sqlQuery = `
|
||||
SELECT ce.id,
|
||||
to_char(time_created, 'FMDD. FMMM. YYYY') formatted_time_created,
|
||||
author_id,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial,
|
||||
to_char(time_published, 'FMDD. FMMM. YYYY') time_published,
|
||||
title,
|
||||
question,
|
||||
answer,
|
||||
path,
|
||||
answer_authors,
|
||||
domain_primary_id,
|
||||
first_name,
|
||||
last_name,
|
||||
cec.is_moderator
|
||||
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.status=$1
|
||||
ORDER BY time_published DESC
|
||||
LIMIT 5`
|
||||
|
||||
/* filter them in pug by displaying moderator, and showing authors
|
||||
of non moderator */
|
||||
/* AND cec.is_moderator='true';` */
|
||||
|
||||
const values = ['published']
|
||||
const { rows: fetchedConsEntries } = await db.query(sqlQuery, values)
|
||||
|
||||
const deserializedConsEntries = fetchedConsEntries.map(
|
||||
consEntry => new this(consEntry)
|
||||
)
|
||||
return deserializedConsEntries
|
||||
}
|
||||
|
||||
static async fetchPublishedCount() {
|
||||
const sqlQuery = `
|
||||
SELECT COUNT(DISTINCT(ce.id))
|
||||
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.status=$1`
|
||||
|
||||
/* filter them in pug by displaying moderator, and showing authors
|
||||
of non moderator */
|
||||
/* AND cec.is_moderator='true';` */
|
||||
|
||||
const values = ['published']
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
|
||||
return rows[0].count
|
||||
}
|
||||
|
||||
/*
|
||||
static async fetchAuthorsFirstAndLastName(entryId, userId) {
|
||||
const sqlQuery = `
|
||||
SELECT u.first_name u.last_name
|
||||
FROM "user" u INNER JOIN "consultancy_entry_consultant" cec ON u.id = cec.user_id
|
||||
WHERE cec.entry_id=$1 and cec.user_id=$2`
|
||||
|
||||
const values = [entryId, userId]
|
||||
const { rows: fetchedConsEntries } = await db.query(sqlQuery, values)
|
||||
|
||||
return fetchedConsEntries
|
||||
}
|
||||
*/
|
||||
|
||||
/* Get shared authors in progress,
|
||||
answer_authors only get published when the question is published */
|
||||
static async getSharedAuthorsArrayBeforePublish(entryId) {
|
||||
const sqlQuery = `SELECT cec.entry_id, cec.user_id,
|
||||
u.first_name, u.last_name, u.username
|
||||
FROM "consultancy_entry_consultant" cec INNER JOIN
|
||||
"user" u ON u.id = cec.user_id
|
||||
WHERE cec.entry_id=$1 AND cec.is_moderator='false';`
|
||||
|
||||
const values = [entryId]
|
||||
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
return rows
|
||||
}
|
||||
|
||||
static async getModerator(entryId) {
|
||||
const sqlQuery = `
|
||||
SELECT u.id, u.first_name, u.last_name
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.id=$1 AND cec.is_moderator=true;`
|
||||
|
||||
const values = [entryId]
|
||||
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
return rows[0]
|
||||
}
|
||||
|
||||
static async getEditors(entryId) {
|
||||
const sqlQuery = `
|
||||
SELECT u.id, u.first_name, u.last_name
|
||||
FROM "consultancy_entry" ce
|
||||
INNER JOIN "consultancy_entry_consultant" cec ON ce.id = cec.entry_id
|
||||
INNER JOIN "user" u ON u.id = cec.user_id
|
||||
WHERE ce.id=$1`
|
||||
|
||||
const values = [entryId]
|
||||
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
return rows
|
||||
}
|
||||
|
||||
static async getSharedAuthorsArray(entryId) {
|
||||
const sqlQuery = `SELECT answer_authors FROM "consultancy_entry"
|
||||
WHERE id=$1;`
|
||||
|
||||
const values = [entryId]
|
||||
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
return rows[0]
|
||||
}
|
||||
|
||||
static async updateSharedAuthorsArray(entryId, authors) {
|
||||
const sqlQuery = `UPDATE "consultancy_entry" SET answer_authors=$2
|
||||
WHERE id=$1;`
|
||||
|
||||
const values = [entryId, authors]
|
||||
|
||||
await db.query(sqlQuery, values)
|
||||
}
|
||||
|
||||
static async createQuestion(consultancyEntry) {
|
||||
const sqlQuery = `INSERT INTO consultancy_entry (
|
||||
status,
|
||||
author_id,
|
||||
institution,
|
||||
description,
|
||||
domain_primary_id_initial,
|
||||
existing_solutions,
|
||||
examples_of_use
|
||||
)
|
||||
VALUES (
|
||||
$1,
|
||||
$2,
|
||||
$3,
|
||||
$4,
|
||||
$5,
|
||||
$6,
|
||||
$7
|
||||
)
|
||||
RETURNING id;`
|
||||
|
||||
const values = [
|
||||
consultancyEntry.status,
|
||||
consultancyEntry.authorId,
|
||||
consultancyEntry.institution,
|
||||
consultancyEntry.description,
|
||||
consultancyEntry.domainPrimaryIdInitial || null,
|
||||
consultancyEntry.existingSolutions,
|
||||
consultancyEntry.examplesOfUse
|
||||
]
|
||||
|
||||
const {
|
||||
rows: [{ id }]
|
||||
} = await db.query(sqlQuery, values)
|
||||
return id
|
||||
}
|
||||
|
||||
static async updateQuestion(consultancyEntry) {
|
||||
await db.transaction(async dbClient => {
|
||||
const sqlQuery = `UPDATE consultancy_entry SET
|
||||
id_external=$2,
|
||||
status=$3,
|
||||
author_id=$4,
|
||||
institution=$5,
|
||||
description=$6,
|
||||
domain_primary_id_initial=$7,
|
||||
existing_solutions=$8,
|
||||
examples_of_use=$9,
|
||||
title=$10,
|
||||
question=$11,
|
||||
answer=$12,
|
||||
path=$13,
|
||||
answer_authors=$14,
|
||||
domain_primary_id=$15
|
||||
WHERE id=$1;`
|
||||
|
||||
const values = [
|
||||
consultancyEntry.id,
|
||||
consultancyEntry.idExternal,
|
||||
consultancyEntry.status,
|
||||
consultancyEntry.authorId,
|
||||
consultancyEntry.institution,
|
||||
consultancyEntry.description,
|
||||
consultancyEntry.domainPrimaryIdInitial,
|
||||
consultancyEntry.existingSolutions,
|
||||
consultancyEntry.examplesOfUse,
|
||||
consultancyEntry.title,
|
||||
consultancyEntry.question,
|
||||
consultancyEntry.answer,
|
||||
consultancyEntry.path,
|
||||
consultancyEntry.answerAuthors,
|
||||
consultancyEntry.domainPrimaryId
|
||||
]
|
||||
|
||||
await dbClient.query(sqlQuery, values)
|
||||
|
||||
await dbClient.query(
|
||||
`UPDATE "consultancy_entry" SET status=$2
|
||||
WHERE id=$1;`,
|
||||
[consultancyEntry.id, 'in progress']
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
static async deleteQuestion(id) {
|
||||
const sqlQuery = `DELETE FROM consultancy_entry
|
||||
WHERE id=$1;`
|
||||
|
||||
const values = [id]
|
||||
|
||||
await db.query(sqlQuery, values)
|
||||
}
|
||||
|
||||
/** refactor in case you need both moderator and non moderator
|
||||
* insertions as a common function
|
||||
*/
|
||||
static async insertNonModerator(entryId, userId) {
|
||||
const sqlQuery = `INSERT INTO "consultancy_entry_consultant" (entry_id, user_id, is_moderator) VALUES
|
||||
($1, $2, 'false');
|
||||
`
|
||||
|
||||
const values = [entryId, userId]
|
||||
|
||||
const { rows } = await db.query(sqlQuery, values)
|
||||
return rows
|
||||
}
|
||||
|
||||
static async assignWorkInProgress(entryId, userId) {
|
||||
await db.transaction(async dbClient => {
|
||||
let sqlQuery = `SELECT entry_id FROM consultancy_entry_consultant
|
||||
WHERE entry_id=$1 AND is_moderator='true'`
|
||||
|
||||
let values = [entryId]
|
||||
|
||||
const { rows } = await dbClient.query(sqlQuery, values)
|
||||
if (rows.length) {
|
||||
await dbClient.query(
|
||||
`DELETE FROM consultancy_entry_consultant
|
||||
WHERE entry_id=$1 AND is_moderator='true'`,
|
||||
values
|
||||
)
|
||||
}
|
||||
sqlQuery = [
|
||||
`UPDATE "consultancy_entry" SET status='in progress'
|
||||
WHERE id=$1;`,
|
||||
`INSERT INTO "consultancy_entry_consultant" (entry_id, user_id, is_moderator) VALUES
|
||||
($1, $2, 'true');
|
||||
`
|
||||
]
|
||||
|
||||
values = [[entryId], [entryId, userId]]
|
||||
|
||||
for (let i = 0; i < sqlQuery.length; i++) {
|
||||
await dbClient.query(sqlQuery[i], values[i])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static async updateConsultancyEntryStatus(entryId, status) {
|
||||
const sqlQuery = `UPDATE "consultancy_entry" SET status=$2
|
||||
WHERE id=$1;`
|
||||
|
||||
const values = [entryId, status]
|
||||
|
||||
await db.query(sqlQuery, values)
|
||||
}
|
||||
|
||||
static async rejectEntry(entryId) {
|
||||
await this.updateConsultancyEntryStatus(entryId, 'rejected')
|
||||
}
|
||||
|
||||
static async sendToReview(entryId) {
|
||||
await this.updateConsultancyEntryStatus(entryId, 'review')
|
||||
}
|
||||
|
||||
static async publish(entryId, answerAuthors) {
|
||||
await db.transaction(async dbClient => {
|
||||
await dbClient.query(
|
||||
`UPDATE "consultancy_entry" SET status=$2
|
||||
WHERE id=$1;`,
|
||||
[entryId, 'published']
|
||||
)
|
||||
|
||||
if (answerAuthors) {
|
||||
answerAuthors = answerAuthors.split(',').filter(author => author !== '')
|
||||
await dbClient.query(
|
||||
`UPDATE "consultancy_entry"
|
||||
SET answer_authors=$2
|
||||
WHERE id=$1;`,
|
||||
[entryId, answerAuthors]
|
||||
)
|
||||
}
|
||||
|
||||
await dbClient.query(
|
||||
`UPDATE "consultancy_entry"
|
||||
SET time_published=CURRENT_TIMESTAMP
|
||||
WHERE id=$1;`,
|
||||
[entryId]
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
static async removeConsultantForEntry(entryId, userId) {
|
||||
// TODO check for any other tables where entry id is foreign key
|
||||
await db.query(
|
||||
`DELETE FROM consultancy_entry_consultant
|
||||
WHERE entry_id=$1 AND user_id=$2`,
|
||||
[entryId, userId]
|
||||
)
|
||||
}
|
||||
|
||||
static async removeEntry(id) {
|
||||
// TODO check for any other tables where entry id is foreign key
|
||||
await db.transaction(async dbClient => {
|
||||
await dbClient.query(
|
||||
`DELETE FROM consultancy_entry_consultant
|
||||
WHERE entry_id=$1`,
|
||||
[id]
|
||||
)
|
||||
|
||||
await dbClient.query(
|
||||
`DELETE FROM consultancy_entry
|
||||
WHERE id=$1`,
|
||||
[id]
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// (Re)index specific consultancy entry into consultancy search index.
|
||||
static async indexIntoSearchEngine(entryId, shouldWait) {
|
||||
const values = [entryId]
|
||||
const text = `
|
||||
SELECT
|
||||
jsonb_strip_nulls(
|
||||
jsonb_build_object(
|
||||
'id', ce.id,
|
||||
'timeCreated', ce.time_created,
|
||||
'status', ce.status,
|
||||
'description', ce.description,
|
||||
'title', ce.title,
|
||||
'question', ce.question,
|
||||
'answer', ce.answer,
|
||||
'answerAuthors', ce.answer_authors,
|
||||
'primaryDomain', jsonb_strip_nulls(
|
||||
jsonb_build_object(
|
||||
'id', dp.id,
|
||||
'nameSl', dp.name_sl,
|
||||
'nameEn', dp.name_en
|
||||
)
|
||||
),
|
||||
'assignedConsultants', ARRAY(
|
||||
SELECT jsonb_strip_nulls(
|
||||
jsonb_build_object(
|
||||
'id', u.id,
|
||||
'firstName', u.first_name,
|
||||
'lastName', u.last_name,
|
||||
'isModerator', cec.is_moderator
|
||||
)
|
||||
)
|
||||
FROM consultancy_entry_consultant cec
|
||||
LEFT JOIN "user" u on u.id = cec.user_id
|
||||
WHERE cec.entry_id = ce.id
|
||||
ORDER BY is_moderator DESC
|
||||
)
|
||||
)
|
||||
) entry
|
||||
FROM consultancy_entry ce
|
||||
LEFT JOIN domain_primary dp on dp.id = ce.domain_primary_id
|
||||
WHERE ce.id = $1`
|
||||
|
||||
let {
|
||||
rows: [{ entry }]
|
||||
} = await db.query(text, values)
|
||||
|
||||
if (!entry.answerAuthors?.length) delete entry.answerAuthors
|
||||
if (!Object.keys(entry.primaryDomain).length) delete entry.primaryDomain
|
||||
if (!entry.assignedConsultants.length) delete entry.assignedConsultants
|
||||
|
||||
entry = removeHtmlTags(JSON.stringify(entry))
|
||||
|
||||
await searchEngineClient.index({
|
||||
id: entryId,
|
||||
index: CONSULTANCY_ENTRY_INDEX,
|
||||
body: entry,
|
||||
refresh: shouldWait ? 'wait_for' : false
|
||||
})
|
||||
}
|
||||
|
||||
// Remove all consultancy entries from index and index them all again.
|
||||
static async reindexAll() {
|
||||
await deleteConsultancyEntriesFromIndex()
|
||||
|
||||
const { rows } = await db.query('SELECT id FROM consultancy_entry')
|
||||
|
||||
for (const row of rows) {
|
||||
const { id: entryId } = row
|
||||
await this.indexIntoSearchEngine(entryId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConsultancyEntry
|
||||
Reference in New Issue
Block a user