route.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import { NextResponse } from 'next/server';
  2. const openApiSpec = {
  3. openapi: '3.0.0',
  4. info: {
  5. title: 'Vtorio API',
  6. version: '1.0.0',
  7. description: 'File upload and management API for Vtorio application',
  8. },
  9. servers: [
  10. {
  11. url: 'http://localhost:3000',
  12. description: 'Development server',
  13. },
  14. ],
  15. paths: {
  16. '/api/upload': {
  17. post: {
  18. summary: 'Upload a file',
  19. description: 'Upload a file to the server and store it in the database',
  20. tags: ['Files'],
  21. requestBody: {
  22. required: true,
  23. content: {
  24. 'multipart/form-data': {
  25. schema: {
  26. type: 'object',
  27. properties: {
  28. file: {
  29. type: 'string',
  30. format: 'binary',
  31. description: 'The file to upload',
  32. },
  33. },
  34. required: ['file'],
  35. },
  36. },
  37. },
  38. },
  39. responses: {
  40. '200': {
  41. description: 'File uploaded successfully',
  42. content: {
  43. 'application/json': {
  44. schema: {
  45. type: 'object',
  46. properties: {
  47. success: { type: 'boolean', example: true },
  48. file: {
  49. type: 'object',
  50. properties: {
  51. id: { type: 'string', example: 'clh123abc456' },
  52. filename: { type: 'string', example: 'document.pdf' },
  53. mimetype: { type: 'string', example: 'application/pdf' },
  54. size: { type: 'number', example: 1024000 },
  55. createdAt: { type: 'string', format: 'date-time' },
  56. },
  57. },
  58. },
  59. },
  60. },
  61. },
  62. },
  63. '400': {
  64. description: 'Bad request - No file provided',
  65. content: {
  66. 'application/json': {
  67. schema: {
  68. type: 'object',
  69. properties: {
  70. success: { type: 'boolean', example: false },
  71. error: { type: 'string', example: 'No file provided' },
  72. },
  73. },
  74. },
  75. },
  76. },
  77. '500': {
  78. description: 'Internal server error',
  79. content: {
  80. 'application/json': {
  81. schema: {
  82. type: 'object',
  83. properties: {
  84. success: { type: 'boolean', example: false },
  85. error: { type: 'string', example: 'Failed to upload file' },
  86. },
  87. },
  88. },
  89. },
  90. },
  91. },
  92. },
  93. },
  94. '/api/files': {
  95. get: {
  96. summary: 'List all files',
  97. description: 'Get a list of all uploaded files with metadata',
  98. tags: ['Files'],
  99. responses: {
  100. '200': {
  101. description: 'List of files retrieved successfully',
  102. content: {
  103. 'application/json': {
  104. schema: {
  105. type: 'object',
  106. properties: {
  107. success: { type: 'boolean', example: true },
  108. files: {
  109. type: 'array',
  110. items: {
  111. type: 'object',
  112. properties: {
  113. id: { type: 'string', example: 'clh123abc456' },
  114. filename: { type: 'string', example: 'document.pdf' },
  115. mimetype: { type: 'string', example: 'application/pdf' },
  116. size: { type: 'number', example: 1024000 },
  117. createdAt: { type: 'string', format: 'date-time' },
  118. updatedAt: { type: 'string', format: 'date-time' },
  119. },
  120. },
  121. },
  122. },
  123. },
  124. },
  125. },
  126. },
  127. '500': {
  128. description: 'Internal server error',
  129. content: {
  130. 'application/json': {
  131. schema: {
  132. type: 'object',
  133. properties: {
  134. success: { type: 'boolean', example: false },
  135. error: { type: 'string', example: 'Failed to list files' },
  136. },
  137. },
  138. },
  139. },
  140. },
  141. },
  142. },
  143. },
  144. '/api/files/{id}': {
  145. get: {
  146. summary: 'Download a file',
  147. description: 'Download a specific file by its ID',
  148. tags: ['Files'],
  149. parameters: [
  150. {
  151. name: 'id',
  152. in: 'path',
  153. required: true,
  154. description: 'The ID of the file to download',
  155. schema: {
  156. type: 'string',
  157. example: 'clh123abc456',
  158. },
  159. },
  160. ],
  161. responses: {
  162. '200': {
  163. description: 'File downloaded successfully',
  164. content: {
  165. 'application/octet-stream': {
  166. schema: {
  167. type: 'string',
  168. format: 'binary',
  169. },
  170. },
  171. },
  172. headers: {
  173. 'Content-Type': {
  174. description: 'MIME type of the file',
  175. schema: { type: 'string' },
  176. },
  177. 'Content-Disposition': {
  178. description: 'Attachment header with filename',
  179. schema: { type: 'string' },
  180. },
  181. 'Content-Length': {
  182. description: 'Size of the file in bytes',
  183. schema: { type: 'integer' },
  184. },
  185. },
  186. },
  187. '404': {
  188. description: 'File not found',
  189. content: {
  190. 'application/json': {
  191. schema: {
  192. type: 'object',
  193. properties: {
  194. error: { type: 'string', example: 'File not found' },
  195. },
  196. },
  197. },
  198. },
  199. },
  200. '500': {
  201. description: 'Internal server error',
  202. content: {
  203. 'application/json': {
  204. schema: {
  205. type: 'object',
  206. properties: {
  207. error: { type: 'string', example: 'Failed to retrieve file' },
  208. },
  209. },
  210. },
  211. },
  212. },
  213. },
  214. },
  215. },
  216. },
  217. };
  218. export const GET = async () => {
  219. return NextResponse.json(openApiSpec, {
  220. headers: {
  221. 'Content-Type': 'application/json',
  222. },
  223. });
  224. };