video.controller.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { Controller, Get, Param, Query } from '@nestjs/common';
  2. import { ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
  3. import { VideoService } from './video.service';
  4. import {
  5. VideoPageDto,
  6. VideoDetailDto,
  7. VideoCategoryDto,
  8. VideoTagDto,
  9. } from './dto';
  10. @ApiTags('Videos')
  11. @Controller('api/v1/video')
  12. export class VideoController {
  13. constructor(private readonly videoService: VideoService) {}
  14. /**
  15. * Get categories for a channel from Redis cache.
  16. */
  17. @Get('categories/:channelId')
  18. @ApiOperation({
  19. summary: 'Get video categories for channel',
  20. description: 'Returns list of video categories from prebuilt Redis cache.',
  21. })
  22. @ApiResponse({
  23. status: 200,
  24. description: 'List of categories',
  25. type: VideoCategoryDto,
  26. isArray: true,
  27. })
  28. async getCategories(
  29. @Param('channelId') channelId: string,
  30. ): Promise<VideoCategoryDto[]> {
  31. return this.videoService.getCategoryListForChannel(channelId);
  32. }
  33. /**
  34. * Get tags for a category within a channel.
  35. */
  36. @Get('tags/:channelId/:categoryId')
  37. @ApiOperation({
  38. summary: 'Get video tags for category',
  39. description:
  40. 'Returns list of tags in a specific category from Redis cache.',
  41. })
  42. @ApiResponse({
  43. status: 200,
  44. description: 'List of tags',
  45. type: VideoTagDto,
  46. isArray: true,
  47. })
  48. async getTags(
  49. @Param('channelId') channelId: string,
  50. @Param('categoryId') categoryId: string,
  51. ): Promise<VideoTagDto[]> {
  52. return this.videoService.getTagListForCategory(channelId, categoryId);
  53. }
  54. /**
  55. * Get videos in a category with pagination.
  56. */
  57. @Get('category/:channelId/:categoryId')
  58. @ApiOperation({
  59. summary: 'Get videos by category',
  60. description:
  61. 'Returns paginated videos for a specific category from Redis cache.',
  62. })
  63. @ApiQuery({
  64. name: 'page',
  65. required: false,
  66. description: 'Page number (default: 1)',
  67. example: 1,
  68. })
  69. @ApiQuery({
  70. name: 'pageSize',
  71. required: false,
  72. description: 'Items per page (default: 20)',
  73. example: 20,
  74. })
  75. @ApiResponse({
  76. status: 200,
  77. description: 'Paginated video list',
  78. type: VideoPageDto,
  79. })
  80. async getVideosByCategory(
  81. @Param('channelId') channelId: string,
  82. @Param('categoryId') categoryId: string,
  83. @Query('page') page?: string,
  84. @Query('pageSize') pageSize?: string,
  85. ): Promise<VideoPageDto<VideoDetailDto>> {
  86. const parsedPage = page ? Math.max(1, Number.parseInt(page, 10)) : 1;
  87. const parsedPageSize = pageSize
  88. ? Math.min(100, Number.parseInt(pageSize, 10))
  89. : 20;
  90. return this.videoService.getVideosByCategoryWithPaging({
  91. channelId,
  92. categoryId,
  93. page: parsedPage,
  94. pageSize: parsedPageSize,
  95. });
  96. }
  97. /**
  98. * Get videos for a tag with pagination.
  99. */
  100. @Get('tag/:channelId/:tagId')
  101. @ApiOperation({
  102. summary: 'Get videos by tag',
  103. description:
  104. 'Returns paginated videos for a specific tag from Redis cache.',
  105. })
  106. @ApiQuery({
  107. name: 'page',
  108. required: false,
  109. description: 'Page number (default: 1)',
  110. example: 1,
  111. })
  112. @ApiQuery({
  113. name: 'pageSize',
  114. required: false,
  115. description: 'Items per page (default: 20)',
  116. example: 20,
  117. })
  118. @ApiResponse({
  119. status: 200,
  120. description: 'Paginated video list',
  121. type: VideoPageDto,
  122. })
  123. async getVideosByTag(
  124. @Param('channelId') channelId: string,
  125. @Param('tagId') tagId: string,
  126. @Query('page') page?: string,
  127. @Query('pageSize') pageSize?: string,
  128. ): Promise<VideoPageDto<VideoDetailDto>> {
  129. const parsedPage = page ? Math.max(1, Number.parseInt(page, 10)) : 1;
  130. const parsedPageSize = pageSize
  131. ? Math.min(100, Number.parseInt(pageSize, 10))
  132. : 20;
  133. return this.videoService.getVideosByTagWithPaging({
  134. channelId,
  135. tagId,
  136. page: parsedPage,
  137. pageSize: parsedPageSize,
  138. });
  139. }
  140. /**
  141. * Get home section videos (e.g., featured, latest, editorPick).
  142. */
  143. @Get('home/:channelId/:section')
  144. @ApiOperation({
  145. summary: 'Get home section videos',
  146. description:
  147. 'Returns videos for home page sections (featured, latest, editorPick) from Redis cache.',
  148. })
  149. @ApiResponse({
  150. status: 200,
  151. description: 'List of videos in section',
  152. type: VideoDetailDto,
  153. isArray: true,
  154. })
  155. async getHomeSectionVideos(
  156. @Param('channelId') channelId: string,
  157. @Param('section') section: string,
  158. ): Promise<VideoDetailDto[]> {
  159. // Validate section is a known type
  160. const validSections = ['featured', 'latest', 'editorPick'];
  161. if (!validSections.includes(section)) {
  162. return [];
  163. }
  164. return this.videoService.getHomeSectionVideos(channelId, section as any);
  165. }
  166. }