From 9c54125fe5492cda256701695235e229a05f084f Mon Sep 17 00:00:00 2001 From: Antti Leinonen Date: Tue, 14 Jan 2025 17:39:23 +0200 Subject: [PATCH] Add Masaryk emailer --- backend/bin/masarykStatsEmailer.ts | 69 +++++++++++++++++++ backend/package.json | 1 + .../masaryk-stats-mailer-cronjob.yml | 37 ++++++++++ helm/values.yaml | 8 +++ 4 files changed, 115 insertions(+) create mode 100644 backend/bin/masarykStatsEmailer.ts create mode 100644 helm/templates/masaryk-stats-mailer-cronjob.yml diff --git a/backend/bin/masarykStatsEmailer.ts b/backend/bin/masarykStatsEmailer.ts new file mode 100644 index 000000000..ef26a8f38 --- /dev/null +++ b/backend/bin/masarykStatsEmailer.ts @@ -0,0 +1,69 @@ +import { PRAGUE_COMPLETION_RECIPIENTS } from "../config" +import sentryLogger from "../lib/logger" +import prisma from "../prisma" +import { sendMail } from "../util/sendMail" + +const logger = sentryLogger({ service: "masaryk-stats-emailer" }) + +const masarykStatsEmailer = async () => { + // Same recipients as for prague stats as masaryk stats are sent to the same partner in CZ, who re-distributes the stats to the universities + const recipients = PRAGUE_COMPLETION_RECIPIENTS?.split(";") + + if (!recipients) { + throw new Error("No recipients set for completion emails") + } + + // TODO: one completion per user? + const result = await prisma.$queryRaw< + Array<{ email: string; completion_date: string; tier: number }> + >` + SELECT co.tier, u.email, co.completion_date + FROM "user" u + JOIN completion co on u.id = co.user_id + WHERE co.course_id = '49cbadd8-be32-454f-9b7d-e84d52100b74'::uuid + AND u.email ILIKE '%@muni.cz' + GROUP BY co.tier, u.email, co.completion_date + ORDER BY co.completion_date DESC, u.email, co.tier; + ` + + const tiers: Record> = {} + + for (const { email, completion_date, tier } of result) { + if (!tiers[tier]) { + tiers[tier] = [] + } + + tiers[tier].push(`${email},${completion_date},${tier}`) + } + + const tierNames: Record = { + 1: "Beginner", + 2: "Intermediate", + 3: "Advanced", + } + + let text = "" + + for (let tier = 1; tier <= 3; tier++) { + text += `${tierNames[tier]}:\n\n` + if (!tiers[tier]?.length) { + text += "No completions for this tier\n" + } else { + text += tiers[tier].join("\n") + } + text += "\n" + } + + await sendMail({ + to: recipients, + text, + subject: "Building AI completions", + }) +} + +masarykStatsEmailer() + .then(() => prisma.$disconnect().then(() => process.exit(0))) + .catch((error) => { + logger.error(error) + return prisma.$disconnect().then(() => process.exit(1)) + }) diff --git a/backend/package.json b/backend/package.json index 9e2671d16..05aa3d124 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,6 +19,7 @@ "prague-stats-emailer": "node ./dist/bin/pragueStatsEmailer.js", "opava-stats-emailer": "node ./dist/bin/opavaStatsEmailer.js", "purkyne-stats-emailer": "node ./dist/bin/purkyneStatsEmailer.js", + "masaryk-stats-emailer": "node ./dist/bin/masarykStatsEmailer.js", "import-organizations": "node ./dist/bin/importOrganizations.js", "parse-file": "node ./dist/bin/parseFile.js", "start-kafka-consumers": "concurrently --kill-others --restart-tries 2 npm:kafka-consumer-*", diff --git a/helm/templates/masaryk-stats-mailer-cronjob.yml b/helm/templates/masaryk-stats-mailer-cronjob.yml new file mode 100644 index 000000000..ca6d320a1 --- /dev/null +++ b/helm/templates/masaryk-stats-mailer-cronjob.yml @@ -0,0 +1,37 @@ +{{- range $cron := .Values.cronjob.masaryk.crons }} +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: masaryk-stats-emailer-{{$cron.id}} + labels: + {{- include "helm.labels" $ | nindent 4 }} +spec: + schedule: "0 10 {{$cron.day}} {{$cron.month}} *" + startingDeadlineSeconds: 3600 + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + successfulJobsHistoryLimit: 3 + jobTemplate: + metadata: + labels: + {{- include "helm.selectorLabels" $ | nindent 8 }} + spec: + activeDeadlineSeconds: 7200 + template: + spec: + restartPolicy: OnFailure + containers: + - name: masaryk-stats-emailer + image: "{{ $.Values.image.repository }}/moocfi-backend:{{ $.Values.image.tag | default $.Chart.AppVersion }}" + command: ["sh", "-c", "npm run masaryk-stats-emailer"] + envFrom: + - secretRef: + name: backend-secret + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: new-redis + key: redis-password +{{- end }} diff --git a/helm/values.yaml b/helm/values.yaml index 54f1ab171..82e0072ea 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -147,3 +147,11 @@ cronjob: - id: "2" day: 20 month: 12 + masaryk: # @muni.cz report, see backend/bin/masarykStatsEmailer.ts + crons: + - id: "0" + day: 15 + month: 1 + - id: "1" + day: 13 + month: 6