import { z } from 'zod' import { router, publicProcedure, memberProcedure, adminProcedure } from '../trpc' const StelleInput = z.object({ sparte: z.string().min(2), stellenAnz: z.number().int().min(1).default(1), verguetung: z.string().optional(), lehrjahr: z.string().optional(), beschreibung: z.string().optional(), kontaktEmail: z.string().email(), kontaktName: z.string().optional(), }) export const stellenRouter = router({ /** * Public list — no auth required (Lehrlingsbörse) */ listPublic: publicProcedure .input( z.object({ sparte: z.string().optional(), lehrjahr: z.string().optional(), orgSlug: z.string().optional(), }) ) .query(async ({ ctx, input }) => { const stellen = await ctx.prisma.stelle.findMany({ where: { aktiv: true, ...(input.sparte && { sparte: input.sparte }), ...(input.lehrjahr && { lehrjahr: input.lehrjahr }), ...(input.orgSlug && { org: { slug: input.orgSlug }, }), }, include: { member: { select: { betrieb: true, ort: true } }, org: { select: { name: true, slug: true } }, }, orderBy: { createdAt: 'desc' }, }) return stellen }), /** * List stellen for org (authenticated members) */ list: memberProcedure .input( z.object({ includeInaktiv: z.boolean().default(false), }) ) .query(async ({ ctx, input }) => { const stellen = await ctx.prisma.stelle.findMany({ where: { orgId: ctx.orgId, ...(ctx.role !== 'admin' && !input.includeInaktiv && { aktiv: true }), ...(ctx.role === 'admin' && !input.includeInaktiv && { aktiv: true }), }, include: { member: { select: { name: true, betrieb: true, ort: true } }, }, orderBy: { createdAt: 'desc' }, }) return stellen }), /** * Get single Stelle (public) */ byId: publicProcedure .input(z.object({ id: z.string() })) .query(async ({ ctx, input }) => { const stelle = await ctx.prisma.stelle.findFirstOrThrow({ where: { id: input.id, aktiv: true }, include: { member: { select: { betrieb: true, ort: true } }, org: { select: { name: true } }, }, }) return stelle }), /** * Create Stelle (own member only) */ create: memberProcedure .input(StelleInput) .mutation(async ({ ctx, input }) => { const member = await ctx.prisma.member.findFirstOrThrow({ where: { userId: ctx.session.user.id, orgId: ctx.orgId }, }) const stelle = await ctx.prisma.stelle.create({ data: { orgId: ctx.orgId, memberId: member.id, ...input, }, }) return stelle }), /** * Update own Stelle or admin update any */ update: memberProcedure .input( z.object({ id: z.string(), data: StelleInput.partial().extend({ aktiv: z.boolean().optional() }), }) ) .mutation(async ({ ctx, input }) => { const member = await ctx.prisma.member.findFirst({ where: { userId: ctx.session.user.id, orgId: ctx.orgId }, }) await ctx.prisma.stelle.updateMany({ where: { id: input.id, orgId: ctx.orgId, // Admin can update any, member only their own ...(ctx.role !== 'admin' && member ? { memberId: member.id } : {}), }, data: input.data, }) return { success: true } }), /** * Deactivate Stelle (admin moderation) */ deactivate: adminProcedure .input(z.object({ id: z.string() })) .mutation(async ({ ctx, input }) => { await ctx.prisma.stelle.updateMany({ where: { id: input.id, orgId: ctx.orgId }, data: { aktiv: false }, }) return { success: true } }), })