managarten/apps/calendar/apps/backend/src/share/share.controller.ts
Till-JS 78ff102631 feat(calendar): add production launch features
- Email Service: Add email.service.ts with Brevo SMTP for reminders and
  calendar share invitations (German templates)
- Push Notifications: Add notification module with Expo Push API support,
  device token management, and notification.controller.ts endpoints
- Reminder Service: Integrate email and push notifications in reminder
  processing, add userEmail field to reminders schema
- Share Service: Send invitation emails when sharing calendars
- Unit Tests: Add jest.config.js and 63 tests for CalendarService,
  EventService, ReminderService, and ShareService with mock utilities
- Database Migrations: Add migrate.ts with advisory locks for safe
  production deployments
- Type-Checking: Enable type-check script for web app, fix all TypeScript
  errors including CalendarViewType completeness and optional field access

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 12:30:01 +01:00

76 lines
2.4 KiB
TypeScript

import { Controller, Get, Post, Put, Delete, Body, Param, UseGuards } from '@nestjs/common';
import { JwtAuthGuard, CurrentUser, CurrentUserData } from '@manacore/shared-nestjs-auth';
import { ShareService } from './share.service';
import { CreateShareDto, UpdateShareDto } from './dto';
@Controller()
@UseGuards(JwtAuthGuard)
export class ShareController {
constructor(private readonly shareService: ShareService) {}
@Get('calendars/:calendarId/shares')
async findByCalendar(
@CurrentUser() user: CurrentUserData,
@Param('calendarId') calendarId: string
) {
const shares = await this.shareService.findByCalendar(calendarId, user.userId);
return { shares };
}
@Post('calendars/:calendarId/shares')
async create(
@CurrentUser() user: CurrentUserData,
@Param('calendarId') calendarId: string,
@Body() dto: Omit<CreateShareDto, 'calendarId'>
) {
const share = await this.shareService.create(user.userId, user.email, {
...dto,
calendarId,
});
return { share };
}
@Put('calendars/:calendarId/shares/:shareId')
async update(
@CurrentUser() user: CurrentUserData,
@Param('shareId') shareId: string,
@Body() dto: UpdateShareDto
) {
const share = await this.shareService.update(shareId, user.userId, dto);
return { share };
}
@Delete('calendars/:calendarId/shares/:shareId')
async delete(@CurrentUser() user: CurrentUserData, @Param('shareId') shareId: string) {
await this.shareService.delete(shareId, user.userId);
return { success: true };
}
@Get('shares/invitations')
async getInvitations(@CurrentUser() user: CurrentUserData) {
// TODO: Get user email from auth service
const invitations = await this.shareService.findPendingInvitations(
user.userId,
user.email || ''
);
return { invitations };
}
@Post('shares/:shareId/accept')
async acceptInvitation(@CurrentUser() user: CurrentUserData, @Param('shareId') shareId: string) {
const share = await this.shareService.acceptInvitation(shareId, user.userId);
return { share };
}
@Post('shares/:shareId/decline')
async declineInvitation(@CurrentUser() user: CurrentUserData, @Param('shareId') shareId: string) {
const share = await this.shareService.declineInvitation(shareId, user.userId);
return { share };
}
@Get('shares/shared-with-me')
async getSharedCalendars(@CurrentUser() user: CurrentUserData) {
const shares = await this.shareService.getSharedCalendarsForUser(user.userId);
return { shares };
}
}