87 lines
3.8 KiB
JavaScript
87 lines
3.8 KiB
JavaScript
import { config } from '../config.js'
|
||
import { berlinDateTime } from './berlinTime.js'
|
||
import { listDocuments, updateDocument, Query } from './appwriteAdmin.js'
|
||
import { sendStaffMail } from './mailer.js'
|
||
import { findEmployeeForPusher } from './pushTimeMail.js'
|
||
|
||
/**
|
||
* Mail "Neues Repo zuordnen" (Vorlage T17): wer in Gitea ein Repo anlegt, bekommt eine Mail mit
|
||
* Knopf in die Zuordnung im Ticketsystem. Eine Erinnerung nach 24 Stunden, danach nichts mehr.
|
||
*/
|
||
|
||
const DAY_MS = 24 * 60 * 60 * 1000
|
||
const MAX_ATTEMPTS = 3
|
||
|
||
const time = (value) => {
|
||
const ms = new Date(value || '').getTime()
|
||
return Number.isNaN(ms) ? null : ms
|
||
}
|
||
|
||
/**
|
||
* Soll fuer dieses Repo die erste Mail raus? Nur wenn das Projekt-Dokument jetzt neu angelegt wurde,
|
||
* das Gitea-Repo juenger als 24 h ist, noch keine Art gesetzt ist und noch keine Mail ging.
|
||
*/
|
||
export function shouldSendAssignMail(project, repo, { now = new Date(), createdNow = false } = {}) {
|
||
if (!createdNow) return false
|
||
if (project?.kind || project?.assignMailSentAt) return false
|
||
if (Number(project?.assignMailAttempts || 0) >= MAX_ATTEMPTS) return false
|
||
const created = time(repo?.created_at)
|
||
if (created === null) return false
|
||
return new Date(now).getTime() - created < DAY_MS
|
||
}
|
||
|
||
/** Erinnerung faellig: Mail ging vor >= 24 h, Art fehlt noch, noch keine Erinnerung. */
|
||
export function dueReminder(project, { now = new Date() } = {}) {
|
||
if (project?.kind || project?.assignReminderSentAt) return false
|
||
if (Number(project?.assignMailAttempts || 0) >= MAX_ATTEMPTS) return false
|
||
const sent = time(project?.assignMailSentAt)
|
||
if (sent === null) return false
|
||
return new Date(now).getTime() - sent >= DAY_MS
|
||
}
|
||
|
||
/** Mail verschicken; wirft nie (Webhook/Sync darf daran nicht scheitern). */
|
||
export async function sendRepoAssignMail(project, { giteaLogin, reminder = false, repoCreatedAt } = {}) {
|
||
try {
|
||
const employees = await listDocuments(config.collections.employees, [Query.limit(100)])
|
||
const employee = findEmployeeForPusher({ username: giteaLogin }, employees)
|
||
if (!employee) {
|
||
console.warn(`[repoAssignMail] Gitea-Login "${giteaLogin || '?'}" keinem Mitarbeiter mit E-Mail zugeordnet – keine Mail`)
|
||
return { sent: false, reason: 'no_employee' }
|
||
}
|
||
|
||
const created = new Date(repoCreatedAt || project.$createdAt || Date.now())
|
||
const { date, time: hhmm } = berlinDateTime(Number.isNaN(created.getTime()) ? new Date() : created)
|
||
const attempts = Number(project.assignMailAttempts || 0) + 1
|
||
const message = {
|
||
template: 'T17',
|
||
values: {
|
||
betreff_vorsatz: reminder ? 'Erinnerung: ' : '',
|
||
vorname: String(employee.displayName || '').trim().split(/\s+/)[0] || 'du',
|
||
repo: project.repoFullName,
|
||
repo_link: project.giteaRepoUrl,
|
||
angelegt_von: employee.displayName || giteaLogin,
|
||
angelegt_am: `${date} ${hhmm.slice(0, 2)}:${hhmm.slice(2)}`,
|
||
zuordnen_link: `https://ticket.webklar.com/projects/zuordnen/${project.$id}`,
|
||
},
|
||
blocks: { erinnerung: Boolean(reminder) },
|
||
}
|
||
|
||
const patch = { assignMailAttempts: attempts }
|
||
try {
|
||
await sendStaffMail(employee.email, message)
|
||
} catch (err) {
|
||
console.error('[repoAssignMail] Versand fehlgeschlagen:', err.message)
|
||
await updateDocument(config.collections.websiteProjects, project.$id, patch)
|
||
return { sent: false, reason: err.message }
|
||
}
|
||
// assignMailAttempts zaehlt die Versuche der aktuellen Mail: nach Erfolg zurueck auf 0 (R7)
|
||
patch.assignMailAttempts = 0
|
||
patch[reminder ? 'assignReminderSentAt' : 'assignMailSentAt'] = new Date().toISOString()
|
||
await updateDocument(config.collections.websiteProjects, project.$id, patch)
|
||
return { sent: true }
|
||
} catch (err) {
|
||
console.error('[repoAssignMail] Fehler:', err.message)
|
||
return { sent: false, reason: err.message }
|
||
}
|
||
}
|