Files
harheimertc/server/api/members/bulk.post.js

193 lines
5.4 KiB
JavaScript

import { verifyToken, getUserById } from '../../utils/auth.js'
import { readMembers, writeMembers, normalizeDate } from '../../utils/members.js'
import { randomUUID } from 'crypto'
// Helper function to check for duplicates in a list (with optional exclude)
function findDuplicateMemberInList(members, firstName, lastName, geburtsdatum, excludeId = null) {
const normalizedFirstName = (firstName || '').trim().toLowerCase()
const normalizedLastName = (lastName || '').trim().toLowerCase()
const normalizedDate = normalizeDate(geburtsdatum)
return members.find(m => {
if (excludeId && m.id === excludeId) return false
const mFirstName = (m.firstName || '').trim().toLowerCase()
const mLastName = (m.lastName || '').trim().toLowerCase()
const mDate = normalizeDate(m.geburtsdatum)
return mFirstName === normalizedFirstName &&
mLastName === normalizedLastName &&
mDate === normalizedDate &&
mDate !== ''
})
}
export default defineEventHandler(async (event) => {
try {
// Support both Cookie and Authorization Header
let token = getCookie(event, 'auth_token')
if (!token) {
const authHeader = getHeader(event, 'authorization')
if (authHeader && authHeader.startsWith('Bearer ')) {
token = authHeader.substring(7)
}
}
if (!token) {
throw createError({
statusCode: 401,
message: 'Nicht authentifiziert. Bitte Token im Cookie oder Authorization-Header bereitstellen.'
})
}
const decoded = verifyToken(token)
if (!decoded) {
throw createError({
statusCode: 401,
message: 'Ungültiges Token.'
})
}
const user = await getUserById(decoded.id)
if (!user) {
throw createError({
statusCode: 401,
message: 'Benutzer nicht gefunden.'
})
}
// Only admin and vorstand can add members in bulk
if (user.role !== 'admin' && user.role !== 'vorstand') {
throw createError({
statusCode: 403,
message: 'Keine Berechtigung zum Bulk-Import von Mitgliedern. Erforderlich: admin oder vorstand Rolle.'
})
}
const body = await readBody(event)
const { members: membersToImport } = body
if (!Array.isArray(membersToImport) || membersToImport.length === 0) {
throw createError({
statusCode: 400,
message: 'Bitte senden Sie ein Array von Mitgliedern im Feld "members".'
})
}
// Validate all members before processing
const validationErrors = []
membersToImport.forEach((member, index) => {
if (!member.firstName || !member.lastName) {
validationErrors.push(`Zeile ${index + 1}: Vorname und Nachname sind erforderlich.`)
}
if (!member.geburtsdatum) {
validationErrors.push(`Zeile ${index + 1}: Geburtsdatum ist erforderlich.`)
}
})
if (validationErrors.length > 0) {
throw createError({
statusCode: 400,
message: `Validierungsfehler:\n${validationErrors.join('\n')}`
})
}
// Read existing members
const existingMembers = await readMembers()
const results = {
success: [],
duplicates: [],
errors: []
}
// Process each member
for (let i = 0; i < membersToImport.length; i++) {
const memberData = membersToImport[i]
try {
// Check for duplicates in existing members
const duplicateInExisting = findDuplicateMemberInList(
existingMembers,
memberData.firstName,
memberData.lastName,
memberData.geburtsdatum
)
if (duplicateInExisting) {
results.duplicates.push({
index: i + 1,
member: memberData,
reason: `Existiert bereits (ID: ${duplicateInExisting.id})`
})
continue
}
// Check for duplicates within the import batch
const duplicateInBatch = findDuplicateMemberInList(
membersToImport.slice(0, i),
memberData.firstName,
memberData.lastName,
memberData.geburtsdatum
)
if (duplicateInBatch) {
results.duplicates.push({
index: i + 1,
member: memberData,
reason: 'Duplikat innerhalb des Imports'
})
continue
}
// Add new member
const newMember = {
...memberData,
id: memberData.id || randomUUID()
}
existingMembers.push(newMember)
results.success.push({
index: i + 1,
member: newMember
})
} catch (error) {
results.errors.push({
index: i + 1,
member: memberData,
error: error.message || 'Unbekannter Fehler'
})
}
}
// Save all successfully imported members
if (results.success.length > 0) {
await writeMembers(existingMembers)
}
return {
success: results.success.length > 0,
summary: {
total: membersToImport.length,
imported: results.success.length,
duplicates: results.duplicates.length,
errors: results.errors.length
},
results: results
}
} catch (error) {
console.error('Fehler beim Bulk-Import von Mitgliedern:', error)
if (error.statusCode) {
throw error
}
throw createError({
statusCode: error.statusCode || 500,
message: error.message || 'Fehler beim Bulk-Import von Mitgliedern.'
})
}
})