This commit is contained in:
2026-03-04 14:13:16 +01:00
parent b7d826e29c
commit 56ea3348d6
41 changed files with 846 additions and 162 deletions

View File

@@ -1,9 +1,9 @@
import { type FetchCreateContextFnOptions } from '@trpc/server/adapters/fetch'
import { auth } from '@/lib/auth'
import { auth, getSanitizedHeaders } from '@/lib/auth'
import { prisma } from '@innungsapp/shared'
export async function createContext({ req }: FetchCreateContextFnOptions) {
const session = await auth.api.getSession({ headers: req.headers })
const session = await auth.api.getSession({ headers: await getSanitizedHeaders(req.headers) })
return {
req,
session,

View File

@@ -1,6 +1,5 @@
import { z } from 'zod'
import { router, memberProcedure, adminProcedure } from '../trpc'
import { auth, getSanitizedHeaders } from '@/lib/auth'
import { sendInviteEmail, sendAdminCredentialsEmail } from '@/lib/email'
import crypto from 'node:crypto'
import { prisma } from '@innungsapp/shared'
@@ -51,7 +50,8 @@ const nonEmptyString = (min = 2) =>
const MemberInput = z.object({
name: z.string().min(2),
betrieb: z.preprocess((v) => (v === '' ? undefined : v), z.string().optional()),
sparte: z.preprocess((v) => (v === '' ? undefined : v), z.string().optional()),
// Member.sparte is required in Prisma; map "not selected" to a safe default.
sparte: z.preprocess((v) => (v === '' ? undefined : v), z.string().optional().default('Sonstiges')),
ort: z.preprocess((v) => (v === '' ? undefined : v), z.string().optional()),
telefon: z.string().optional(),
email: z.string().email(),
@@ -216,14 +216,17 @@ export const membersRouter = router({
// 1. Create the member record
const member = await ctx.prisma.member.create({
data: { ...rest, orgId: ctx.orgId } as any,
data: {
...rest,
sparte: rest.sparte || 'Sonstiges',
orgId: ctx.orgId,
} as any,
})
// 2. Create a User account if a password was provided OR role is 'admin',
// so the role is always persisted (no email sent here).
if (password || role === 'admin') {
try {
const authHeaders = await getSanitizedHeaders()
const existing = await ctx.prisma.user.findUnique({ where: { email: input.email } })
let userId: string | undefined = existing?.id
const effectivePassword = password || crypto.randomBytes(8).toString('hex')
@@ -279,11 +282,14 @@ export const membersRouter = router({
.input(MemberInput)
.mutation(async ({ ctx, input }) => {
const { role, password, ...memberData } = input
const authHeaders = await getSanitizedHeaders()
// 1. Create member record
const member = await ctx.prisma.member.create({
data: { ...memberData, orgId: ctx.orgId } as any,
data: {
...memberData,
sparte: memberData.sparte || 'Sonstiges',
orgId: ctx.orgId,
} as any,
})
const org = await ctx.prisma.organization.findUniqueOrThrow({