feat(server): add booking, payment, and scheduler modules
Booking: reservation with atomic transactions, cancellation with refund logic based on cancelHoursLimit (23 tests) Payment: WeChat Pay integration (mock), order lifecycle, membership creation on payment callback (13 tests) Scheduler: cron tasks for slot generation, cleanup, membership expiry (8 tests) 109 total tests passing across 9 test suites
This commit is contained in:
81
packages/server/src/booking/booking.controller.ts
Normal file
81
packages/server/src/booking/booking.controller.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common'
|
||||
import { BookingStatus, UserRole } from '@mp-pilates/shared'
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard'
|
||||
import { RolesGuard } from '../auth/roles.guard'
|
||||
import { Roles } from '../auth/roles.decorator'
|
||||
import { CurrentUser } from '../common/decorators/current-user.decorator'
|
||||
import { BookingService } from './booking.service'
|
||||
import { CreateBookingDto } from './dto/create-booking.dto'
|
||||
|
||||
@Controller()
|
||||
export class BookingController {
|
||||
constructor(private readonly bookingService: BookingService) {}
|
||||
|
||||
// ─── User Endpoints ───────────────────────────────────────────────────────
|
||||
|
||||
@Post('booking')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async createBooking(
|
||||
@CurrentUser('sub') userId: string,
|
||||
@Body() dto: CreateBookingDto,
|
||||
) {
|
||||
return this.bookingService.createBooking(userId, dto)
|
||||
}
|
||||
|
||||
@Put('booking/:id/cancel')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async cancelBooking(
|
||||
@CurrentUser('sub') userId: string,
|
||||
@Param('id') id: string,
|
||||
) {
|
||||
return this.bookingService.cancelBooking(userId, id)
|
||||
}
|
||||
|
||||
@Get('booking/my/upcoming')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async getUpcomingBookings(@CurrentUser('sub') userId: string) {
|
||||
return this.bookingService.getUpcomingBookings(userId)
|
||||
}
|
||||
|
||||
@Get('booking/my')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async getMyBookings(
|
||||
@CurrentUser('sub') userId: string,
|
||||
@Query('status') status?: BookingStatus,
|
||||
@Query('page') page?: string,
|
||||
@Query('limit') limit?: string,
|
||||
) {
|
||||
return this.bookingService.getMyBookings(
|
||||
userId,
|
||||
status,
|
||||
page ? Number(page) : 1,
|
||||
limit ? Number(limit) : 10,
|
||||
)
|
||||
}
|
||||
|
||||
// ─── Admin Endpoints ──────────────────────────────────────────────────────
|
||||
|
||||
@Get('admin/bookings')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Roles(UserRole.ADMIN)
|
||||
async getAllBookings(
|
||||
@Query('page') page?: string,
|
||||
@Query('limit') limit?: string,
|
||||
@Query('status') status?: BookingStatus,
|
||||
) {
|
||||
return this.bookingService.getAllBookings(
|
||||
page ? Number(page) : 1,
|
||||
limit ? Number(limit) : 10,
|
||||
status,
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user