Skip to content

Commit

Permalink
Add Purkyne emailer (#1259)
Browse files Browse the repository at this point in the history
  • Loading branch information
Redande committed Apr 26, 2024
1 parent c081242 commit ee13feb
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
69 changes: 69 additions & 0 deletions backend/bin/purkyneStatsEmailer.ts
Original file line number Diff line number Diff line change
@@ -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: "purkyne-stats-emailer" })

const purkyneStatsEmailer = async () => {
// Same recipients as for prague stats as opava 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 '%@ujep.cz'
GROUP BY co.tier, u.email, co.completion_date
ORDER BY co.completion_date DESC, u.email, co.tier;
`

const tiers: Record<number, Array<string>> = {}

for (const { email, completion_date, tier } of result) {
if (!tiers[tier]) {
tiers[tier] = []
}

tiers[tier].push(`${email},${completion_date},${tier}`)
}

const tierNames: Record<number, string> = {
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",
})
}

purkyneStatsEmailer()
.then(() => prisma.$disconnect().then(() => process.exit(0)))
.catch((error) => {
logger.error(error)
return prisma.$disconnect().then(() => process.exit(1))
})
2 changes: 2 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"course-stats-emailer": "node ./dist/bin/courseStatsEmailer.js",
"linkoping-stats-emailer": "node ./dist/bin/linkopingStatsEmailer.js",
"prague-stats-emailer": "node ./dist/bin/pragueStatsEmailer.js",
"opava-stats-emailer": "node ./dist/bin/opavaStatsEmailer.js",
"purkyne-stats-emailer": "node ./dist/bin/purkyneStatsEmailer.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-*",
Expand Down
35 changes: 35 additions & 0 deletions helm/templates/purkyne-stats-mailer-cronjob.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: purkyne-stats-emailer
labels:
{{- include "helm.labels" . | nindent 4 }}
spec:
# Run at 10:00 AM on 30th of June
schedule: "0 10 30 6 *"
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: purkyne-stats-emailer
image: "{{ .Values.image.repository }}/moocfi-backend:{{ .Values.image.tag | default .Chart.AppVersion }}"
command: ["sh", "-c", "npm run purkyne-stats-emailer"]
envFrom:
- secretRef:
name: backend-secret
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: new-redis
key: redis-password

0 comments on commit ee13feb

Please sign in to comment.