Files

107 lines
4.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { config } from '../config.js'
import { berlinDateTime } from './berlinTime.js'
import { listDocuments, Query } from './appwriteAdmin.js'
import { sendStaffMail } from './mailer.js'
import { createPushTimeToken } from './pushTimeToken.js'
/**
* Push-Zeitmail (Vorlage T15): nach einem neuen Git-Push-Arbeitsblatt bekommt die pushende Person
* eine Mail mit Ticket- und Push-Infos und Schnell-Knoepfen zum Eintragen der Zeit (/zeit/<token>).
*/
const QUICK_MINUTES = [15, 30, 45, 60, 90, 120, 180]
const MAX_COMMITS = 10
const DESCRIPTION_MAX = 300
// Deutsche Bezeichnungen wie in WOMS (lib/ticketStatus.js)
const STATUS_LABELS = {
Open: 'Offen',
Assigned: 'Eingeplant',
Occupied: 'In Arbeit',
Awaiting: 'Wartet',
'In Test': 'Prüfung',
Closed: 'Erledigt',
Cancelled: 'Abgebrochen',
}
const norm = (value) => String(value || '').trim().toLowerCase()
/**
* Gitea-Pusher einem Mitarbeiter zuordnen - dieselbe Regel wie canEditWorksheetTimes in WOMS:
* Gitea-Name gegen Kuerzel oder Anzeigenamen, ohne Gross-/Kleinschreibung. Nur mit E-Mail-Adresse.
*/
export function findEmployeeForPusher(pusher, employees) {
const names = [pusher?.username, pusher?.login, pusher?.full_name].map(norm).filter(Boolean)
if (!names.length) return null
const sorted = [...(employees || [])].sort((a, b) => String(a.$createdAt || '').localeCompare(String(b.$createdAt || '')))
return (
sorted.find(
(emp) => String(emp.email || '').trim() && names.some((n) => n === norm(emp.shortcode) || n === norm(emp.displayName))
) || null
)
}
function commitLines(commits) {
const list = Array.isArray(commits) ? commits : []
const lines = list.slice(0, MAX_COMMITS).map((commit) => {
const sha = String(commit.id || commit.sha || '').slice(0, 7)
const title = String(commit.message || '').trim().split('\n')[0]
return `${sha} ${title}`.trim()
})
if (list.length > MAX_COMMITS) lines.push(`… und ${list.length - MAX_COMMITS} weitere`)
return lines.join('\n') || '(keine Commit-Details)'
}
function shorten(text, max) {
const value = String(text || '').trim()
return value.length > max ? `${value.slice(0, max)}…` : value
}
/** Werte fuer Vorlage T15 */
export function buildPushTimeMail({ employee, ticket, worksheet, repoFullName, branch, commits, pushedAt = new Date() }) {
const token = createPushTimeToken({ worksheetId: worksheet.$id, employeeId: employee.$id })
const base = `${config.publicBaseUrl}/zeit/${token}`
const { date, time } = berlinDateTime(pushedAt)
const woid = String(ticket?.woid || worksheet?.woid || '')
const links = Object.fromEntries(QUICK_MINUTES.map((m) => [`link_${m}`, `${base}?min=${m}`]))
return {
template: 'T15',
values: {
vorname: String(employee.displayName || '').trim().split(/\s+/)[0] || 'du',
woid,
kunde: ticket?.customerName || 'ohne Kunde',
ticket_titel: ticket?.topic || '',
ticket_beschreibung: shorten(ticket?.details, DESCRIPTION_MAX),
ticket_status: STATUS_LABELS[ticket?.status] || ticket?.status || '',
repo: repoFullName,
branch,
push_zeit: `${date} ${time.slice(0, 2)}:${time.slice(2)}`,
anzahl_commits: Array.isArray(commits) ? commits.length : 0,
commits: commitLines(commits),
...links,
link_andere: base,
ticket_link: `${config.womsBaseUrl}/tickets?woid=${encodeURIComponent(woid)}`,
},
}
}
/** Mail verschicken; wirft nie (Webhook darf daran nicht scheitern). */
export async function sendPushTimeMail({ ticket, worksheet, repoFullName, branch, commits, pusher, pushedAt }) {
try {
const employees = await listDocuments(config.collections.employees, [Query.limit(100)])
const employee = findEmployeeForPusher(pusher, employees)
if (!employee) {
const name = pusher?.username || pusher?.login || pusher?.full_name || '?'
console.warn(`[pushTimeMail] Pusher "${name}" keinem Mitarbeiter mit E-Mail zugeordnet – keine Zeitmail`)
return { sent: false, reason: 'no_employee' }
}
const mail = buildPushTimeMail({ employee, ticket, worksheet, repoFullName, branch, commits, pushedAt })
await sendStaffMail(employee.email, mail)
return { sent: true }
} catch (err) {
console.error('[pushTimeMail] Versand fehlgeschlagen:', err.message)
return { sent: false, reason: err.message }
}
}