import { Body, Controller, Delete, Get, Param, Patch, Post, Put, Query, Req, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { AcceptStaffInviteDto } from './dto/accept-staff-invite.dto'; import { InviteStaffDto } from './dto/invite-staff.dto'; import { PreviewStaffInviteDto } from './dto/preview-staff-invite.dto'; import { UpdateStaffMemberDto } from './dto/update-staff-member.dto'; import { UpsertWorkingHoursDto } from './dto/upsert-working-hours.dto'; import { StaffService } from './staff.service'; import { StaffWorkingHoursService } from './staff-working-hours.service'; @ApiTags('staff') @ApiBearerAuth('JWT-auth') @Controller('staff') export class StaffController { constructor( private readonly staffService: StaffService, private readonly staffWorkingHoursService: StaffWorkingHoursService, ) {} @Get('invitations/preview') @ApiOperation({ summary: 'Preview invite info by token (public)' }) previewInvite(@Query() query: PreviewStaffInviteDto) { return this.staffService.previewInvite(query.token); } @Post('invitations/accept') @ApiOperation({ summary: 'Accept invite and activate account (public)' }) acceptInvite(@Body() dto: AcceptStaffInviteDto) { return this.staffService.acceptInvite(dto); } @Get() @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'List organization members (requires TAB_STAFF_READ or owner)' }) list(@Req() req: { user: { id: string; organizationId?: string } }) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.list(req.user.id, organizationId); } @Post('invite') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Invite staff (requires TAB_STAFF_EDIT or owner)' }) invite( @Req() req: { user: { id: string; organizationId?: string } }, @Body() dto: InviteStaffDto, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.invite(req.user.id, organizationId, dto); } @Post('members/:membershipId/clear-password') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Clear a staff member password and return a setup link (owner or TAB_STAFF_EDIT; active members only)', }) clearPassword( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.clearPassword(req.user.id, organizationId, membershipId); } @Post('members/:membershipId/invitation-link') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Regenerate and return invite link for a pending staff member', }) getInvitationLink( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.getInvitationLink(req.user.id, organizationId, membershipId); } @Patch('members/:membershipId') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Update staff member name and/or permissions' }) updateMember( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, @Body() dto: UpdateStaffMemberDto, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.updateMember(req.user.id, organizationId, membershipId, dto); } @Get('members/:membershipId/working-hours') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Get weekly working hours for a staff member' }) getWorkingHours( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffWorkingHoursService.getWorkingHours( req.user.id, organizationId, membershipId, ); } @Put('members/:membershipId/working-hours') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Save weekly working hours for a staff member' }) upsertWorkingHours( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, @Body() dto: UpsertWorkingHoursDto, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffWorkingHoursService.upsertWorkingHours( req.user.id, organizationId, membershipId, dto, ); } @Patch('members/:membershipId/enable') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Re-enable a disabled staff member (uses one plan seat; no new invitation)', }) enableMember( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.enableMember(req.user.id, organizationId, membershipId); } @Patch('members/:membershipId/disable') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Disable staff member (frees a seat; member cannot access this organization)', }) disableMember( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.disableMember(req.user.id, organizationId, membershipId); } @Delete('members/:membershipId') @UseGuards(JwtAuthGuard) @ApiOperation({ summary: 'Remove staff member from organization' }) removeMember( @Req() req: { user: { id: string; organizationId?: string } }, @Param('membershipId') membershipId: string, ) { const organizationId = this.staffService.getOrganizationIdFromUser(req.user); return this.staffService.removeMember(req.user.id, organizationId, membershipId); } }