Projektarten: Mail T16 Repo zuordnen

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-09-30 18:31:07 +00:00
1 parent 08958dee77
commit b8a530958f
3 files changed
+261

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
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 T16): 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
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: 'T16',
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 }
}
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 }
}
}