154 lines
4.8 KiB
TypeScript
154 lines
4.8 KiB
TypeScript
import { db } from '../db/client.js';
|
|
import type { DailyEducationQuestion, DailyEducationRow, EducationQuestionRow } from '../types.js';
|
|
|
|
export const getEducationOptOut = async (userId: string) => {
|
|
const result = await db.query<{ education_opt_out: boolean }>(
|
|
`SELECT education_opt_out
|
|
FROM users
|
|
WHERE id = $1`,
|
|
[userId],
|
|
);
|
|
|
|
return result.rows[0]?.education_opt_out ?? false;
|
|
};
|
|
|
|
export const updateEducationOptOut = async (userId: string, educationOptOut: boolean) => {
|
|
const result = await db.query<{ education_opt_out: boolean }>(
|
|
`UPDATE users
|
|
SET education_opt_out = $2
|
|
WHERE id = $1
|
|
RETURNING education_opt_out`,
|
|
[userId, educationOptOut],
|
|
);
|
|
|
|
return result.rows[0]?.education_opt_out ?? educationOptOut;
|
|
};
|
|
|
|
export const getDailyEducationForDate = async (publishDate?: string) => {
|
|
const result = publishDate
|
|
? await db.query<DailyEducationRow>(
|
|
`SELECT id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at
|
|
FROM daily_education
|
|
WHERE publish_date = $1`,
|
|
[publishDate],
|
|
)
|
|
: await db.query<DailyEducationRow>(
|
|
`SELECT id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at
|
|
FROM daily_education
|
|
WHERE publish_date = CURRENT_DATE`,
|
|
);
|
|
|
|
return result.rows[0] ?? null;
|
|
};
|
|
|
|
export const listDailyEducationForAdmin = async () => {
|
|
const result = await db.query<DailyEducationRow>(
|
|
`SELECT id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at
|
|
FROM daily_education
|
|
ORDER BY publish_date DESC
|
|
LIMIT 120`,
|
|
);
|
|
|
|
return result.rows;
|
|
};
|
|
|
|
export const upsertDailyEducation = async ({
|
|
publishDate,
|
|
fact,
|
|
createdByUserId,
|
|
}: {
|
|
publishDate: string;
|
|
fact: string;
|
|
createdByUserId: string;
|
|
}) => {
|
|
const result = await db.query<DailyEducationRow>(
|
|
`INSERT INTO daily_education (publish_date, fact, created_by_user_id)
|
|
VALUES ($1, $2, $3)
|
|
ON CONFLICT (publish_date) DO UPDATE
|
|
SET fact = EXCLUDED.fact,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
RETURNING id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at`,
|
|
[publishDate, fact, createdByUserId],
|
|
);
|
|
|
|
return result.rows[0];
|
|
};
|
|
|
|
export const listEducationQuestionsForAdmin = async () => {
|
|
const result = await db.query<EducationQuestionRow>(
|
|
`SELECT id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at
|
|
FROM education_question_bank
|
|
ORDER BY updated_at DESC, created_at DESC
|
|
LIMIT 400`,
|
|
);
|
|
|
|
return result.rows;
|
|
};
|
|
|
|
export const listDailyEducationQuestions = async (seedDate?: string) => {
|
|
const result = await db.query<EducationQuestionRow>(
|
|
`SELECT id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at
|
|
FROM education_question_bank
|
|
ORDER BY md5(COALESCE($1::text, CURRENT_DATE::text) || id::text)
|
|
LIMIT 4`,
|
|
[seedDate ?? null],
|
|
);
|
|
|
|
return result.rows;
|
|
};
|
|
|
|
export const createEducationQuestion = async ({
|
|
question,
|
|
createdByUserId,
|
|
}: {
|
|
question: DailyEducationQuestion;
|
|
createdByUserId: string;
|
|
}) => {
|
|
const result = await db.query<EducationQuestionRow>(
|
|
`INSERT INTO education_question_bank (prompt, options, correct_answer_index, explanation, created_by_user_id)
|
|
VALUES ($1, $2::jsonb, $3, $4, $5)
|
|
RETURNING id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at`,
|
|
[question.prompt, JSON.stringify(question.options), question.correctAnswerIndex, question.explanation, createdByUserId],
|
|
);
|
|
|
|
return result.rows[0];
|
|
};
|
|
|
|
export const updateEducationQuestion = async (questionId: string, question: DailyEducationQuestion) => {
|
|
const result = await db.query<EducationQuestionRow>(
|
|
`UPDATE education_question_bank
|
|
SET prompt = $2,
|
|
options = $3::jsonb,
|
|
correct_answer_index = $4,
|
|
explanation = $5,
|
|
updated_at = CURRENT_TIMESTAMP
|
|
WHERE id = $1
|
|
RETURNING id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at`,
|
|
[questionId, question.prompt, JSON.stringify(question.options), question.correctAnswerIndex, question.explanation],
|
|
);
|
|
|
|
return result.rows[0] ?? null;
|
|
};
|
|
|
|
export const deleteEducationQuestion = async (questionId: string) => {
|
|
const result = await db.query<{ id: string }>(
|
|
`DELETE FROM education_question_bank
|
|
WHERE id = $1
|
|
RETURNING id`,
|
|
[questionId],
|
|
);
|
|
|
|
return Boolean(result.rowCount);
|
|
};
|
|
|
|
export const deleteDailyEducation = async (educationId: string) => {
|
|
const result = await db.query<{ id: string }>(
|
|
`DELETE FROM daily_education
|
|
WHERE id = $1
|
|
RETURNING id`,
|
|
[educationId],
|
|
);
|
|
|
|
return Boolean(result.rowCount);
|
|
};
|