/** * Project Share Routes – invite users to projects */ import type { FastifyInstance } from 'fastify'; import type { DatabaseInterface } from '../database/DatabaseInterface.js'; import { requireAuth } from '../auth/authMiddleware.js'; import type { AuthService } from '../auth/AuthService.js'; export function registerShareRoutes(fastify: FastifyInstance, db: DatabaseInterface, authService: AuthService) { // List shares for a project fastify.get('/api/projects/:projectId/shares', async (request, reply) => { const user = requireAuth(request, reply, authService); if (!user) return; const { projectId } = request.params as { projectId: string }; return db.listProjectShares(projectId); }); // Create a share / invite by email fastify.post('/api/projects/:projectId/shares', async (request, reply) => { const user = requireAuth(request, reply, authService); if (!user) return; const { projectId } = request.params as { projectId: string }; const body = request.body as { email: string }; if (!body.email) return reply.code(400).send({ error: 'Email is required' }); const share = db.createProjectShare({ project_id: projectId, shared_by_user_id: user.id, shared_with_email: body.email, }); // Create a notification for the invited user if they exist const invitedUser = db.getUserByEmail(body.email); if (invitedUser) { db.createNotification({ user_id: invitedUser.id, project_id: projectId, type: 'share', title: 'Projekt-Einladung', message: `${user.name} hat Sie zum Projekt eingeladen`, }); } return share; }); // Get share by token (public, no auth required) fastify.get('/api/shares/:token', async (request, reply) => { const { token } = request.params as { token: string }; const share = db.getProjectShareByToken(token); if (!share) return reply.code(404).send({ error: 'Share not found' }); return share; }); // Accept a share by token fastify.put('/api/shares/:token/accept', async (request, reply) => { const user = requireAuth(request, reply, authService); if (!user) return; const { token } = request.params as { token: string }; const ok = db.acceptProjectShare(token); if (!ok) return reply.code(404).send({ error: 'Share not found' }); return { success: true }; }); // Revoke a share fastify.delete('/api/shares/:id', async (request, reply) => { const user = requireAuth(request, reply, authService); if (!user) return; const { id } = request.params as { id: string }; const ok = db.deleteProjectShare(id); if (!ok) return reply.code(404).send({ error: 'Share not found' }); return { success: true }; }); }